@babel/preset-env を入れても構文が変換されない
preset-env は targets が無ければ Browserslist の設定を読み、その対象が最新ブラウザだけなら何も変換しない。
変換されないときはまず targets と browserslist の指定を確認する。
公開:
要約
@babel/preset-env を入れたのにアロー関数やクラスがそのまま残るのは、多くの場合「変換する必要が無い」と判断されているためです。
preset-env は targets が指定されていなければ Browserslist の設定を読み、その対象が最新ブラウザだけなら出力は入力とほぼ同じになります。
まず実際の対象を表示して確かめます。
npx browserslistよくある原因
- Browserslist の対象が新しすぎる: 公式ドキュメントは「By default
@babel/preset-envwill use browserslist config sources unless either the targets or ignoreBrowserslistConfig options are set」と説明している。package.jsonに"browserslist": ["last 1 chrome version"]のような指定があれば、変換はほとんど発生しない。 targetsの書き場所が違う:targetsは preset のオプションとして渡す必要がある。babel.config.jsonのトップレベルに書いても、preset 側のオプションとしては読まれない。ignoreBrowserslistConfig: trueを付けている: Browserslist を無視する設定にしたままtargetsを書かないと、対象が定まらず期待した変換にならない。- 構文ではなく API の話である:
PromiseやArray.prototype.includesは構文ではなくランタイムの機能なので、preset-env の構文変換では追加されない。
polyfill の設定が別に要る。
解決策
1. 実際の対象ブラウザを表示する
設定を変える前に、いま何を対象にしているかを確認します。
npx browserslist
npx browserslist "defaults"出力が Chrome の最新版だけであれば、変換が起きないのは正常な動作です。
2. browserslist で対象を明示する
Browserslist の設定は Babel だけでなく Autoprefixer とも共有されるため、ファイルとして持つのが扱いやすい形です。
# .browserslistrc
> 0.5%
last 2 versions
not deadpackage.json に書く場合は次のようになります。
{
"browserslist": ["> 0.5%", "last 2 versions", "not dead"]
}3. preset のオプションに targets を直接書く
ツールごとに対象を変えたいときは、preset のオプションとして指定します。
この場合、Browserslist の設定は読まれません。
// babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
"targets": { "chrome": "80", "ie": "11" }
}
]
]
}Node.js 向けのビルドでは { "node": "current" } を指定すると、実行中のバージョンに合わせた最小限の変換になります。
4. API の polyfill は useBuiltIns で分けて考える
構文の変換と、Promise などの実装の追加は別の仕組みです。useBuiltIns と corejs を設定すると、対象環境に足りない機能だけが読み込まれます。
// babel.config.json
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": "3.38"
}
]
]
}usage はソース中で使われた機能だけを import に展開します。corejs のバージョンは、実際に依存へ入れた core-js に合わせます。