@@ -40,87 +40,153 @@ module.exports = class CssLoadingRuntimeModule extends RuntimeModule {
4040 } = compilation ;
4141 const chunkMap = getCssChunkObject ( chunk , compilation ) ;
4242
43- if ( Object . keys ( chunkMap ) . length === 0 ) return null ;
44-
45- const withLoading = runtimeRequirements . has (
46- RuntimeGlobals . ensureChunkHandlers
43+ const withLoading =
44+ runtimeRequirements . has ( RuntimeGlobals . ensureChunkHandlers ) &&
45+ Object . keys ( chunkMap ) . length > 0 ;
46+ const withHmr = runtimeRequirements . has (
47+ RuntimeGlobals . hmrDownloadUpdateHandlers
4748 ) ;
4849
50+ if ( ! withLoading && ! withHmr ) return null ;
51+
4952 return Template . asString ( [
50- '// object to store loaded CSS chunks' ,
51- 'var installedCssChunks = {' ,
52- Template . indent (
53- chunk . ids . map ( ( id ) => `${ JSON . stringify ( id ) } : 0` ) . join ( ',\n' )
54- ) ,
55- '};' ,
56- '' ,
53+ `var createStylesheet = ${ runtimeTemplate . basicFunction (
54+ 'fullhref, resolve, reject' ,
55+ [
56+ 'var linkTag = document.createElement("link");' ,
57+ 'linkTag.rel = "stylesheet";' ,
58+ 'linkTag.type = "text/css";' ,
59+ 'linkTag.onload = resolve;' ,
60+ 'linkTag.onerror = function(event) {' ,
61+ Template . indent ( [
62+ 'var request = event && event.target && event.target.src || fullhref;' ,
63+ 'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + request + ")");' ,
64+ 'err.code = "CSS_CHUNK_LOAD_FAILED";' ,
65+ 'err.request = request;' ,
66+ 'linkTag.parentNode.removeChild(linkTag)' ,
67+ 'reject(err);' ,
68+ ] ) ,
69+ '};' ,
70+ 'linkTag.href = fullhref;' ,
71+ crossOriginLoading
72+ ? Template . asString ( [
73+ `if (linkTag.href.indexOf(window.location.origin + '/') !== 0) {` ,
74+ Template . indent (
75+ `linkTag.crossOrigin = ${ JSON . stringify ( crossOriginLoading ) } ;`
76+ ) ,
77+ '}' ,
78+ ] )
79+ : '' ,
80+ 'var head = document.getElementsByTagName("head")[0];' ,
81+ 'head.appendChild(linkTag);' ,
82+ 'return linkTag;' ,
83+ ]
84+ ) } ;`,
85+ `var findStylesheet = ${ runtimeTemplate . basicFunction ( 'href, fullhref' , [
86+ 'var existingLinkTags = document.getElementsByTagName("link");' ,
87+ 'for(var i = 0; i < existingLinkTags.length; i++) {' ,
88+ Template . indent ( [
89+ 'var tag = existingLinkTags[i];' ,
90+ 'var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");' ,
91+ 'if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return tag;' ,
92+ ] ) ,
93+ '}' ,
94+ 'var existingStyleTags = document.getElementsByTagName("style");' ,
95+ 'for(var i = 0; i < existingStyleTags.length; i++) {' ,
96+ Template . indent ( [
97+ 'var tag = existingStyleTags[i];' ,
98+ 'var dataHref = tag.getAttribute("data-href");' ,
99+ 'if(dataHref === href || dataHref === fullhref) return tag;' ,
100+ ] ) ,
101+ '}' ,
102+ ] ) } ;`,
103+ `var loadStylesheet = ${ runtimeTemplate . basicFunction (
104+ 'chunkId' ,
105+ `return new Promise(${ runtimeTemplate . basicFunction ( 'resolve, reject' , [
106+ `var href = ${ RuntimeGlobals . require } .miniCssF(chunkId);` ,
107+ `var fullhref = ${ RuntimeGlobals . publicPath } + href;` ,
108+ 'if(findStylesheet(href, fullhref)) return resolve();' ,
109+ 'createStylesheet(fullhref, resolve, reject);' ,
110+ ] ) } );`
111+ ) } `,
57112 withLoading
58113 ? Template . asString ( [
114+ '// object to store loaded CSS chunks' ,
115+ 'var installedCssChunks = {' ,
116+ Template . indent (
117+ chunk . ids . map ( ( id ) => `${ JSON . stringify ( id ) } : 0` ) . join ( ',\n' )
118+ ) ,
119+ '};' ,
120+ '' ,
59121 `${
60122 RuntimeGlobals . ensureChunkHandlers
61123 } .miniCss = ${ runtimeTemplate . basicFunction ( 'chunkId, promises' , [
62124 `var cssChunks = ${ JSON . stringify ( chunkMap ) } ;` ,
63125 'if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);' ,
64126 'else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {' ,
65127 Template . indent ( [
66- 'promises.push(installedCssChunks[chunkId] = new Promise(function(resolve, reject) {' ,
67- Template . indent ( [
68- `var href = ${ RuntimeGlobals . require } .miniCssF(chunkId);` ,
69- `var fullhref = ${ RuntimeGlobals . publicPath } + href;` ,
70- 'var existingLinkTags = document.getElementsByTagName("link");' ,
71- 'for(var i = 0; i < existingLinkTags.length; i++) {' ,
72- Template . indent ( [
73- 'var tag = existingLinkTags[i];' ,
74- 'var dataHref = tag.getAttribute("data-href") || tag.getAttribute("href");' ,
75- 'if(tag.rel === "stylesheet" && (dataHref === href || dataHref === fullhref)) return resolve();' ,
76- ] ) ,
77- '}' ,
78- 'var existingStyleTags = document.getElementsByTagName("style");' ,
79- 'for(var i = 0; i < existingStyleTags.length; i++) {' ,
80- Template . indent ( [
81- 'var tag = existingStyleTags[i];' ,
82- 'var dataHref = tag.getAttribute("data-href");' ,
83- 'if(dataHref === href || dataHref === fullhref) return resolve();' ,
84- ] ) ,
85- '}' ,
86- 'var linkTag = document.createElement("link");' ,
87- 'linkTag.rel = "stylesheet";' ,
88- 'linkTag.type = "text/css";' ,
89- 'linkTag.onload = resolve;' ,
90- 'linkTag.onerror = function(event) {' ,
91- Template . indent ( [
92- 'var request = event && event.target && event.target.src || fullhref;' ,
93- 'var err = new Error("Loading CSS chunk " + chunkId + " failed.\\n(" + request + ")");' ,
94- 'err.code = "CSS_CHUNK_LOAD_FAILED";' ,
95- 'err.request = request;' ,
96- 'delete installedCssChunks[chunkId]' ,
97- 'linkTag.parentNode.removeChild(linkTag)' ,
98- 'reject(err);' ,
99- ] ) ,
100- '};' ,
101- 'linkTag.href = fullhref;' ,
102- crossOriginLoading
103- ? Template . asString ( [
104- `if (linkTag.href.indexOf(window.location.origin + '/') !== 0) {` ,
105- Template . indent (
106- `linkTag.crossOrigin = ${ JSON . stringify (
107- crossOriginLoading
108- ) } ;`
109- ) ,
110- '}' ,
111- ] )
112- : '' ,
113- 'var head = document.getElementsByTagName("head")[0];' ,
114- 'head.appendChild(linkTag);' ,
115- ] ) ,
116- '}).then(function() {' ,
117- Template . indent ( [ 'installedCssChunks[chunkId] = 0;' ] ) ,
118- '}));' ,
128+ `promises.push(installedCssChunks[chunkId] = loadStylesheet(chunkId).then(${ runtimeTemplate . basicFunction (
129+ '' ,
130+ 'installedCssChunks[chunkId] = 0;'
131+ ) } , ${ runtimeTemplate . basicFunction ( 'e' , [
132+ 'delete installedCssChunks[chunkId];' ,
133+ 'throw e;' ,
134+ ] ) } ));`,
119135 ] ) ,
120136 '}' ,
121137 ] ) } ;`,
122138 ] )
123139 : '// no chunk loading' ,
140+ '' ,
141+ withHmr
142+ ? Template . asString ( [
143+ 'var oldTags = [];' ,
144+ 'var newTags = [];' ,
145+ `var applyHandler = ${ runtimeTemplate . basicFunction ( 'options' , [
146+ `return { dispose: ${ runtimeTemplate . basicFunction ( '' , [
147+ 'for(var i = 0; i < oldTags.length; i++) {' ,
148+ Template . indent ( [
149+ 'var oldTag = oldTags[i];' ,
150+ 'if(oldTag.parentNode) oldTag.parentNode.removeChild(oldTag);' ,
151+ ] ) ,
152+ '}' ,
153+ 'oldTags.length = 0;' ,
154+ ] ) } , apply: ${ runtimeTemplate . basicFunction ( '' , [
155+ 'for(var i = 0; i < newTags.length; i++) newTags[i].rel = "stylesheet";' ,
156+ 'newTags.length = 0;' ,
157+ ] ) } };`,
158+ ] ) } `,
159+ `${
160+ RuntimeGlobals . hmrDownloadUpdateHandlers
161+ } .miniCss = ${ runtimeTemplate . basicFunction (
162+ 'chunkIds, removedChunks, removedModules, promises, applyHandlers, updatedModulesList' ,
163+ [
164+ 'applyHandlers.push(applyHandler);' ,
165+ `chunkIds.forEach(${ runtimeTemplate . basicFunction ( 'chunkId' , [
166+ `var href = ${ RuntimeGlobals . require } .miniCssF(chunkId);` ,
167+ `var fullhref = ${ RuntimeGlobals . publicPath } + href;` ,
168+ 'const oldTag = findStylesheet(href, fullhref);' ,
169+ 'if(!oldTag) return;' ,
170+ `promises.push(new Promise(${ runtimeTemplate . basicFunction (
171+ 'resolve, reject' ,
172+ [
173+ `var tag = createStylesheet(fullhref, ${ runtimeTemplate . basicFunction (
174+ '' ,
175+ [
176+ 'tag.as = "style";' ,
177+ 'tag.rel = "preload";' ,
178+ 'resolve();' ,
179+ ]
180+ ) } , reject);`,
181+ 'oldTags.push(oldTag);' ,
182+ 'newTags.push(tag);' ,
183+ ]
184+ ) } ));`,
185+ ] ) } );`,
186+ ]
187+ ) } `,
188+ ] )
189+ : '// no hmr' ,
124190 ] ) ;
125191 }
126192} ;
0 commit comments