webpack2->4とbabel6->7のアップグレード作業ログ

2017年から運用されているNode.jsのプロジェクトのwebpackとbabelのバージョンアップ作業をしたので、作業ログを残しておきます。

アップグレードしたバージョン

  • babel 6 -> 7
  • webpack 2 -> 4

Babelのアップグレード

Babel6 -> 7 は各パッケージ名が変更されていて、パッケージアップグレードで対応できません。 babel-upgrade をつかって、package.jsonと .babelrc をアップグレードすることができます。

npx babel-upgrade --write

いきなり最新のbabelの設定に生まれ変わります。

diff --git a/.babelrc b/.babelrc
index 6cfcd56..bfb063f 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,4 +1,25 @@
 {
-  "plugins": ["transform-runtime", "babel-plugin-transform-flow-strip-types"],
-  "presets": ["es2015", "stage-3"]
+  "presets": [
+    "@babel/preset-env"
+  ],
+  "plugins": [
+    "@babel/plugin-transform-runtime",
+    "@babel/plugin-transform-flow-strip-types",
+    ["@babel/plugin-proposal-class-properties", { "loose": true }],
+    ["@babel/plugin-proposal-decorators", { "regacy": true }],
+    "@babel/plugin-proposal-do-expressions",
+    "@babel/plugin-proposal-export-default-from",
+    "@babel/plugin-proposal-export-namespace-from",
+    "@babel/plugin-proposal-function-bind",
+    "@babel/plugin-proposal-function-sent",
+    "@babel/plugin-proposal-json-strings",
+    "@babel/plugin-proposal-logical-assignment-operators",
+    "@babel/plugin-proposal-nullish-coalescing-operator",
+    "@babel/plugin-proposal-numeric-separator",
+    "@babel/plugin-proposal-optional-chaining",
+    "@babel/plugin-proposal-pipeline-operator",
+    "@babel/plugin-proposal-throw-expressions",
+    "@babel/plugin-syntax-dynamic-import",
+    "@babel/plugin-syntax-import-meta"
+  ]
 }

(使ってるところはなさそうだけど) @babel/plugin-proposal-decorators@babel/plugin-proposal-pipeline-operator だけ、そのままでは動かなそうだったのでオプションを追加

diff --git a/.babelrc b/.babelrc
index bfb063f3..2a985dd4 100644
--- a/.babelrc
+++ b/.babelrc
@@ -6,7 +6,7 @@
     "@babel/plugin-transform-runtime", 
     "@babel/plugin-transform-flow-strip-types",
     ["@babel/plugin-proposal-class-properties", { "loose": true }],
-    ["@babel/plugin-proposal-decorators", { "regacy": true }],
+    ["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": true, "regacy": true }],
     "@babel/plugin-proposal-do-expressions",
     "@babel/plugin-proposal-export-default-from",
     "@babel/plugin-proposal-export-namespace-from",
@@ -17,7 +17,7 @@
     "@babel/plugin-proposal-nullish-coalescing-operator",
     "@babel/plugin-proposal-numeric-separator",
     "@babel/plugin-proposal-optional-chaining",
-    "@babel/plugin-proposal-pipeline-operator",
+    ["@babel/plugin-proposal-pipeline-operator", { "proposal": "minimal" }],
     "@babel/plugin-proposal-throw-expressions",
     "@babel/plugin-syntax-dynamic-import",
     "@babel/plugin-syntax-import-meta"

すべての箇所のrequireをimportに書き換えられたら良かったのですが、歴史のあるプロジェクトではそういうわけにもいきませんでした。 歴史的経緯でexport defaultに指定されているものをrequireする部分は以下のようにしました。

const lib = require('./lib.js').default // .defalutを追加

webpack.config.jsの変更

webpackを2 -> 4 に変更するので、当然のようにwebpack.config.js の設定が違います。

一旦webpack4で新規プロジェクトをつくって、ひとつひとつ同等の設定をしていきました。

はまったポイントとしては、webpack4では process.env.NODE_ENVの環境変数が最適化で文字列に置換されてしまうので。 実行時に環境変数から与えたいので以下のように設定しました。

module.exports = {
...
  optimization: {
    nodeEnv: false // process.env.NODE_ENVを文字列に置換しない
  },
...

なるべく CJSのimportのスタイルに治す

requireを全文検索してimportのスタイルに変更