Babel 6からBabel 7へアップグレードした際の覚書

4 min read

概要

ややレガシー気味のプロジェクト内の Babel 6 から Babel 7 へのアップグレードした。
アップグレードの期待としては、処理時間の改善(最適化)や今後のアップデートへの対応が柔軟に行えるようになることである。

プロダジェクト環境の概要

単一リポジトリ内に複数のディレクトリがあり、そこで各自 Babel を有している状態であった。これはこの機にルートディレクトリに Babel を集約した。

マイグレーション実行

マイグレーションは、GitHub - babel/babel-upgradeを使用して、大まかな変更は解決させた。

リンク先同様、下記にような形で名称の変更を実行して、あとは必要な箇所の修正を行う。

{
  "devDependencies": {
+   "@babel/core": "^7.0.0",
+   "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
+   "@babel/preset-env": "^7.0.0",
+   "babel-loader": "v8.0.0-beta.0"
-   "babel-loader": "6.0.0",
-   "babel-plugin-transform-object-rest-spread": "6.0.0",
-   "babel-preset-env": "^1.0.0",
  },
}

npm-check-updates - npmを利用して、さらに最新のバージョンに変更した。

Babel 7 での変更点(特筆)

いくつか変更点があるが気になった点だけ特筆しておく。

名称

バージョンアップに伴い、Scoped module に変更になった。

babel-** → @babel/**

babel-upgradeがやってくれたが、package.jsonbabelrc内の記述を変更。

@babel/core

@babel/core パッケージが、 dependencies からpeerDependencies に変更されたため、明示的にインストールする必要が出てきた模様。

useBuiltIns: "usage"オプション

当該プロダクトでは、babel-polyfillを使用していた。

useBuiltIns: 'usage'を指定すると、import '@babel/polyfill' を明示的に呼び出さなくても、必要に応じた内容のpolyfillが自動で読み込むようになる。

しかしながら、今回は@babel/polyfillの使用をやめ、polyfill.io に置き換えた。

変更点

設定

プロダクトの仕様により、.babelrcで記述していた設定をwebpack.config.jsへ移動した。

  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              compact: true,
              cacheDirectory: true,
              presets: [
                [
                  '@babel/preset-env',
                  {
                    targets: ['ie 11', 'safari >= 10', 'not dead']
                  }
                ]
              ],
              plugins: [['@babel/plugin-proposal-object-rest-spread'], ['@babel/plugin-transform-object-assign']]
            }
          }
        ],
        exclude: /node_modules/
      }
    ]
  },

@babel/polyfill の削除

polyfill は polyfill.io(CDN)経由で事足りため、すべて下記に置き換え、メインの JS ファイルにはバンドルしないようにした。

<script
  crossorigin="anonymous"
  src="https://cdn.polyfill.io/v3/polyfill.min.js"
></script>

また、Babel 7.4.0 から@babel/polyfillは非推奨となったようなので、もしビルド側で polyfill 対応を行いたい場合は、core-jsregenerator-runtimeを利用して出力する必要があるようだ。

As of Babel 7.4.0, this package has been deprecated in favor of directly including core-js/stable (to polyfill ECMAScript features) and regenerator-runtime/runtime (needed to use transpiled generator functions):

ファイルサイズ比較

Babel 6 -> Babel 7

main.js
babel 6278KB
babel 7247KB

@babel/polyfill分が減少している。

remove babel-polyfill

main.js
babel 7247KB
babel 7 (without polyfill)217KB

計測

Scripting 時間の比較

 before (ms)after (ms)
1335.8337.5
2465.9305.8
3336.6385.6
4479.9331.8
5409.5395.8
平均405.54351.3

雑多に 5 回ずつ計測してみたが、全体的に 50ms ほど減っている。


おわり

これまでいくつか Babel 6 → Babel 7 へのアップグレードは行ってきたが、今回アップグレードした環境はトリッキーな環境だったので本質じゃない部分でハマることが多かった。