source: frontend/node_modules/webpack/lib/esm/ModuleChunkLoadingRuntimeModule.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 11 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 14.6 KB
RevLine 
[9af201e]1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3*/
4
5"use strict";
6
7const { SyncWaterfallHook } = require("tapable");
8const Compilation = require("../Compilation");
9const RuntimeGlobals = require("../RuntimeGlobals");
10const RuntimeModule = require("../RuntimeModule");
11const Template = require("../Template");
12const {
13 generateJavascriptHMR
14} = require("../hmr/JavascriptHotModuleReplacementHelper");
15const {
16 chunkHasJs,
17 getChunkFilenameTemplate
18} = require("../javascript/JavascriptModulesPlugin");
19const { getInitialChunkIds } = require("../javascript/StartupHelpers");
20const compileBooleanMatcher = require("../util/compileBooleanMatcher");
21const { getUndoPath } = require("../util/identifier");
22
23/** @typedef {import("../Chunk")} Chunk */
24/** @typedef {import("../ChunkGraph")} ChunkGraph */
25/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
26
27/**
28 * Defines the jsonp compilation plugin hooks type used by this module.
29 * @typedef {object} JsonpCompilationPluginHooks
30 * @property {SyncWaterfallHook<[string, Chunk]>} linkPreload
31 * @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch
32 */
33
34/** @type {WeakMap<Compilation, JsonpCompilationPluginHooks>} */
35const compilationHooksMap = new WeakMap();
36
37class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
38 /**
39 * Returns hooks.
40 * @param {Compilation} compilation the compilation
41 * @returns {JsonpCompilationPluginHooks} hooks
42 */
43 static getCompilationHooks(compilation) {
44 if (!(compilation instanceof Compilation)) {
45 throw new TypeError(
46 "The 'compilation' argument must be an instance of Compilation"
47 );
48 }
49 let hooks = compilationHooksMap.get(compilation);
50 if (hooks === undefined) {
51 hooks = {
52 linkPreload: new SyncWaterfallHook(["source", "chunk"]),
53 linkPrefetch: new SyncWaterfallHook(["source", "chunk"])
54 };
55 compilationHooksMap.set(compilation, hooks);
56 }
57 return hooks;
58 }
59
60 /**
61 * Creates an instance of ModuleChunkLoadingRuntimeModule.
62 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
63 */
64 constructor(runtimeRequirements) {
65 super("import chunk loading", RuntimeModule.STAGE_ATTACH);
66 /** @type {ReadOnlyRuntimeRequirements} */
67 this._runtimeRequirements = runtimeRequirements;
68 }
69
70 /**
71 * Returns generated code.
72 * @private
73 * @param {Chunk} chunk chunk
74 * @param {string} rootOutputDir root output directory
75 * @returns {string} generated code
76 */
77 _generateBaseUri(chunk, rootOutputDir) {
78 const options = chunk.getEntryOptions();
79 if (options && options.baseUri) {
80 return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
81 }
82 const compilation = /** @type {Compilation} */ (this.compilation);
83 const {
84 outputOptions: { importMetaName }
85 } = compilation;
86 return `${RuntimeGlobals.baseURI} = new URL(${JSON.stringify(
87 rootOutputDir
88 )}, ${importMetaName}.url);`;
89 }
90
91 /**
92 * Generates runtime code for this runtime module.
93 * @returns {string | null} runtime code
94 */
95 generate() {
96 const compilation = /** @type {Compilation} */ (this.compilation);
97 const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
98 const chunk = /** @type {Chunk} */ (this.chunk);
99 const environment = compilation.outputOptions.environment;
100 const {
101 runtimeTemplate,
102 outputOptions: { importFunctionName, crossOriginLoading, charset }
103 } = compilation;
104 const fn = RuntimeGlobals.ensureChunkHandlers;
105 const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI);
106 const withExternalInstallChunk = this._runtimeRequirements.has(
107 RuntimeGlobals.externalInstallChunk
108 );
109 const withLoading = this._runtimeRequirements.has(
110 RuntimeGlobals.ensureChunkHandlers
111 );
112 const withOnChunkLoad = this._runtimeRequirements.has(
113 RuntimeGlobals.onChunksLoaded
114 );
115 const withHmr = this._runtimeRequirements.has(
116 RuntimeGlobals.hmrDownloadUpdateHandlers
117 );
118 const withHmrManifest = this._runtimeRequirements.has(
119 RuntimeGlobals.hmrDownloadManifest
120 );
121 const { linkPreload, linkPrefetch } =
122 ModuleChunkLoadingRuntimeModule.getCompilationHooks(compilation);
123 const isNeutralPlatform = runtimeTemplate.isNeutralPlatform();
124 const withPrefetch =
125 (environment.document || isNeutralPlatform) &&
126 this._runtimeRequirements.has(RuntimeGlobals.prefetchChunkHandlers) &&
127 chunk.hasChildByOrder(chunkGraph, "prefetch", true, chunkHasJs);
128 const withPreload =
129 (environment.document || isNeutralPlatform) &&
130 this._runtimeRequirements.has(RuntimeGlobals.preloadChunkHandlers) &&
131 chunk.hasChildByOrder(chunkGraph, "preload", true, chunkHasJs);
132 const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs);
133 const hasJsMatcher = compileBooleanMatcher(conditionMap);
134 const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs);
135
136 const outputName = compilation.getPath(
137 getChunkFilenameTemplate(chunk, compilation.outputOptions),
138 {
139 chunk,
140 contentHashType: "javascript"
141 }
142 );
143 const rootOutputDir = getUndoPath(
144 outputName,
145 compilation.outputOptions.path,
146 true
147 );
148
149 const stateExpression = withHmr
150 ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_module`
151 : undefined;
152
153 return Template.asString([
154 withBaseURI
155 ? this._generateBaseUri(chunk, rootOutputDir)
156 : "// no baseURI",
157 "",
158 "// object to store loaded and loading chunks",
159 "// undefined = chunk not loaded, null = chunk preloaded/prefetched",
160 "// [resolve, Promise] = chunk loading, 0 = chunk loaded",
161 `var installedChunks = ${
162 stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
163 }{`,
164 Template.indent(
165 Array.from(initialChunkIds, (id) => `${JSON.stringify(id)}: 0`).join(
166 ",\n"
167 )
168 ),
169 "};",
170 "",
171 withLoading || withExternalInstallChunk
172 ? `var installChunk = ${runtimeTemplate.basicFunction("data", [
173 runtimeTemplate.destructureObject(
174 [
175 RuntimeGlobals.esmIds,
176 RuntimeGlobals.esmModules,
177 RuntimeGlobals.esmRuntime
178 ],
179 "data"
180 ),
181 '// add "modules" to the modules object,',
182 '// then flag all "ids" as loaded and fire callback',
183 "var moduleId, chunkId, i = 0;",
184 `for(moduleId in ${RuntimeGlobals.esmModules}) {`,
185 Template.indent([
186 `if(${RuntimeGlobals.hasOwnProperty}(${RuntimeGlobals.esmModules}, moduleId)) {`,
187 Template.indent(
188 `${RuntimeGlobals.moduleFactories}[moduleId] = ${RuntimeGlobals.esmModules}[moduleId];`
189 ),
190 "}"
191 ]),
192 "}",
193 `if(${RuntimeGlobals.esmRuntime}) ${RuntimeGlobals.esmRuntime}(${RuntimeGlobals.require});`,
194 `for(;i < ${RuntimeGlobals.esmIds}.length; i++) {`,
195 Template.indent([
196 `chunkId = ${RuntimeGlobals.esmIds}[i];`,
197 `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`,
198 Template.indent("installedChunks[chunkId][0]();"),
199 "}",
200 `installedChunks[${RuntimeGlobals.esmIds}[i]] = 0;`
201 ]),
202 "}",
203 withOnChunkLoad ? `${RuntimeGlobals.onChunksLoaded}();` : ""
204 ])}`
205 : "// no install chunk",
206 "",
207 withLoading
208 ? Template.asString([
209 `${fn}.j = ${runtimeTemplate.basicFunction(
210 "chunkId, promises",
211 hasJsMatcher !== false
212 ? Template.indent([
213 "// import() chunk loading for javascript",
214 `var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`,
215 'if(installedChunkData !== 0) { // 0 means "already installed".',
216 Template.indent([
217 "",
218 '// a Promise means "currently loading".',
219 "if(installedChunkData) {",
220 Template.indent([
221 "promises.push(installedChunkData[1]);"
222 ]),
223 "} else {",
224 Template.indent([
225 hasJsMatcher === true
226 ? "if(true) { // all chunks have JS"
227 : `if(${hasJsMatcher("chunkId")}) {`,
228 Template.indent([
229 "// setup Promise in chunk cache",
230 `var promise = ${importFunctionName}(${
231 compilation.outputOptions.publicPath === "auto"
232 ? JSON.stringify(rootOutputDir)
233 : RuntimeGlobals.publicPath
234 } + ${
235 RuntimeGlobals.getChunkScriptFilename
236 }(chunkId)).then(installChunk, ${runtimeTemplate.basicFunction(
237 "e",
238 [
239 "if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined;",
240 "throw e;"
241 ]
242 )});`,
243 `var promise = Promise.race([promise, new Promise(${runtimeTemplate.expressionFunction(
244 "installedChunkData = installedChunks[chunkId] = [resolve]",
245 "resolve"
246 )})])`,
247 "promises.push(installedChunkData[1] = promise);"
248 ]),
249 hasJsMatcher === true
250 ? "}"
251 : "} else installedChunks[chunkId] = 0;"
252 ]),
253 "}"
254 ]),
255 "}"
256 ])
257 : Template.indent(["installedChunks[chunkId] = 0;"])
258 )};`
259 ])
260 : "// no chunk on demand loading",
261 "",
262 withPrefetch && hasJsMatcher !== false
263 ? `${
264 RuntimeGlobals.prefetchChunkHandlers
265 }.j = ${runtimeTemplate.basicFunction("chunkId", [
266 isNeutralPlatform
267 ? "if (typeof document === 'undefined') return;"
268 : "",
269 `if((!${
270 RuntimeGlobals.hasOwnProperty
271 }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${
272 hasJsMatcher === true ? "true" : hasJsMatcher("chunkId")
273 }) {`,
274 Template.indent([
275 "installedChunks[chunkId] = null;",
276 linkPrefetch.call(
277 Template.asString([
278 "var link = document.createElement('link');",
279 charset ? "link.charset = 'utf-8';" : "",
280 crossOriginLoading
281 ? `link.crossOrigin = ${JSON.stringify(
282 crossOriginLoading
283 )};`
284 : "",
285 `if (${RuntimeGlobals.scriptNonce}) {`,
286 Template.indent(
287 `link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
288 ),
289 "}",
290 'link.rel = "prefetch";',
291 'link.as = "script";',
292 `link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`
293 ]),
294 chunk
295 ),
296 "document.head.appendChild(link);"
297 ]),
298 "}"
299 ])};`
300 : "// no prefetching",
301 "",
302 withPreload && hasJsMatcher !== false
303 ? `${
304 RuntimeGlobals.preloadChunkHandlers
305 }.j = ${runtimeTemplate.basicFunction("chunkId", [
306 isNeutralPlatform
307 ? "if (typeof document === 'undefined') return;"
308 : "",
309 `if((!${
310 RuntimeGlobals.hasOwnProperty
311 }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${
312 hasJsMatcher === true ? "true" : hasJsMatcher("chunkId")
313 }) {`,
314 Template.indent([
315 "installedChunks[chunkId] = null;",
316 linkPreload.call(
317 Template.asString([
318 "var link = document.createElement('link');",
319 charset ? "link.charset = 'utf-8';" : "",
320 `if (${RuntimeGlobals.scriptNonce}) {`,
321 Template.indent(
322 `link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
323 ),
324 "}",
325 'link.rel = "modulepreload";',
326 `link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`,
327 crossOriginLoading
328 ? crossOriginLoading === "use-credentials"
329 ? 'link.crossOrigin = "use-credentials";'
330 : Template.asString([
331 "if (link.href.indexOf(window.location.origin + '/') !== 0) {",
332 Template.indent(
333 `link.crossOrigin = ${JSON.stringify(
334 crossOriginLoading
335 )};`
336 ),
337 "}"
338 ])
339 : ""
340 ]),
341 chunk
342 ),
343 "document.head.appendChild(link);"
344 ]),
345 "}"
346 ])};`
347 : "// no preloaded",
348 "",
349 withExternalInstallChunk
350 ? Template.asString([
351 `${RuntimeGlobals.externalInstallChunk} = installChunk;`
352 ])
353 : "// no external install chunk",
354 "",
355 withOnChunkLoad
356 ? `${
357 RuntimeGlobals.onChunksLoaded
358 }.j = ${runtimeTemplate.returningFunction(
359 "installedChunks[chunkId] === 0",
360 "chunkId"
361 )};`
362 : "// no on chunks loaded",
363 withHmr
364 ? Template.asString([
365 generateJavascriptHMR("module"),
366 "",
367 "function loadUpdateChunk(chunkId, updatedModulesList) {",
368 Template.indent([
369 `return new Promise(${runtimeTemplate.basicFunction(
370 "resolve, reject",
371 [
372 "// start update chunk loading",
373 `var url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId);`,
374 `var onResolve = ${runtimeTemplate.basicFunction("obj", [
375 `var updatedModules = obj.${RuntimeGlobals.esmModules};`,
376 `var updatedRuntime = obj.${RuntimeGlobals.esmRuntime};`,
377 "if(updatedRuntime) currentUpdateRuntime.push(updatedRuntime);",
378 "for(var moduleId in updatedModules) {",
379 Template.indent([
380 `if(${RuntimeGlobals.hasOwnProperty}(updatedModules, moduleId)) {`,
381 Template.indent([
382 "currentUpdate[moduleId] = updatedModules[moduleId];",
383 "if(updatedModulesList) updatedModulesList.push(moduleId);"
384 ]),
385 "}"
386 ]),
387 "}",
388 "resolve(obj);"
389 ])};`,
390 `var onReject = ${runtimeTemplate.basicFunction("error", [
391 "var errorMsg = error.message || 'unknown reason';",
392 "error.message = 'Loading hot update chunk ' + chunkId + ' failed.\\n(' + errorMsg + ')';",
393 "error.name = 'ChunkLoadError';",
394 "reject(error);"
395 ])}`,
396 `var loadScript = ${runtimeTemplate.basicFunction(
397 "url, onResolve, onReject",
398 [
399 `return ${importFunctionName}(/* webpackIgnore: true */ url).then(onResolve).catch(onReject)`
400 ]
401 )}`,
402 "loadScript(url, onResolve, onReject);"
403 ]
404 )});`
405 ]),
406 "}",
407 ""
408 ])
409 : "// no HMR",
410 "",
411 withHmrManifest
412 ? Template.asString([
413 `${
414 RuntimeGlobals.hmrDownloadManifest
415 } = ${runtimeTemplate.basicFunction("", [
416 `return ${importFunctionName}(/* webpackIgnore: true */ ${RuntimeGlobals.publicPath} + ${
417 RuntimeGlobals.getUpdateManifestFilename
418 }()).then(${runtimeTemplate.basicFunction("obj", [
419 "return obj.default;"
420 ])}, ${runtimeTemplate.basicFunction("error", [
421 "if(['MODULE_NOT_FOUND', 'ENOENT'].includes(error.code)) return;",
422 "throw error;"
423 ])});`
424 ])};`
425 ])
426 : "// no HMR manifest"
427 ]);
428 }
429}
430
431module.exports = ModuleChunkLoadingRuntimeModule;
Note: See TracBrowser for help on using the repository browser.