💭

webpackでつまりやすいchunkについて【随時更新】

2022/06/09に公開

概要

よく「webpackがわかりにくい」と思われる理由はさまざまあると思いますが、chunk周りがその大きな理由の一つになっているかなと個人的には考えています。

今回は、そのchunk周りの知識をメモ書き程度にこちらのスクラップにまとめていたものを記事化してみました。
※本記事は、このスクラップの更新に伴って随時更新していく予定です。

webpackで頻繁に登場するchunkの種類ごとの役割

【参考】webpack公式

  • [contenthash] -> ファイルごとに生成される一意の文字列
  • [id] -> entryオブジェクト内でのインデックス値(※これがまだよくわかってない
  • [name] -> バンドルするエントリーポイント名
    • デフォルト(entryの任意のchunk名を渡さなかった場合)では、mainという文字列が入る。
  • [hash] -> バンドル全体で共通のハッシュ値(一つだけ)
  • [chunkhash] -> エントリーポイントごと一意に生成されたハッシュ値

※ちなみに、hashchunkhashは同時には使用できない。

そもそもwebpackでよく聞く「チャンク(chunk)」とは?

チャンク(chunk)とは、バンドルした後に出力されるコード(ファイル)等の塊のことらしい。
ただし、1チャンク = 最終的に1ファイルに出力されるとは限らない
※プラグインを使えば、例えばcssだけ別の出力ファイルに抜き出すこともできる

werbpack.config.js
module.exports = {
  entry: './index.js',
};

上の例の場合、chunk名はデフォルトの設定であるmainが採用される。
webpackのパーサーが./index.js内でimportの処理を行うと、そのimportしたモジュールをmainチャンクに追加していく。

「チャンク(chunk)」についてもう少し詳しく

【参考】公式ドキュメント
チャンク(chunk)には二つの形態がある。

  1. initial
  2. non-initial

1. initialチャンク

エントリーポイントのメインチャンクのこと。
このチャンクには、エントリーポイントに指定する全てのモジュールとその依存関係が含まれる。

2. non-initialチャンク

遅延ロードされる可能性があるチャンクのこと。
Dynamic importSplitChunksPluginが使用されている場合に表示される。

上の各チャンクには、対応するアセット(出力ファイルのことで、バンドルした結果を指す)があります。

【例】

webpack.config.js
module.exports = {
    exntry:  './src/index.jsx'
}
./src/index.jsx
import React from 'react';
import ReactDOM from 'react-dom';

import('./app.jsx').then((App) => {
    ReactDOM.render(<App />, root);
});

この上の例の場合、initialチャンクとしてmainチャンク(デフォルトの設定)が作成されます。
そしてmainチャンクには、以下のモジュールが含まれます。

  • エントリファイル本体である./src/index.jsx
  • react(importしているライブラリ)
  • react-dom(importしているライブラリ)
  • 動的importしている./app.jsx除く、全ての依存関係

またこのモジュールは動的インポートされているため、./app.jsxの非初期チャンクが作成されます。

【バンドル出力結果】

  • initialチャンク -> /dist/main.js
  • non-initialチャンク -> /dist/394.js

デフォルトでnon-initialチャンクには名前がなく、一意のIDが使用されます。
動的インポートであれば、マジックコメントを使用して明示的に名前を指定することも可能です。

./src/indexjsx
import(
    /* webpackChunkName: "app" */
    './app.jsx'
).then((App) => {
    ReactDOM.render(<App />, root);
});

【バンドル出力結果】

  • initialチャンク -> /dist/main.js
  • non-initialチャンク -> /dist/app.js

出力ファイル名に関して

webpackでは出力ファイルの名前に二つの形式を設定することができます。

  1. filename
  2. chunkFilename

filename

公式ドキュメント(filename)
filenameは、initialチャンクファイルにつけられる名前を決定します。

chunkFilename

公式ドキュメント(chunkFilename)
chunkFilennameは、non-initialチャンクにつけられる名前を決定します。

※復習
【initialチャンク】
エントリーポイントのメインチャンクのこと。
このチャンクには、エントリーポイントに指定する全てのモジュールとその依存関係が含まれる。

【non-initialチャンク】
遅延ロードされる可能性があるチャンクのこと。
Dynamic importやSplitChunksPluginが使用されている場合に表示される。

※initialチャンクもnon-initialチャンクも使われる場合には、output.filenameの方が適用される。

Discussion