@@ -4,6 +4,7 @@ import webpack from 'webpack';
44import sources from 'webpack-sources' ;
55
66const { RawSource, ConcatSource } = sources ;
7+ const { Template } = webpack ;
78
89const NS = path . dirname ( fs . realpathSync ( __filename ) ) ;
910
@@ -118,8 +119,75 @@ class MiniCssExtractPlugin {
118119 } ) ;
119120 }
120121 } ) ;
122+ const { mainTemplate } = compilation ;
123+ mainTemplate . hooks . requireEnsure . tap (
124+ 'mini-css-extract-plugin' ,
125+ ( source , chunk , hash ) => {
126+ const chunkMap = this . getCssChunkObject ( chunk ) ;
127+ if ( Object . keys ( chunkMap ) . length > 0 ) {
128+ const chunkMaps = chunk . getChunkMaps ( ) ;
129+ const linkHrefPath = mainTemplate . getAssetPath (
130+ JSON . stringify ( this . options . chunkFilename ) ,
131+ {
132+ hash : `" + ${ mainTemplate . renderCurrentHashCode ( hash ) } + "` ,
133+ hashWithLength : length =>
134+ `" + ${ mainTemplate . renderCurrentHashCode ( hash , length ) } + "` ,
135+ chunk : {
136+ id : '" + chunkId + "' ,
137+ hash : `" + ${ JSON . stringify ( chunkMaps . hash ) } [chunkId] + "` ,
138+ hashWithLength ( length ) {
139+ const shortChunkHashMap = Object . create ( null ) ;
140+ for ( const chunkId of Object . keys ( chunkMaps . hash ) ) {
141+ if ( typeof chunkMaps . hash [ chunkId ] === 'string' ) {
142+ shortChunkHashMap [ chunkId ] = chunkMaps . hash [ chunkId ] . substr ( 0 , length ) ;
143+ }
144+ }
145+ return `" + ${ JSON . stringify ( shortChunkHashMap ) } [chunkId] + "` ;
146+ } ,
147+ name : `" + (${ JSON . stringify ( chunkMaps . name ) } [chunkId]||chunkId) + "` ,
148+ } ,
149+ } ,
150+ ) ;
151+ return Template . asString ( [
152+ source ,
153+ '' ,
154+ '// mini-css-extract-plugin CSS loading' ,
155+ `var cssChunks = ${ JSON . stringify ( chunkMap ) } ;` ,
156+ 'if(cssChunks[chunkId]) {' ,
157+ Template . indent ( [
158+ 'promises.push(new Promise(function(resolve, reject) {' ,
159+ Template . indent ( [
160+ 'var linkTag = document.createElement("link");' ,
161+ 'linkTag.rel = "stylesheet";' ,
162+ 'linkTag.onload = resolve;' ,
163+ 'linkTag.onerror = reject;' ,
164+ `linkTag.href = ${ linkHrefPath } ;` ,
165+ 'var head = document.getElementsByTagName("head")[0];' ,
166+ 'head.appendChild(linkTag);' ,
167+ ] ) ,
168+ '}));' ,
169+ ] ) ,
170+ '}' ,
171+ ] ) ;
172+ }
173+ return source ;
174+ } ) ;
121175 } ) ;
122176 }
177+
178+ getCssChunkObject ( mainChunk ) {
179+ const obj = { } ;
180+ for ( const chunk of mainChunk . getAllAsyncChunks ( ) ) {
181+ for ( const module of chunk . modulesIterable ) {
182+ if ( module . type === NS ) {
183+ obj [ chunk . id ] = 1 ;
184+ break ;
185+ }
186+ }
187+ }
188+ return obj ;
189+ }
190+
123191 renderContentAsset ( modules ) {
124192 modules . sort ( ( a , b ) => a . index2 - b . index2 ) ;
125193 // TODO put @import on top
0 commit comments