babelバージョン7系のpolyfillについてのメモ。
babelのインストール
7.0.0から接頭に@がつくようになった。
babel(6系以下)と@babel(7系)はまぜると動かない。
本体とcliとpreset-env
npm install @babel/core @babel/cli @babel/preset-env --save-dev yarn add @babel/core @babel/cli @babel/preset-env --dev
そして、polyfill
npm install @babel/polyfill --save-dev yarn add @babel/polyfill --dev
プラグインを入れたりする。
npm install @babel/plugin-syntax-dynamic-import --save-dev yarn add @babel/plugin-syntax-dynamic-import --dev
babel.config.js
設定ファイルを用意する。
const presets = [
["@babel/env", {
targets: {
browsers: ['last 2 versions', '> 3% in JP'],
IE: 11,
},
useBuiltIns: "usage"
}]
];
const plugins = [
'@babel/plugin-syntax-dynamic-import',
];
module.exports = { presets, plugins };
@babel/envで対応するブラウザについて設定すれば、それで動くようにシンタックス変えたりポリフィルしてくれたりする。
設定はオブジェクトに書くもよし、.browserslistrc用意するもよし…。
説明は公式サイトを見た方が詳しいので割愛する。
targetsに燦然と輝くIE11、もはやpolyfillはこいつとAndroid4系のためにあると言っても過言ではないね。
@babel/polyfillを複数回importすると爆発四散するのは前バージョンから変わらないが、
useBuiltIns: "usage" にしておけば、babelが必要なプラグインだけをimportしてくれるので、
エントリーポイントになるjsファイルで import @babel/polyfill すらしなくてもいい。
いやいや全部入れときたいし!って場合は “entry”にしてpolyfillを1回だけimportする。
@babel/plugin-transform-runtimeの場合
エントリーポイントが複数あったり、グローバル汚染が気になるならこちらの方がマッチする。
インストールは2つで、依存している@babel/runtimeも必要。
npm install @babel/plugin-transform-runtime --save-dev npm install @babel/runtime yarn add @babel/plugin-transform-runtime --dev yarn add @babel/runtime
babel.config.js
pluginsに追加、useBuiltInsはfalseにする。
const presets = [
["@babel/env", {
targets: {
browsers: ['last 2 versions', '> 3% in JP'],
IE: 11,
},
useBuiltIns: false
}]
];
const plugins = [
'@babel/plugin-syntax-dynamic-import',
'@babel/plugin-transform-runtime'
];
module.exports = { presets, plugins };
エントリーポイントで@babel/runtimeを追加する。
import '@babel/runtime';
サードパーティ製ライブラリにPromiseがある場合
たとえば、WebpackのDynamic Import:
import('./sub').then(...)
のような、Webpackでバンドルされるnode_modulesのライブラリでのみPromiseが使われているケースではpolyfillされないので、
IE11などの未対応ブラウザで "Symbol" is not defined エラーが出たりする。
解決策1
useBuiltIns: "entry" にして import @babel/polyfill する。
解決策2
@babel/plugin-transform-runtime または useBuiltIns: "usage" の場合。
エントリポイントにこのようなおまじないを書いておく。
window.Promise = Promise;