Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 08ab3ac

Browse files
authored
Fix mini-css-plugin webpack 5 deprecation warnings (#16390)
Solves the warnings coming from mini-css-plugin in webpack 5. Fixes #15947
1 parent 3e81809 commit 08ab3ac

File tree

3 files changed

+185
-115
lines changed

3 files changed

+185
-115
lines changed

packages/next/build/webpack/plugins/mini-css-extract-plugin/src/index.js

+100-78
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const {
1212
util: { createHash },
1313
} = webpack
1414

15+
const isWebpack5 = parseInt(webpack.version) === 5
1516
const MODULE_TYPE = 'css/mini-extract'
1617

1718
const pluginName = 'mini-css-extract-plugin'
@@ -22,6 +23,14 @@ const REGEXP_NAME = /\[name\]/i
2223
const REGEXP_PLACEHOLDERS = /\[(name|id|chunkhash)\]/g
2324
const DEFAULT_FILENAME = '[name].css'
2425

26+
function getModulesIterable(compilation, chunk) {
27+
if (isWebpack5) {
28+
return compilation.chunkGraph.getChunkModulesIterable(chunk)
29+
}
30+
31+
return chunk.modulesIterable
32+
}
33+
2534
class CssDependencyTemplate {
2635
apply() {}
2736
}
@@ -68,94 +77,103 @@ class MiniCssExtractPlugin {
6877
new CssDependencyTemplate()
6978
)
7079

71-
compilation.mainTemplate.hooks.renderManifest.tap(
72-
pluginName,
73-
(result, { chunk }) => {
74-
const renderedModules = Array.from(chunk.modulesIterable).filter(
75-
(module) => module.type === MODULE_TYPE
76-
)
80+
const renderManifestFn = (result, { chunk }) => {
81+
const renderedModules = Array.from(
82+
getModulesIterable(compilation, chunk)
83+
).filter((module) => module.type === MODULE_TYPE)
7784

78-
if (renderedModules.length > 0) {
79-
result.push({
80-
render: () =>
81-
this.renderContentAsset(
82-
compilation,
83-
chunk,
84-
renderedModules,
85-
compilation.runtimeTemplate.requestShortener
86-
),
87-
filenameTemplate: ({ chunk: chunkData }) =>
88-
this.options.moduleFilename(chunkData),
89-
pathOptions: {
85+
if (renderedModules.length > 0) {
86+
result.push({
87+
render: () =>
88+
this.renderContentAsset(
89+
compilation,
9090
chunk,
91-
contentHashType: MODULE_TYPE,
92-
},
93-
identifier: `${pluginName}.${chunk.id}`,
94-
hash: chunk.contentHash[MODULE_TYPE],
95-
})
96-
}
91+
renderedModules,
92+
compilation.runtimeTemplate.requestShortener
93+
),
94+
filenameTemplate: ({ chunk: chunkData }) =>
95+
this.options.moduleFilename(chunkData),
96+
pathOptions: {
97+
chunk,
98+
contentHashType: MODULE_TYPE,
99+
},
100+
identifier: `${pluginName}.${chunk.id}`,
101+
hash: chunk.contentHash[MODULE_TYPE],
102+
})
97103
}
98-
)
99-
100-
compilation.chunkTemplate.hooks.renderManifest.tap(
101-
pluginName,
102-
(result, { chunk }) => {
103-
const renderedModules = Array.from(chunk.modulesIterable).filter(
104-
(module) => module.type === MODULE_TYPE
105-
)
104+
}
106105

107-
if (renderedModules.length > 0) {
108-
result.push({
109-
render: () =>
110-
this.renderContentAsset(
111-
compilation,
112-
chunk,
113-
renderedModules,
114-
compilation.runtimeTemplate.requestShortener
115-
),
116-
filenameTemplate: this.options.chunkFilename,
117-
pathOptions: {
118-
chunk,
119-
contentHashType: MODULE_TYPE,
120-
},
121-
identifier: `${pluginName}.${chunk.id}`,
122-
hash: chunk.contentHash[MODULE_TYPE],
123-
})
124-
}
125-
}
126-
)
106+
if (isWebpack5) {
107+
compilation.hooks.renderManifest.tap(pluginName, renderManifestFn)
108+
} else {
109+
// In webpack 5 the 2 separate hooks are now one hook: `compilation.hooks.renderManifest`
110+
// So we no longer have to double-apply the same function
111+
compilation.mainTemplate.hooks.renderManifest.tap(
112+
pluginName,
113+
renderManifestFn
114+
)
115+
compilation.chunkTemplate.hooks.renderManifest.tap(
116+
pluginName,
117+
renderManifestFn
118+
)
119+
}
127120

128-
compilation.mainTemplate.hooks.hashForChunk.tap(
129-
pluginName,
130-
(hash, chunk) => {
131-
const { chunkFilename } = this.options
121+
const handleHashForChunk = (hash, chunk) => {
122+
const { chunkFilename } = this.options
132123

133-
if (REGEXP_CHUNKHASH.test(chunkFilename)) {
134-
hash.update(JSON.stringify(chunk.getChunkMaps(true).hash))
135-
}
124+
if (REGEXP_CHUNKHASH.test(chunkFilename)) {
125+
hash.update(JSON.stringify(chunk.getChunkMaps(true).hash))
126+
}
136127

137-
if (REGEXP_CONTENTHASH.test(chunkFilename)) {
138-
hash.update(
139-
JSON.stringify(
140-
chunk.getChunkMaps(true).contentHash[MODULE_TYPE] || {}
141-
)
128+
if (REGEXP_CONTENTHASH.test(chunkFilename)) {
129+
hash.update(
130+
JSON.stringify(
131+
chunk.getChunkMaps(true).contentHash[MODULE_TYPE] || {}
142132
)
143-
}
133+
)
134+
}
144135

145-
if (REGEXP_NAME.test(chunkFilename)) {
146-
hash.update(JSON.stringify(chunk.getChunkMaps(true).name))
147-
}
136+
if (REGEXP_NAME.test(chunkFilename)) {
137+
hash.update(JSON.stringify(chunk.getChunkMaps(true).name))
148138
}
149-
)
139+
}
140+
if (isWebpack5) {
141+
const JSModulesHooks = webpack.javascript.JavascriptModulesPlugin.getCompilationHooks(
142+
compilation
143+
)
144+
JSModulesHooks.chunkHash.tap(pluginName, (chunk, hash) => {
145+
if (!chunk.hasRuntime()) return
146+
return handleHashForChunk(hash, chunk)
147+
})
148+
} else {
149+
compilation.mainTemplate.hooks.hashForChunk.tap(
150+
pluginName,
151+
handleHashForChunk
152+
)
153+
}
150154

151155
compilation.hooks.contentHash.tap(pluginName, (chunk) => {
152156
const { outputOptions } = compilation
153157
const { hashFunction, hashDigest, hashDigestLength } = outputOptions
154158
const hash = createHash(hashFunction)
155159

156-
for (const m of chunk.modulesIterable) {
157-
if (m.type === MODULE_TYPE) {
158-
m.updateHash(hash)
160+
const modules = getModulesIterable(compilation, chunk)
161+
162+
if (modules) {
163+
if (isWebpack5) {
164+
const xor = new (require('webpack/lib/util/StringXor'))()
165+
for (const m of modules) {
166+
if (m.type === MODULE_TYPE) {
167+
xor.add(compilation.chunkGraph.getModuleHash(m, chunk.runtime))
168+
}
169+
}
170+
xor.updateHash(hash)
171+
} else {
172+
for (const m of modules) {
173+
if (m.type === MODULE_TYPE) {
174+
m.updateHash(hash)
175+
}
176+
}
159177
}
160178
}
161179

@@ -169,7 +187,7 @@ class MiniCssExtractPlugin {
169187
const { mainTemplate } = compilation
170188

171189
mainTemplate.hooks.localVars.tap(pluginName, (source, chunk) => {
172-
const chunkMap = this.getCssChunkObject(chunk)
190+
const chunkMap = this.getCssChunkObject(compilation, chunk)
173191

174192
if (Object.keys(chunkMap).length > 0) {
175193
return Template.asString([
@@ -190,7 +208,7 @@ class MiniCssExtractPlugin {
190208
mainTemplate.hooks.requireEnsure.tap(
191209
pluginName,
192210
(source, chunk, hash) => {
193-
const chunkMap = this.getCssChunkObject(chunk)
211+
const chunkMap = this.getCssChunkObject(compilation, chunk)
194212

195213
if (Object.keys(chunkMap).length > 0) {
196214
const chunkMaps = chunk.getChunkMaps()
@@ -322,11 +340,11 @@ class MiniCssExtractPlugin {
322340
})
323341
}
324342

325-
getCssChunkObject(mainChunk) {
343+
getCssChunkObject(compilation, mainChunk) {
326344
const obj = {}
327345

328346
for (const chunk of mainChunk.getAllAsyncChunks()) {
329-
for (const module of chunk.modulesIterable) {
347+
for (const module of getModulesIterable(compilation, chunk)) {
330348
if (module.type === MODULE_TYPE) {
331349
obj[chunk.id] = 1
332350
break
@@ -342,7 +360,9 @@ class MiniCssExtractPlugin {
342360

343361
const [chunkGroup] = chunk.groupsIterable
344362

345-
if (typeof chunkGroup.getModuleIndex2 === 'function') {
363+
const getModulePostOrderIndex =
364+
chunkGroup.getModulePostOrderIndex || chunkGroup.getModuleIndex2
365+
if (typeof getModulePostOrderIndex === 'function') {
346366
// Store dependencies for modules
347367
const moduleDependencies = new Map(modules.map((m) => [m, new Set()]))
348368
const moduleDependenciesReasons = new Map(
@@ -357,7 +377,9 @@ class MiniCssExtractPlugin {
357377
.map((m) => {
358378
return {
359379
module: m,
360-
index: cg.getModuleIndex2(m),
380+
index: isWebpack5
381+
? cg.getModulePostOrderIndex(m)
382+
: cg.getModuleIndex2(m),
361383
}
362384
})
363385
// eslint-disable-next-line no-undefined

0 commit comments

Comments
 (0)