Edited at

@babel/preset-envのuseBuiltInsを使ってpolyfillする

@babel/preset-envのuseBuiltInsに関する記事です。

Babel v7以降で使えるようになるpolyfillを自動補完してくれる機能について紹介します。


更新(2018/08/27)

2018/08/27にBabel v7が正式リリースされました🎉

https://babeljs.io/blog/2018/08/27/7.0.0


Babel v7


@babel/polyfill


  • babelは文法の変換のみ。ブラウザによっては使えない機能はあります。

  • 例えば、IEはPromiseとかSymbolとか使えません。これは文法ではなく、機能です。

  • @babel/polyfillを使えばその辺の穴埋め(polyfill)をしてくます。

  • ソースコードを直接改変する必要があり。以下のようにpolyfillをimportしなければいけません。

import "@babel/polyfill"


@babel/plugin-transform-runtime


  • こちらもpolyfillするbabelのプラグイン

  • babel-polyfillとは違いimportを書く必要がない。babelの設定に追加するだけ

  • babelのプラグインなので変換時にpolyfillします

  • 指定したブラウザとか関係なく問答無用で変換する。ようするにchromeには既に実装済の機能でChromeの最新バージョンに合わせて変換してもChromeがネイティブ対応済のものまでpolyfillします


求めているもの


  • polyfillのためにimportを書いたり、polyfill用のパッケージをインストールしたくない

  • 指定したブラウザやバージョンに無い機能だけpolyfill入れてほしい


@babel/preset-env


  • babel 6の頃はbabel-preset-envだった

  • 指定したブラウザやNodeのバージョンに合わせてネイティブサポートしていない文法のみ変換

  • cssのAutoprefixerのようにbrowserslistを使って文法の変換を行う

  • 上記で書いた「求めているもの」を叶えてくれる優れもの


Install

まずは@babel/preset-envのインストール方法

npm install --save-dev @babel/preset-env


useBuiltIns: "usage"オプション


  • polyfillのための@babel/polyfillのインストールが不要

  • 指定したブラウザやバージョンに合わせて必要なpolyfillだけをimport

@babel/polyfillとbabel-plugin-transform-runtimeのいいとこどり!


Babel v6のbabel-preset-envのpolyfill

useBuiltInsオプションは1.x系からありました。

{

"presets": [
[
"env",
{
"targets": {
"ie": 11
},
// trueにすることで必要なpolyfillだけをimportするようにします
"useBuiltIns": true
}
]
]
}


  • 必要なpolyfillのみインポート

  • ただし前述の通り@babel/polyfillをimportしなければいけません。

イメージ的には以下のように@babel/polyfillをimportするコードが必要な分のpolyfillをimportするコードに変換されます

import "@babel/polyfill";

require("babel-polyfill/lib/core-js/modules/es6.promise");



Babel v7の@babel/preset-envからのpolyfill

{

"presets": [
[
"env",
{
"targets": {
"ie": 11
},
// 必要な分だけのpolyfillを自動でインポート
"useBuiltIns": "usage"
}
]
]
}


  • @babel/polyfillの別途インストールが不要

  • @babel/polyfillをインポートするコードが不要

  • usageにしてbabelを実行すると勝手に以下ような必要な分だけpolyfillが埋め込まれる

これが自動でコード内に挿入される

require("babel-polyfill/lib/core-js/modules/es6.promise");

開発者はpolyfillいるかいらないか気にしなくてよいようになります


注意

場合によっては別途polyfillが必要だったりもするので万能ではない

以下のような実行しないと型がわからない場合とかは自動でpolyfillできません

そういった場合は必要なpolyfillをimportする必要があります

users.includes("hoge")


GitHubにサンプル置いときました!

shisama/babel-preset-env-useBuiltIns-sample

npm updateしてnpm run buildすれば以下のトランスパイルした結果を出力

- Node.js(4/6/8)

- chrome(v60/v50)

- firefox(v55/beta)

- Safari

- Edge

- IE11


まとめ


  • babelは文法の変換だけ

  • polyfillは@babel/preset-envで

    "useBuiltIns": "usage"

    すればどのpolyfillが必要か考えなくてよくなるし、不要なpolyfillは入らない

最後までお読みいただきありがとうございました。質問や不備がございましたらコメント欄またはTwitter(@shisama_)までお願いいたします。