@@ -23,6 +23,19 @@ const REGEXP_CONTENTHASH = /\[contenthash(?::(\d+))?\]/i;
2323const REGEXP_NAME = / \[ n a m e \] / i;
2424const DEFAULT_FILENAME = '[name].css' ;
2525
26+ const compareIds = ( a , b ) => {
27+ if ( typeof a !== typeof b ) {
28+ return typeof a < typeof b ? - 1 : 1 ;
29+ }
30+ if ( a < b ) return - 1 ;
31+ if ( a > b ) return 1 ;
32+ return 0 ;
33+ } ;
34+
35+ const compareModulesByIdentifier = ( a , b ) => {
36+ return compareIds ( a . identifier ( ) , b . identifier ( ) ) ;
37+ } ;
38+
2639class CssDependencyTemplate {
2740 apply ( ) { }
2841}
@@ -82,8 +95,8 @@ class CssModule extends webpack.Module {
8295 callback ( ) ;
8396 }
8497
85- updateHash ( hash ) {
86- super . updateHash ( hash ) ;
98+ updateHash ( hash , chunkGraph ) {
99+ super . updateHash ( hash , chunkGraph ) ;
87100
88101 hash . update ( this . content ) ;
89102 hash . update ( this . media || '' ) ;
@@ -132,7 +145,7 @@ class MiniCssExtractPlugin {
132145 ) ;
133146 }
134147 } else {
135- this . options . chunkFilename = '[id].css' ;
148+ this . options . chunkFilename = DEFAULT_FILENAME ;
136149 }
137150 }
138151 }
@@ -149,71 +162,117 @@ class MiniCssExtractPlugin {
149162 new CssDependencyTemplate ( )
150163 ) ;
151164
152- compilation . mainTemplate . hooks . renderManifest . tap (
153- pluginName ,
154- ( result , { chunk } ) => {
155- const renderedModules = Array . from ( chunk . modulesIterable ) . filter (
156- ( module ) => module . type === MODULE_TYPE
157- ) ;
158-
159- const filenameTemplate =
160- chunk . filenameTemplate || this . options . filename ;
161-
162- if ( renderedModules . length > 0 ) {
163- result . push ( {
164- render : ( ) =>
165- this . renderContentAsset (
166- compilation ,
165+ // Webpack 4
166+ if ( ! compilation . hooks . renderManifest ) {
167+ compilation . mainTemplate . hooks . renderManifest . tap (
168+ pluginName ,
169+ ( result , { chunk } ) => {
170+ const { chunkGraph } = compilation ;
171+
172+ const renderedModules = Array . from (
173+ this . getChunks ( chunk , chunkGraph )
174+ ) . filter ( ( module ) => module . type === MODULE_TYPE ) ;
175+
176+ const filenameTemplate =
177+ chunk . filenameTemplate || this . options . filename ;
178+
179+ if ( renderedModules . length > 0 ) {
180+ result . push ( {
181+ render : ( ) =>
182+ this . renderContentAsset (
183+ compilation ,
184+ chunk ,
185+ renderedModules ,
186+ compilation . runtimeTemplate . requestShortener
187+ ) ,
188+ filenameTemplate,
189+ pathOptions : {
167190 chunk,
168- renderedModules ,
169- compilation . runtimeTemplate . requestShortener
170- ) ,
171- filenameTemplate,
172- pathOptions : {
173- chunk,
174- contentHashType : MODULE_TYPE ,
175- } ,
176- identifier : `${ pluginName } .${ chunk . id } ` ,
177- hash : chunk . contentHash [ MODULE_TYPE ] ,
178- } ) ;
191+ contentHashType : MODULE_TYPE ,
192+ } ,
193+ identifier : `${ pluginName } .${ chunk . id } ` ,
194+ hash : chunk . contentHash [ MODULE_TYPE ] ,
195+ } ) ;
196+ }
179197 }
180- }
181- ) ;
182-
183- compilation . chunkTemplate . hooks . renderManifest . tap (
184- pluginName ,
185- ( result , { chunk } ) => {
186- const renderedModules = Array . from ( chunk . modulesIterable ) . filter (
187- ( module ) => module . type === MODULE_TYPE
188- ) ;
189-
190- const filenameTemplate =
191- chunk . filenameTemplate || this . options . chunkFilename ;
192-
193- if ( renderedModules . length > 0 ) {
194- result . push ( {
195- render : ( ) =>
196- this . renderContentAsset (
197- compilation ,
198+ ) ;
199+
200+ compilation . chunkTemplate . hooks . renderManifest . tap (
201+ pluginName ,
202+ ( result , { chunk } ) => {
203+ const { chunkGraph } = compilation ;
204+
205+ const renderedModules = Array . from (
206+ this . getChunks ( chunk , chunkGraph )
207+ ) . filter ( ( module ) => module . type === MODULE_TYPE ) ;
208+
209+ const filenameTemplate =
210+ chunk . filenameTemplate || this . options . chunkFilename ;
211+
212+ if ( renderedModules . length > 0 ) {
213+ result . push ( {
214+ render : ( ) =>
215+ this . renderContentAsset (
216+ compilation ,
217+ chunk ,
218+ renderedModules ,
219+ compilation . runtimeTemplate . requestShortener
220+ ) ,
221+ filenameTemplate,
222+ pathOptions : {
198223 chunk,
199- renderedModules ,
200- compilation . runtimeTemplate . requestShortener
201- ) ,
202- filenameTemplate,
203- pathOptions : {
204- chunk,
205- contentHashType : MODULE_TYPE ,
206- } ,
207- identifier : `${ pluginName } .${ chunk . id } ` ,
208- hash : chunk . contentHash [ MODULE_TYPE ] ,
209- } ) ;
224+ contentHashType : MODULE_TYPE ,
225+ } ,
226+ identifier : `${ pluginName } .${ chunk . id } ` ,
227+ hash : chunk . contentHash [ MODULE_TYPE ] ,
228+ } ) ;
229+ }
210230 }
211- }
212- ) ;
231+ ) ;
232+ } else {
233+ compilation . hooks . renderManifest . tap (
234+ pluginName ,
235+ ( result , { chunk } ) => {
236+ const { chunkGraph } = compilation ;
237+
238+ const renderedModules = Array . from (
239+ this . getChunks ( chunk , chunkGraph )
240+ ) . filter ( ( module ) => module . type === MODULE_TYPE ) ;
241+
242+ const filenameTemplate =
243+ chunk . filenameTemplate || chunk . hasRuntime ( )
244+ ? this . options . filename
245+ : this . options . chunkFilename ;
246+
247+ if ( renderedModules . length > 0 ) {
248+ result . push ( {
249+ render : ( ) =>
250+ this . renderContentAsset (
251+ compilation ,
252+ chunk ,
253+ renderedModules ,
254+ compilation . runtimeTemplate . requestShortener
255+ ) ,
256+ filenameTemplate,
257+ pathOptions : {
258+ chunk,
259+ contentHashType : MODULE_TYPE ,
260+ } ,
261+ identifier : `${ pluginName } .${ chunk . id } ` ,
262+ hash : chunk . contentHash [ MODULE_TYPE ] ,
263+ } ) ;
264+ }
265+ }
266+ ) ;
267+ }
213268
214- compilation . mainTemplate . hooks . hashForChunk . tap (
215- pluginName ,
216- ( hash , chunk ) => {
269+ if (
270+ typeof webpack . javascript !== 'undefined' &&
271+ typeof webpack . javascript . JavascriptModulesPlugin !== 'undefined'
272+ ) {
273+ webpack . javascript . JavascriptModulesPlugin . getCompilationHooks (
274+ compilation
275+ ) . chunkHash . tap ( pluginName , ( chunk , hash ) => {
217276 const { chunkFilename } = this . options ;
218277
219278 if ( REGEXP_CHUNKHASH . test ( chunkFilename ) ) {
@@ -231,17 +290,40 @@ class MiniCssExtractPlugin {
231290 if ( REGEXP_NAME . test ( chunkFilename ) ) {
232291 hash . update ( JSON . stringify ( chunk . getChunkMaps ( true ) . name ) ) ;
233292 }
234- }
235- ) ;
293+ } ) ;
294+ } else {
295+ compilation . mainTemplate . hooks . hashForChunk . tap (
296+ pluginName ,
297+ ( hash , chunk ) => {
298+ const { chunkFilename } = this . options ;
299+
300+ if ( REGEXP_CHUNKHASH . test ( chunkFilename ) ) {
301+ hash . update ( JSON . stringify ( chunk . getChunkMaps ( true ) . hash ) ) ;
302+ }
303+
304+ if ( REGEXP_CONTENTHASH . test ( chunkFilename ) ) {
305+ hash . update (
306+ JSON . stringify (
307+ chunk . getChunkMaps ( true ) . contentHash [ MODULE_TYPE ] || { }
308+ )
309+ ) ;
310+ }
311+
312+ if ( REGEXP_NAME . test ( chunkFilename ) ) {
313+ hash . update ( JSON . stringify ( chunk . getChunkMaps ( true ) . name ) ) ;
314+ }
315+ }
316+ ) ;
317+ }
236318
237319 compilation . hooks . contentHash . tap ( pluginName , ( chunk ) => {
238- const { outputOptions } = compilation ;
320+ const { outputOptions, chunkGraph } = compilation ;
239321 const { hashFunction, hashDigest, hashDigestLength } = outputOptions ;
240322 const hash = createHash ( hashFunction ) ;
241323
242- for ( const m of chunk . modulesIterable ) {
324+ for ( const m of this . getChunks ( chunk , chunkGraph ) ) {
243325 if ( m . type === MODULE_TYPE ) {
244- m . updateHash ( hash ) ;
326+ m . updateHash ( hash , chunkGraph ) ;
245327 }
246328 }
247329
@@ -255,7 +337,7 @@ class MiniCssExtractPlugin {
255337 const { mainTemplate } = compilation ;
256338
257339 mainTemplate . hooks . localVars . tap ( pluginName , ( source , chunk ) => {
258- const chunkMap = this . getCssChunkObject ( chunk ) ;
340+ const chunkMap = this . getCssChunkObject ( chunk , compilation ) ;
259341
260342 if ( Object . keys ( chunkMap ) . length > 0 ) {
261343 return Template . asString ( [
@@ -276,17 +358,28 @@ class MiniCssExtractPlugin {
276358 mainTemplate . hooks . requireEnsure . tap (
277359 pluginName ,
278360 ( source , chunk , hash ) => {
279- const chunkMap = this . getCssChunkObject ( chunk ) ;
361+ const chunkMap = this . getCssChunkObject ( chunk , compilation ) ;
362+ const isWebpackNext = typeof webpack . RuntimeGlobals !== 'undefined' ;
280363
281364 if ( Object . keys ( chunkMap ) . length > 0 ) {
365+ const maintemplateObject = isWebpackNext
366+ ? compilation
367+ : mainTemplate ;
282368 const chunkMaps = chunk . getChunkMaps ( ) ;
283- const { crossOriginLoading } = mainTemplate . outputOptions ;
284- const linkHrefPath = mainTemplate . getAssetPath (
369+ const { crossOriginLoading } = maintemplateObject . outputOptions ;
370+ const linkHrefPath = maintemplateObject . getAssetPath (
285371 JSON . stringify ( this . options . chunkFilename ) ,
286372 {
287- hash : `" + ${ mainTemplate . renderCurrentHashCode ( hash ) } + "` ,
373+ hash : isWebpackNext
374+ ? `" + ${ webpack . RuntimeGlobals . getFullHash } + "`
375+ : `" + ${ mainTemplate . renderCurrentHashCode ( hash ) } + "` ,
288376 hashWithLength : ( length ) =>
289- `" + ${ mainTemplate . renderCurrentHashCode ( hash , length ) } + "` ,
377+ isWebpackNext
378+ ? `" + ${ webpack . RuntimeGlobals . getFullHash } + "`
379+ : `" + ${ mainTemplate . renderCurrentHashCode (
380+ hash ,
381+ length
382+ ) } + "`,
290383 chunk : {
291384 id : '" + chunkId + "' ,
292385 hash : `" + ${ JSON . stringify ( chunkMaps . hash ) } [chunkId] + "` ,
@@ -347,7 +440,11 @@ class MiniCssExtractPlugin {
347440 'promises.push(installedCssChunks[chunkId] = new Promise(function(resolve, reject) {' ,
348441 Template . indent ( [
349442 `var href = ${ linkHrefPath } ;` ,
350- `var fullhref = ${ mainTemplate . requireFn } .p + href;` ,
443+ `var fullhref = ${
444+ isWebpackNext
445+ ? '__webpack_require__'
446+ : mainTemplate . requireFn
447+ } .p + href;`,
351448 'var existingLinkTags = document.getElementsByTagName("link");' ,
352449 'for(var i = 0; i < existingLinkTags.length; i++) {' ,
353450 Template . indent ( [
@@ -408,11 +505,21 @@ class MiniCssExtractPlugin {
408505 } ) ;
409506 }
410507
411- getCssChunkObject ( mainChunk ) {
508+ getChunks ( chunk , chunkGraph ) {
509+ return typeof chunkGraph !== 'undefined'
510+ ? chunkGraph . getOrderedChunkModulesIterable (
511+ chunk ,
512+ compareModulesByIdentifier
513+ )
514+ : chunk . modulesIterable ;
515+ }
516+
517+ getCssChunkObject ( mainChunk , compilation ) {
412518 const obj = { } ;
519+ const { chunkGraph } = compilation ;
413520
414521 for ( const chunk of mainChunk . getAllAsyncChunks ( ) ) {
415- for ( const module of chunk . modulesIterable ) {
522+ for ( const module of this . getChunks ( chunk , chunkGraph ) ) {
416523 if ( module . type === MODULE_TYPE ) {
417524 obj [ chunk . id ] = 1 ;
418525 break ;
@@ -427,8 +534,12 @@ class MiniCssExtractPlugin {
427534 let usedModules ;
428535
429536 const [ chunkGroup ] = chunk . groupsIterable ;
537+ const moduleIndexFunctionName =
538+ typeof compilation . chunkGraph !== 'undefined'
539+ ? 'getModulePostOrderIndex'
540+ : 'getModuleIndex2' ;
430541
431- if ( typeof chunkGroup . getModuleIndex2 === 'function' ) {
542+ if ( typeof chunkGroup [ moduleIndexFunctionName ] === 'function' ) {
432543 // Store dependencies for modules
433544 const moduleDependencies = new Map ( modules . map ( ( m ) => [ m , new Set ( ) ] ) ) ;
434545 const moduleDependenciesReasons = new Map (
@@ -443,7 +554,7 @@ class MiniCssExtractPlugin {
443554 . map ( ( m ) => {
444555 return {
445556 module : m ,
446- index : cg . getModuleIndex2 ( m ) ,
557+ index : cg [ moduleIndexFunctionName ] ( m ) ,
447558 } ;
448559 } )
449560 // eslint-disable-next-line no-undefined
0 commit comments