@@ -40,87 +40,153 @@ module.exports = class CssLoadingRuntimeModule extends RuntimeModule {
40
40
} = compilation ;
41
41
const chunkMap = getCssChunkObject ( chunk , compilation ) ;
42
42
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
47
48
) ;
48
49
50
+ if ( ! withLoading && ! withHmr ) return null ;
51
+
49
52
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
+ ) } `,
57
112
withLoading
58
113
? 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
+ '' ,
59
121
`${
60
122
RuntimeGlobals . ensureChunkHandlers
61
123
} .miniCss = ${ runtimeTemplate . basicFunction ( 'chunkId, promises' , [
62
124
`var cssChunks = ${ JSON . stringify ( chunkMap ) } ;` ,
63
125
'if(installedCssChunks[chunkId]) promises.push(installedCssChunks[chunkId]);' ,
64
126
'else if(installedCssChunks[chunkId] !== 0 && cssChunks[chunkId]) {' ,
65
127
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
+ ] ) } ));`,
119
135
] ) ,
120
136
'}' ,
121
137
] ) } ;`,
122
138
] )
123
139
: '// 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' ,
124
190
] ) ;
125
191
}
126
192
} ;
0 commit comments