ツイート
シェア
LINEで送る
B! はてぶでブックマーク
Pocketでブックマーク
RSSフィード

webpack4 -> 5 移行ガイドを読んでその通りにやってみる。

Node.js image
イラストダウンロードサイト【イラストAC】
の画像をもとに加工しています。

webpackを4から5へアップデートしましたが、移行ガイドを読まずに自力でできてしまったので、改めて移行ガイドを読んでみます。

抜けがないか確認のため。設定の細かいカスタマイズをしてる人は一読する価値あり。基本設定で済ませていれば、そこまで必要はなかったかな?

変更前変更後
webpack4.44.25.3.2
5.4.0
5.8.0
webpack-cli3.3.124.1.0
4.2.0
webpackのバージョン
プラグインバージョン変更前
babel-loader8.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-loader1.3.2
style-loader2.0.0
css-loader5.0.1
postcss-loader4.0.4
4.1.0
postcss
(postcss-loaderで必要。)
7.0.32
autoprefixer
(postcssのプラグイン)
9.8.6
sass-loader10.0.5
10.1.0
node-sass
(sass-loaderで必要。)
5.0.0
mini-css-extract-plugin1.3.0
1.3.1
copy-webpack-plugin6.3.0
6.3.2
html-webpack-plugin4.5.0
html-webpack-skip-assets-plugin0.0.2
core-js3.7.0
3.8.0
使用ローダー/プラグイン/パッケージ

webpackを4から5に上げる作業をしました。それが自力で意外とあっさりできたので、移行ガイドを読んでません。

これからガイドを順を追って見ていきますが、結論から言うと、

『凝ったカスタマイズしてないかぎりやることないんじゃない?』

(プラグイン、ローダーを追加して使ってる程度では気にするところはない。)

『基本的なことをきちんと書いてればOK。』

です。そして、全部読んで日本語にまとめましたが、やることなかったのにエラい長い。

(疲れた。)

アップデートする前に

webpackのバージョンアップ作業では、前もってやっておくことがあります。それをやらずに、わざとエラーを出して直していく方法もありますが、大量に出るとやる気を失うので確認しておきましょう。

Node.jsのバージョンは、10.13.0 (LTS)以上が必要です。

ガイドでは、バージョンが新しいほどwebpackのパフォーマンスが向上しますと言っています。

webpack4の最新バージョンへ上げておく

まずは、webpack4のバージョンを最新にします。マイナーバージョンを最新にしておくということ。

package.jsonを編集して、yarn upgradeを実行すればいいです。

package.jsonのバージョン指定
  "devDependencies": {
    "webpack": "^4.0.0",
    "webpack-cli": "^3.0.0",
  },
webpack4のアップグレード
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オプションを変更しておきます。

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

webpack5ではこのオプションはありません。デフォルトfalseです。falseでwebpack4を動くようにしておかないと5でも動きませんということですね?

個人的にはこのオプションを消して互換テストしたほうがいいと思います。どのみちwebpack5で消すので。

webpackのアップグレード

アップグレードの準備が整いました。移行ガイドでは、アップグレード前にいくつかwebpack.config.jsの修正をする手順になっていますが、アップグレードからやっちゃいます。

細かいカスタマイズをしないかぎり、影響のない人も多いはずなので。

(直すところは後述。)

まずは、ボクがやったアップグレード方法から。やり方はwebpak4の最新版アップデートと同じ。

package.jsonの編集
  "devDependencies": {
    "webpack": "^5.0.0",
    "webpack-cli": "^4.0.0",
  },

webpackを5にcliを4に上げます。(cliは4にする必要がある。)

マイナーバージョンは0ですが、'^'がついているので最新のマイナーバージョンでアップグレードします。

webpack5へのアップグレード
yarn install
yarn upgrade webpack webpack-cli

移行ガイドではこうなってます。

npm
npm install webpack@next --dev
yarn
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を使ってるならスルーしていい。』

とも言っています。はい、使ってます。スルーします。

(プラグインやローダー開発者向けの話。)

必ずモードを使用するようにしてください

モードの設定をしない人がいるんでしょうか? 最初に書くものなんですけど。

モードを『プロダクト』『開発』に分けてそれぞれのモードでビルドするやつ。これがなくても動くっちゃ動くので書いてない人もいるのかな?

使い方としては、ビルドの実行コマンドのオプションを使ったほうが便利です。

webpack.config.js
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にするとき、たとえばオプション設定を使うなら、

webpack.config.js
module.exports = {
  target: ["web", "es5"],
};

Node.jsのバージョンは、任意の指定か未指定のときは自動的にtargetオプションに追加する。

webpack.config.js
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と言ってるが、警告以外は修正したほうがいい。)

エラーレベルと内容

エラー
レベル
エラー名内容
1Schema validation fails
スキーマ検証に失敗
設定オプションが変更された。
BREAKING CHANGEでバリデーションエラーが発生している。

NOTE: または代わりに使用するオプションのヒントを表示。
2webpack exits with an error
webpackがエラーで終了
エラーメッセージは、何を変更する必要があるかを教えてくれる。
3Build Errors
ビルドエラー
エラーメッセージには、BREAKING CHANGEが表示される。
4Build Warnings
ビルド警告
警告メッセージは、何が改善できるかを伝える。
5Runtime Errors
ランタイムエラー
これは厄介。
デバッグしないと見つけられないだろう。
一般的なアドバイスはここでは難しい。
6Deprecation Warnings
非推奨の警告
Deprecationの警告はたくさん出るだろうが、直接の問題ではない。

プラグインはコアの変更に追いつくために時間が必要。
これらの非推奨事項をプラグインに報告してください。

これらは単なる警告であり、ビルドは小さな欠点(パフォーマンスの低下など)があっても動作する。
7Performance 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

これらのプロファイルをファイルに保存し、課題に提供することができます。

chromechrome://inspect
edgeedge://inspect

場合によってはスタックトレースを改善するために --no-turbo-inlining フラグを使用してみてください。

(個人談: ブラウザの開発ツール -> プロファイラーで解析できるみたい。)

インクリメンタルビルドでのモジュールのビルド時間

インクリメンタルビルドでのモジュールのビルド時間は、webpack 4 のように安全でないキャッシングに戻すことで改善できます。

webpack.config.js
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では内部構造の変更が行われましたが、一般的なユーザーの移行にはあまり関係ありません。

移行ガイドでは、興味のある人に情報提供していると言っています。

ということなので、移行ガイドのリンクだけ貼っておきます。

webpack.js.orgドキュメント

webpack 5 release 2020-10-10

To v5 from v4

前の投稿
webpackを4から5にアップデートしたら起きたこと。
webpack5, CSS圧縮でfont-familyのダブルクォーテーション(")を消さない方法
次の投稿

JavaScriptの本

post-cta-image

『自分は向いていない』『やってみたけど挫折した』『プログラマだけどjavaScriptは未経験』『フロントエンドエンジニアを目指したい』など、いろいろなタイプに合わせた書籍を集めました。

どうしてもネットで自分で調べるのが苦手という人におすすめです。

将来的には、書籍を買わずにネット上の公式ドキュメントで情報収集できるようなものを選んでいます。

コメントを残す

*