Skip to content

Commit 0093c61

Browse files
authored
fix(contribute): fix webpack 4 patterns in plugin-patterns Changed chunks section (#8168)
1 parent e3b5a1e commit 0093c61

File tree

1 file changed

+34
-6
lines changed

1 file changed

+34
-6
lines changed

src/content/contribute/plugin-patterns.mdx

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ contributors:
55
- nveenjain
66
- EugeneHlushko
77
- benglynn
8+
- raj-sapalya
89
---
910

1011
Plugins grant unlimited opportunity to perform customizations within the webpack build system. This allows you to create custom asset types, perform unique build modifications, or even enhance the webpack runtime while using middleware. The following are some features of webpack that become useful while writing plugins.
@@ -93,7 +94,13 @@ W> Since webpack 5, `compilation.fileDependencies`, `compilation.contextDependen
9394

9495
## Changed chunks
9596

96-
Similar to the watch graph, you can monitor changed chunks (or modules, for that matter) within a compilation by tracking their hashes.
97+
Similar to the watch graph, you can monitor changed chunks within a compilation by tracking their content hashes.
98+
99+
W> `compilation.chunks` is a `Set`, not an array. Calling `.filter()` or `.map()` directly on it throws a `TypeError`.
100+
Use `for...of` or spread it into an array first.
101+
102+
W> `chunk.hash` is not defined on chunk objects. Use `chunk.contentHash.javascript` instead.
103+
Accessing `chunk.hash` returns `undefined`, causing every chunk to appear changed on every rebuild.
97104

98105
```js
99106
class MyPlugin {
@@ -103,15 +110,36 @@ class MyPlugin {
103110

104111
apply(compiler) {
105112
compiler.hooks.emit.tapAsync("MyPlugin", (compilation, callback) => {
106-
const changedChunks = compilation.chunks.filter((chunk) => {
107-
const oldVersion = this.chunkVersions[chunk.name];
108-
this.chunkVersions[chunk.name] = chunk.hash;
109-
return chunk.hash !== oldVersion;
110-
});
113+
const changedChunks = [];
114+
115+
for (const chunk of compilation.chunks) {
116+
const key = chunk.id ?? chunk.name;
117+
const currentHash = chunk.contentHash.javascript;
118+
119+
if (currentHash === undefined) continue;
120+
121+
const oldHash = this.chunkVersions[key];
122+
this.chunkVersions[key] = currentHash;
123+
124+
if (currentHash !== oldHash) {
125+
changedChunks.push(chunk);
126+
}
127+
}
128+
129+
if (changedChunks.length > 0) {
130+
console.log(
131+
"Changed chunks:",
132+
changedChunks.map((chunk) => chunk.id),
133+
);
134+
}
135+
111136
callback();
112137
});
113138
}
114139
}
115140

116141
export default MyPlugin;
117142
```
143+
144+
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.
145+
CSS or other non-JS chunks may not have a `javascript` key in `contentHash` — the `continue` guard skips those safely.

0 commit comments

Comments
 (0)