diff --git a/src/content/contribute/plugin-patterns.mdx b/src/content/contribute/plugin-patterns.mdx index d02663309be1..762a34d9fbd1 100644 --- a/src/content/contribute/plugin-patterns.mdx +++ b/src/content/contribute/plugin-patterns.mdx @@ -93,7 +93,13 @@ W> Since webpack 5, `compilation.fileDependencies`, `compilation.contextDependen ## Changed chunks -Similar to the watch graph, you can monitor changed chunks (or modules, for that matter) within a compilation by tracking their hashes. +Similar to the watch graph, you can monitor changed chunks within a compilation by tracking their content hashes. + +W> In webpack 5, `compilation.chunks` is a `Set`, not an array. +Calling `.filter()` or `.map()` directly on it throws a `TypeError`. +Use `for...of` or spread it into an array first. + +W> `chunk.hash` was removed in webpack 5. Use `chunk.contentHash.javascript` instead. Using the old property returns `undefined`, causing every chunk to appear changed on every rebuild. ```js class MyPlugin { @@ -103,11 +109,29 @@ class MyPlugin { apply(compiler) { compiler.hooks.emit.tapAsync("MyPlugin", (compilation, callback) => { - const changedChunks = compilation.chunks.filter((chunk) => { - const oldVersion = this.chunkVersions[chunk.name]; - this.chunkVersions[chunk.name] = chunk.hash; - return chunk.hash !== oldVersion; - }); + const changedChunks = []; + + for (const chunk of compilation.chunks) { + const key = chunk.id ?? chunk.name; + const currentHash = chunk.contentHash.javascript; + + if (currentHash === undefined) continue; + + const oldHash = this.chunkVersions[key]; + this.chunkVersions[key] = currentHash; + + if (currentHash !== oldHash) { + changedChunks.push(chunk); + } + } + + if (changedChunks.length > 0) { + console.log( + "Changed chunks:", + changedChunks.map((chunk) => chunk.id), + ); + } + callback(); }); } @@ -115,3 +139,6 @@ class MyPlugin { export default MyPlugin; ``` + +T> Use `chunk.id ?? chunk.name` as the tracking key. Some chunks have an `id` but no `name`, so relying on `chunk.name` alone can miss changes. +CSS or other non-JS chunks may not have a `javascript` key in `contentHash` — the `continue` guard skips those safely.