[JS] @babel/polyfill の設定と利用

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;

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください