概要

ややレガシー気味のプロジェクト内の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 6 278KB
babel 7 247KB

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

remove babel-polyfill

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

計測

Scripting 時間の比較

before (ms) after (ms)
1 335.8 337.5
2 465.9 305.8
3 336.6 385.6
4 479.9 331.8
5 409.5 395.8
平均 405.54 351.3

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


おわり

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