前提
- トランスパイラ利用の有無に関わらず、ES2017 相当の(2021/10 時点でブラウザの対応率が十分に高い)記述がユーザーのブラウザで動くようにする、という方針
- トランスパイラを用いても、ECMAScript の全ての記述を変換してくれるわけではないことは薄々気づいていた
- ESLint を用いても、ECMAScript の全ての記述を解析してくれるわけではないことは薄々気づいていた
目的
- ECMAScript を利用した場合に
- トランスパイラは何を変換し、何を無視するのかを検証する
- ESLint は何を解析し、何を無視するのかを検証する
検証用の入力
- ES6 〜 ESNext の規格に基づいたコードサンプル
- 利用する機会がありそうな機能をピックアップ
/**
* ES2015
* ------------------------------------------------
*/
/** const, let */
const cst = 1
let lt = 2
console.log(cst)
console.log(lt)
/** Allow function */
const fn = () => {
console.log('fn')
}
/** classes */
class Hoge {
fuga () {
console.log('fuga')
}
}
/**
* ES2016
* ------------------------------------------------
*/
/** Array.prototype.includes */
const array = [1, 2, 3, 4, 5]
console.log(array.includes(2))
/** べき乗演算子 */
console.log(2**2)
/**
* ES2017
* ------------------------------------------------
*/
/** Async functions */
async function log () {
console.log('hoge')
}
/** Object.values() */
const obj = { hoge: 0, fuga: 1, piyo: 2 }
console.log(Object.values(obj))
/**
* ES2018
* ------------------------------------------------
*/
/** Spread Properties */
const hoge = { fuga: 'piyo' }
console.log({ ...hoge })
/** RegExp named capture groups */
console.log(/(?<year>[0-9]{4})年/.test('2021年'))
/** RegExp Lookbehind Assertions */
console.log(/(?<=[0-9]+)\.[0-9]+/.test('.34'))
/**
* ES2019
* ------------------------------------------------
*/
/** flat array methods */
console.log([[1, 2], 3, 4].flat())
/**
* ES2020
* ------------------------------------------------
*/
/** Optional chaining operator */
console.log(hoge?.fuga)
/**
* ES2021
* ------------------------------------------------
*/
/** Logical assignment operators */
console.log(a ||= b)
/** Numeric separators */
console.log(100_000_000)
/**
* ESNext
* ------------------------------------------------
*/
/** static class field */
class Foo {
static bar = 1
}
console.log(Foo.bar)
対象のトランスパイラと設定
No | 名前 | ターゲット |
---|---|---|
1 | Babel / conservative | - ( > 1% in JP ) |
2 | Babel / progressive | - ( > 5% in JP ) |
3 | esbuild / default | ESNext |
4 | esbuild / to ES2017 | ES2017 |
5 | rollup | not transpile |
6 | rollup-plugin-esbuild | ES2017 |
7 | Typescript / default | ES3 |
8 | Typescript / to ES2017 | ES2017 |
検証結果
すべてのトランスパイルで変換されない記述
- RegExp named capture groups (ES2018)
- RegExp Lookbehind Assertions (ES2018)
- flat array methods (ES2019)
ESLint で検証できない記述
- flat array methods (ES2019)
- freaktechnik/eslint-plugin-array-func を試してみたがダメ
その他気がついたこと
- esbuild はデフォルトでコメントが削減される
(おまけ) 実行時間
No | 名前 | ターゲット | 時間 ( s ) |
---|---|---|---|
1 | Babel / conservative | - ( > 1% in JP ) |
0.63 |
2 | Babel / progressive | - ( > 5% in JP ) |
0.53 |
3 | esbuild / default | ESNext | 0.31 |
4 | esbuild / to ES2017 | ES2017 | 0.18 |
5 | rollup | not transpile | 0.20 |
6 | rollup-plugin-esbuild | ES2017 | 0.27 |
7 | Typescript / default | ES3 | 1.21 |
8 | Typescript / to ES2017 | ES2017 | 1.36 |
参考
- ESLint - Pluggable JavaScript linter
- Babel · The compiler for next generation JavaScript
- esbuild - An extremely fast JavaScript bundler
- rollup.js
- egoist/rollup-plugin-esbuild: Use ESBuild with Rollup to transform ESNext and TypeScript code
- TypeScript: JavaScript With Syntax For Types.
- ES6〜ES10(es2015〜es2019)まとめ - Qiita