webpackを4から5へアップデートしましたが、移行ガイドを読まずに自力でできてしまったので、改めて移行ガイドを読んでみます。
抜けがないか確認のため。設定の細かいカスタマイズをしてる人は一読する価値あり。基本設定で済ませていれば、そこまで必要はなかったかな?
変更前 | 変更後 | |
---|---|---|
webpack | 4.44.2 | 5.3.2 5.4.0 5.8.0 |
webpack-cli | 3.3.12 | 4.1.0 4.2.0 |
プラグイン | バージョン変更前 |
---|---|
babel-loader | 8.1.0 8.2.2 |
@babel/core (babel-loaderで必要。) | 7.12.3 7.12.9 |
@babel/preset-env (babel-loaderで必要。) | 7.12.1 7.12.7 |
@babel/plugin-transform-react-jsx (Reactのjsxで必要。) | 7.12.5 7.12.7 |
html-loader | 1.3.2 |
style-loader | 2.0.0 |
css-loader | 5.0.1 |
postcss-loader | 4.0.4 4.1.0 |
postcss (postcss-loaderで必要。) | 7.0.32 |
autoprefixer (postcssのプラグイン) | 9.8.6 |
sass-loader | 10.0.5 10.1.0 |
node-sass (sass-loaderで必要。) | 5.0.0 |
mini-css-extract-plugin | 1.3.0 1.3.1 |
copy-webpack-plugin | 6.3.0 6.3.2 |
html-webpack-plugin | 4.5.0 |
html-webpack-skip-assets-plugin | 0.0.2 |
core-js | 3.7.0 3.8.0 |
webpackを4から5に上げる作業をしました。それが自力で意外とあっさりできたので、移行ガイドを読んでません。
これからガイドを順を追って見ていきますが、結論から言うと、
『凝ったカスタマイズしてないかぎりやることないんじゃない?』
(プラグイン、ローダーを追加して使ってる程度では気にするところはない。)
『基本的なことをきちんと書いてればOK。』
です。そして、全部読んで日本語にまとめましたが、やることなかったのにエラい長い。
(疲れた。)
アップデートする前に
webpackのバージョンアップ作業では、前もってやっておくことがあります。それをやらずに、わざとエラーを出して直していく方法もありますが、大量に出るとやる気を失うので確認しておきましょう。
Node.jsのバージョンは、10.13.0 (LTS)以上が必要です。
ガイドでは、バージョンが新しいほどwebpackのパフォーマンスが向上しますと言っています。
webpack4の最新バージョンへ上げておく
まずは、webpack4のバージョンを最新にします。マイナーバージョンを最新にしておくということ。
package.jsonを編集して、yarn upgradeを実行すればいいです。
"devDependencies": {
"webpack": "^4.0.0",
"webpack-cli": "^3.0.0",
},
yarn install
yarn upgrade webpack webpack-cli
webpack-cliのマイナーバージョンのアップデートも忘れずに。
"yarn install" は、package.jsonを編集したのでその反映です。
プラグイン・ローダーのアップグレード
webpackにnpmやyarnで追加して拡張プラグイン・ローダーを使っているでしょう。これも最新版にバージョンアップします。
アップグレード方法はwebpack, webpack-cliと同じ。最新版にするのでメジャーバージョンが上がるときもあります。適宜package.jsonを編集してください。
各パッケージのバージョン確認はこちら。
yarn outdated
最新バージョンのパッケージはリストに表示されません。
ビルド確認
webpack4環境の最新バージョンでビルドができるか確認します。
非推奨の警告は見逃さないようにしましょう。移行ガイドでは、『非推奨の部分はwebpack5で削除するからエラーになる』と言っています。
もし、プラグインやローダー、パッケージが動かなくなるとき、その最新バージョンがwebpack5用になっていて、webpack4が非対応になってるかも知れません。
その場合は、webpack4が動く最新バージョンにダウングレードしましょう。
(そのまま放置して、webpack5で動けばいいと開き直っても良い。)
webpack5 互換テスト
ビルドを実行する前に、nodeオプションを変更しておきます。
module.exports = {
//...
node: {
Buffer: false,
process: false
}
};
webpack5ではこのオプションはありません。デフォルトfalseです。falseでwebpack4を動くようにしておかないと5でも動きませんということですね?
個人的にはこのオプションを消して互換テストしたほうがいいと思います。どのみちwebpack5で消すので。
webpackのアップグレード
アップグレードの準備が整いました。移行ガイドでは、アップグレード前にいくつかwebpack.config.jsの修正をする手順になっていますが、アップグレードからやっちゃいます。
細かいカスタマイズをしないかぎり、影響のない人も多いはずなので。
(直すところは後述。)
まずは、ボクがやったアップグレード方法から。やり方はwebpak4の最新版アップデートと同じ。
"devDependencies": {
"webpack": "^5.0.0",
"webpack-cli": "^4.0.0",
},
webpackを5にcliを4に上げます。(cliは4にする必要がある。)
マイナーバージョンは0ですが、'^'がついているので最新のマイナーバージョンでアップグレードします。
yarn install
yarn upgrade webpack webpack-cli
移行ガイドではこうなってます。
npm install webpack@next --dev
yarn add webpack@next -D
@nextつけるだけで、webpackとwebpack-cliをまとめてやってくれるんだ。便利~。
と思ったのですが、これ追加です。バージョン4は残骸パッケージになるんじゃないだろうか?
(終わってしまったので検証まではしない。試したい方はどうぞ。)
webpack.config.jsの修正
webpack5では使えなくなったもの、意味がなくなったもの、エラーになるもの、いろいろあります。
webpack.config.jsの設定をwebpack5用に修正します。
アップグレード前にやっとくこと
移行ガイドでは、アップグレード前に書いてあった修正部分です。今回は、あまり影響のない人のことも考えて、あえてアップグレード後にもってきました。
直さないといけない人はwebpackを実行するとエラーになるはずです。
(意味がなくなってスルーもある。)
統計からのエントリーポイント情報を使用していることを確認してください。
When using static HTML or creating HTML in other way, make sure to use entry points from stats JSON to generate <script>, <style> and <link> tags.
If this is not possible, avoid setting splitChunks.chunks: 'all' and splitChunks.maxSize later in this guide. Note that this is sub-optimal and a workaround.
公式ガイド本文
静的HTMLを使用する場合やその他の方法でHTMLを作成する場合は、必ずstats JSONのエントリーポイントを使用して、<script>、<style>、<link>タグを生成してください。
これができない場合は、このガイドで後述する splitChunks.chunks: 'all' と splitChunks.maxSize の設定を避けてください。これは最適ではなく、回避策であることに注意してください。
筆者訳
最初、???でしたが、デフォルトのバインドを変更する場合の注意点らしい。
『エントリポイントまわりはJSONを使え。』
『それができなければ2つの設定を使うな。』
『回避策であってベストアンサーではない。』
と言っています。あともう一つ、
『HtmlWebpackPluginを使ってるならスルーしていい。』
とも言っています。はい、使ってます。スルーします。
(プラグインやローダー開発者向けの話。)
必ずモードを使用するようにしてください
モードの設定をしない人がいるんでしょうか? 最初に書くものなんですけど。
モードを『プロダクト』『開発』に分けてそれぞれのモードでビルドするやつ。これがなくても動くっちゃ動くので書いてない人もいるのかな?
使い方としては、ビルドの実行コマンドのオプションを使ったほうが便利です。
const MODE = process.env.NODE_ENV;
module.exports = {
mode: MODE,
};
(モード以外は割愛。)
process.env.NODE_ENV は、ビルド実行コマンドのオプションの値です。
webpack --mode=production --progress
webpack --mode=development --progress
移行ガイドに『使用してください。』とあるので設定しましょう。(必須)
古いオプションのアップデート
webpack5になってから、オプションが変わったもの、消えたものを修正します。
ボクはひとつもありませんでした。こちらのリンクをどうぞ。
設定のクリーンアップ
移行ガイドでは、『Clean up configuration』になってますが、ようは、設定方法、設定内容、デフォルトの意味が変わってるから設定内容を見直そうという項目です。
凝った設定をしていない人にとっては関係ない所も多いです。じっさいボクもそう。
勝手に優先度をつけて説明します。
デフォルト削除の検討
『デフォルトで設定されていて省略できるから、書いてあるなら消してみては?』
という項目です。(書いても意味ないよ?ということ。)
entry: './src/index.js'
output.path: path.resolve(__dirname, 'dist')
output.filename: '[name].js'
判断はこっちに任せられてますが、いらないなら消しましょう。webpack.config.jsはたださえ冗長になりやすいので。
古いブラウザのサポート
3つのことが書いてあります。ここでは翻訳したものを紹介します。
webpackのデフォルトは、browserslistの設定を使う。
(.browserslistrcファイルかtargetオプションの設定。)
browserslistがないときはES6をデフォルトにする。
デフォルトをES5にするとき、たとえばオプション設定を使うなら、
module.exports = {
target: ["web", "es5"],
};
Node.jsのバージョンは、任意の指定か未指定のときは自動的にtargetオプションに追加する。
module.exports = {
target: 'node8.6',
};
これって、『webpack4とちがいはあるの?』と思うのはボクだけでしょうか?
ES6がデフォルトになるってところがちがうのかな?
必要な人は確認しよう!
そのほかは、細かいカスタマイズをしている人向けです。ボクは使ってません。
そのまま載せます。(使ってないので深いところまで意味は分かってない。)
optimize.moduleIds と optimization.chunkIds を webpack の設定から削除することを検討してください。本番モードでは長期的なキャッシュをサポートし、開発モードではデバッグをサポートしているので、デフォルトの方が良いかもしれません。
モードを'production'にすればキャッシュを使うらしい。
(ビルドの高速化。)
'development'ではデバッグを出すらしい。
(たしかに、'production'ではデバッグできなくなった。ビルドオプション--display-error-detailsの廃止。)
webpackの設定で[hash]プレースホルダを使用する場合は、[contenthash]に変更することを検討してください。これは同じではありませんが、より効果的であることが証明されています。
このプレースホルダは使ったことがない。使ってる人には理解できると思う。
YarnのPnPとpnp-webpack-pluginを使っている場合、良いニュースです!
デフォルトでサポートされています。設定から削除する必要があります。
PnPはyarnが独自にパッケージを展開する手法らしい。
(node_modules下に展開しない。)
使ってる人は、わざわざプラグインとか入れなくてもいいよってこと?
IgnorePluginの引数に正規表現を指定して使用している場合、オプションオブジェクトを受け取るようになりました。
new IgnorePlugin({ resourceRegExp: /regExp/ })
node.something: 'empty'
↓
resolve.fallback.something: false
に置き換える。
これは使ってなくても意味が分かる。
import経由でWebAssemblyを使ってるときは
import経由でWebAssemblyを使ってるときは、2つのステップに従う必要があります。
experimental.syncWebAssembly: true を設定すると、非推奨仕様を有効にしwebpack4と同じ動作になる。
webpack5への移行が成功したら、WASM 統合のために最新の仕様を使用するように実験値を変更します。
(asyncWebAssembly: true)
optimize.splitChunksの見直し
3つの注意事項があります。
デフォルトか optimization.splitChunks: { chunks: 'all' } のどちらかを使用することをお勧めします。
デフォルトは未指定。
カスタム設定をするとき
name: falseを削除して次のいずれかに変える。
name: string
idHint: string付きfunction
function
使ってる人には分かるんじゃないかな?
デフォルトのオフ
optimize.splitChunks: { default: false, vendors: false }
↓
optimization.splitChunks: { default: false, defaultVendors: false }
に変える。
『あまりオススメしませんがどうしてもwebpack5でするなら』と言っています。
使ってる人には分かる注意点だと思う。
コードのクリーンアップ
ここでは、webpackChunkNameとJSONモジュールからのインポートの2つだけ触れています。
webpackChunkName
『/* webpackChunkName. '…' */』を使うときの意味を確認しているだけで、使い方に変更はありません。
『意味を分かって使えよ』ってところでしょう。
chunk nameはpublic。(隠蔽しない。)
開発用の名前ではない。(本番でも使う。)
webpackではこの名前を使って、開発モード、本番モードでファイル名をつける。
webpackChunkNameを使わないとき、webpack5では開発モードで便利な名前が自動的につけられる。
JSON モジュールからの名前付きエクスポートの使用
import { version } from './package.json';
console.log(version);
はサポートされません。これに置き換えます。
import package from './package.json';
console.log(package.version);
ビルドコードのクリーンアップ
ここではひとつだけ。webpackのコンパイラを使うときは必ずクローズしてくれってこと。
const webpack = require('webpack');
const compiler = webpack({
// [Configuration Object](/configuration/)
});
const callback = (err, stats) => {
console.log('Compiler has finished execution.');
};
compiler.close(callback); // 必ずクローズ
注意点もあります。
自動的に閉じるwebpack(…, callback)には適用されない。
ユーザーが処理を終了するまでwatchモードで使う場合は任意。watchモードのアイドルフェーズが使われる。
シングルでビルドを実行しアドバイスに従う
ビルド実行時の注意点です。ここでは移行ガイドの和訳を載せます。
(無駄を省くため思いっきり意訳あり。)
必ずエラー、警告をよくお読みください。少なくともレベル3または4まで修正ステップを繰り返します。
(個人談: 本文はレベル3または4と言ってるが、警告以外は修正したほうがいい。)
エラーレベルと内容
エラー レベル | エラー名 | 内容 |
---|---|---|
1 | Schema validation fails スキーマ検証に失敗 | 設定オプションが変更された。 BREAKING CHANGEでバリデーションエラーが発生している。 NOTE: または代わりに使用するオプションのヒントを表示。 |
2 | webpack exits with an error webpackがエラーで終了 | エラーメッセージは、何を変更する必要があるかを教えてくれる。 |
3 | Build Errors ビルドエラー | エラーメッセージには、BREAKING CHANGEが表示される。 |
4 | Build Warnings ビルド警告 | 警告メッセージは、何が改善できるかを伝える。 |
5 | Runtime Errors ランタイムエラー | これは厄介。 デバッグしないと見つけられないだろう。 一般的なアドバイスはここでは難しい。 |
6 | Deprecation Warnings 非推奨の警告 | Deprecationの警告はたくさん出るだろうが、直接の問題ではない。 プラグインはコアの変更に追いつくために時間が必要。 これらの非推奨事項をプラグインに報告してください。 これらは単なる警告であり、ビルドは小さな欠点(パフォーマンスの低下など)があっても動作する。 |
7 | Performance issues パフォーマンスの警告 | webpack 5でパフォーマンスが向上するはずだが、悪くなるケースも少なからずある。 |
(本文は~されるはず(... should ...)が多い。断定していない。)
ここから先は修正サイクルのヒントです。
レベル5, ランタイムエラーについて
processは定義されていない
webpack5ではNode.js変数のポリフィルが含まれなくなった。フロントエンドコードでの使用は避けてください。
フロントエンドとブラウザでの利用をサポートしたいか?
exports または importsで package.json フィールドを使用して、環境に応じて異なるコードを使用します。
また古いバンドルをサポートするために、ブラウザのフィールドを使用しています。
代替として、コードブロックを 'typeof process' チェックでラップします。これはバンドルサイズに負の影響を与えることに注意。
process.env.VARIABLEで環境変数を使いたいか?
これらの変数を設定で定義するにはDefinePluginやEnvironmentPluginを使用する必要があります。
代わりにVARIABLEを使うことを検討し、typeof VARIABLE !== 'undefined'にもチェックを入れてください。
process.envはNode.js特有のものなので、フロントエンドのコードでは避けるべき。
autoを含むURLsを指す404エラー
すべてのエコシステムツールが、output.publicPath: "auto" を介した新しいデフォルトの自動公開パスに対応しているわけではありません。
代わりに静的な output.publicPath: "" を使用してください。
レベル6, 非推奨の警告について
node --no-deprecation node_modules/webpack/bin/webpack.js
--no-deprecationオプションを付けることで非表示にできるが、一時的な回避策にすぎない。
(個人談: そりゃそうだ。)
筆者追記
--no-deprecationオプションは、nodeコマンドのオプションで、webpack-cliのwebpackコマンドのオプションではない。
個人的には必要ない。そもそも警告を消す理由がない。永久放置に等しい。
プラグインとローダーの開発者は、非推奨のメッセージにあるアドバイスに従うことでコードを改善することができます。
レベル7, パフォーマンスの警告について
時間を費やす場所のプロフィール
--profile --progress はシンプルなパフォーマンスプロファイルを表示します。
筆者追記
--profile, --progressオプションは、webpack-cliのwebpackコマンドのオプション
webpack --mode=production --profile --progress=profile
--progressはビルドの進捗をバーで表示。--profileはローダーやプラグインの個別の実行時間を表示。
nodeコマンドの--inspect-brkオプション
node --inspect-brk node_modules/webpack/bin/webpack.js
これらのプロファイルをファイルに保存し、課題に提供することができます。
chrome | chrome://inspect |
edge | edge://inspect |
場合によってはスタックトレースを改善するために --no-turbo-inlining フラグを使用してみてください。
(個人談: ブラウザの開発ツール -> プロファイラーで解析できるみたい。)
インクリメンタルビルドでのモジュールのビルド時間
インクリメンタルビルドでのモジュールのビルド時間は、webpack 4 のように安全でないキャッシングに戻すことで改善できます。
module.exports = {
module: {
unsafeCache: true,
},
};
しかし、これはコードベースへの変更の一部を処理する能力に影響を与える可能性があります。
(個人談: 使うか?)
フルビルド
非推奨の機能の下位互換性レイヤは、通常、新機能に比べてパフォーマンスが低下します。
多くの警告を作成すると、無視されてもビルドのパフォーマンスに影響を与える可能性があります。
ソースマップは高価です。ドキュメントの devtool オプションを確認して、異なるオプションの比較を確認してください。
ウイルス対策は、ファイルシステムへのアクセスのパフォーマンスに影響を与える可能性があります。
永続的なキャッシングは、反復的なフルビルドを改善するのに役立ちます。
モジュールフェデレーションでは、アプリケーションを複数の小さなビルドに分割することができます。
移行ガイドでは、レベル5~7までは触れていますがそれ以外はありません。出力されるメッセージに従ってくださいということだと思います。
ランタイムコードのES2015構文オフ
『設定のクリーンアップ』の項目でも触れているのですが、改めて大項目で書いています。
ただ、本文がまちがっているような...
By default, webpack's runtime code uses ES2015 syntax to build smaller bundles. If your build targets environments that don't support this syntax (like IE11), you'll need to set target: ['web', 'es5'] to revert to ES5 syntax ('web' if target environment is browser).
移行ガイド本文
デフォルトでは、webpackのランタイムコードはES2015構文を使用して、より小さなバンドルをビルドします。
この構文をサポートしていない環境 (IE11 など) をビルドのターゲットにしている場合は、ターゲットを設定する必要があります。
['web', 'es5'] を設定して ES5 構文に戻す必要があります(ターゲット環境がブラウザの場合は 'web')。
筆者訳
冒頭のデフォルトはES2015構文というところが、おそらく、ES2016構文のまちがい。
内部構造の変更
webpack5では内部構造の変更が行われましたが、一般的なユーザーの移行にはあまり関係ありません。
移行ガイドでは、興味のある人に情報提供していると言っています。
ということなので、移行ガイドのリンクだけ貼っておきます。