webpackのバージョンを移行しなかった備忘録

5 min read読了の目安(約4500字

諸事情によりwebpackのバージョンをアップデートしなかったので、
個人的な備忘録として書いておきます。

参考URL

https://webpack.js.org/migrate/5/

<前提>
・Node.jsのバージョンは10.13.0以上
・webpack-cliを最新のバージョンに更新する
・pluginやloaderを最新のバージョンに更新する
・ビルド時にエラーがない状態ではじめること
・静的HTMLを使っている場合はstats JSONのエントリーポイントを使用して<script>, <style>, <link>タグを生成する

・モードの指定を行っておく。
webpack.config.jsのパラメータに「mode:’development’」もしくは「mode:’production’」を設定する。

■パラメータの設定■
webpack.config.jsのパラメータに以下を使用している場合は変更する。

・optimization.hashedModuleIds: true
→ optimization.moduleIds: 'hashed'

・optimization.namedChunks: true
→optimization.chunkIds: 'named'

・optimization.namedModules: true
→ optimization.moduleIds: 'named'

・NamedModulesPlugin
→optimization.moduleIds: 'named'

・NamedChunksPlugin
→ optimization.chunkIds: 'named'

・HashedModulesPlugin
→ optimization.moduleIds: 'hashed'

・optimization.noEmitOnErrors: false
→ optimization.emitOnErrors: true

・optimization.occurrenceOrder: true
→ optimization: { chunkIds: 'total-size', moduleIds: 'size' }

・optimization.splitChunks.cacheGroups.vendors →optimization.splitChunks.cacheGroups.defaultVendors

・Compilation.entries
→ Compilation.entryDependencies

・serve
→「DevServer」が採用されるので削除

■アップデートの前に■
webpackのバージョンが「4」の状態のまま、
現在の設定で動くかどうかを確認。

以下の設定を追加して、ビルドして成功すれば問題なし。

module.exports = {
  // ...
  node: {
    Buffer: false,
    process: false
  }
};

確認が終わったら、上の設定は削除する。

■アップデート■
npmの場合、
npm install webpack@next --dev

yarnの場合、
yarn add webpack@next -D

を実行する。

■設定の変更■
・「optimization.moduleIds」と「optimization.chunkIds」を使っている場合は削除

・webpackの設定で[hash]プレースホルダを使用している場合は、[contenthash]に変更

・Yarn の PnP と pnp-webpack-plugin を使っている場合、デフォルトでサポートされるようになったので、設定から削除する。

・IgnorePluginの引数に正規表現を指定して使用している場合、オプションオブジェクトを指定する。
new IgnorePlugin({ resourceRegExp: /regExp/ })

・node.something: 'empty'を使用している場合は、
resolve.fallback.something: falseに変更。

■インポート経由でWebAssemblyを使用している場合■
・experiments.syncWebAssembly: trueを追加
・experimentsをexperiments: { asyncWebAssembly: true }に変更

■optimization.splitChunksを使っている場合■
デフォルト値か、
optimization.splitChunks: { chunks: 'all' }を推奨

name: falseを削除し、
name: string | functionをidHint: string | functionに変更する。

・optimization.splitChunks: { default: false, vendors: false }の場合、
推奨はされないものの、optimization.splitChunks: { default: false, defaultVendors: false }にすることで同等の動きになる。

■省略可能のため、削除が推奨される設定■

  entry: './src/index.js'
  output.path: path.resolve(__dirname, 'dist')
  output.filename: '[name].js'

■古いブラウザで動作させたい場合■
・browserslist 設定を使用して、
どのコードスタイルを出力するかを自動実行してくれる。

・browserslistがない場合、ES6スタイルを出力する。

target: ["web", "es5"]

と指定すれば、ES5で出力される。

・Node.jsの場合、
targetオプションにNode.jsのバージョンを書いておけば、
webpackは自動的にどの構文がサポートされているかを把握してビルドする。

■コードの変更■

/* webpackChunkName: '...' */

を使っている場合、以下に注意。

・ここでのチャンク名は公開される。
・開発用の名前ではない
・webpack はこれを使用して、運用モードと開発モードのファイル名を指定する。
・webpack 5 は webpackChunkName を使用していなくても、開発モードでファイル名を自動的に割り当てる。

JSON モジュールから、名前付きエクスポートを使用している場合、

import { version } from './package.json'; 
console.log(version);

ではなく、

import package from './package.json'; 
console.log(package.version);

に変更する。

■ビルドコードの変更■

const compiler = webpack(...);

を使用している場合、
compilerを使用した直後に

compiler.close(callback);

を挿入する。

webpack(..., callback)

では自動終了されない

・ユーザが処理を終了するまでウォッチモードでwebpackを使用する場合はオプションとなる。

■本題■
上記を設定したものの、ビルドエラーが発生。

./node_modules/@babel/runtime/helpers/esm/inherits.js 1:0-46
Module not found: Error: Can't resolve './setPrototypeOf' in '...\client-apps\node_modules\@babel\runtime\helpers\esm'
Did you mean 'setPrototypeOf.js'?
BREAKING CHANGE: The request './setPrototypeOf' failed to resolve only because it was resolved as fully specified
(probably because the origin is a '*.mjs' file or a '*.js' file 
where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.
 @ ./node_modules/i18next/dist/esm/i18next.js 8:0-60 306:2-11 487:2-11 1485:2-11 1839:2-11
 @ ./src/.../i18n/index.ts 6:32-50
 @ ./src/.../index.tsx 26:0-17

「.mjs」もしくは「.js」ファイルを「モジュール」として呼び出しているため、エラーが発生している。
拡張子をきちんと指定する必要がある。

→babelのエラー。
 指定したファイルがjsファイルであるにも関わらず、
 モジュールのように呼び出している。
→今回、i18nextやmaterial-uiを使用しており、
ライブラリ側でbabelを使用している。

i18next.js
import _toConsumableArray from '@babel/runtime/helpers/esm/toConsumableArray';

↑のファイルは↓のファイルをインポートしている。

toConsumableArray.js
import nonIterableSpread from "./nonIterableSpread";

を以下のようにすればエラーは一応解決する。

toConsumableArray.js
import nonIterableSpread from "./nonIterableSpread.js";

もしかすると設定値を変えれば上手くいくのかも。
調査しきれていない部分が多々あると思います。
今回はwebpackのバージョンを据え置くことになりました。

おわり。