source: imaps-frontend/node_modules/webpack/lib/web/JsonpChunkLoadingRuntimeModule.js@ 79a0317

main
Last change on this file since 79a0317 was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 3 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 16.6 KB
RevLine 
[79a0317]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 chunkHasJs = require("../javascript/JavascriptModulesPlugin").chunkHasJs;
13const { getInitialChunkIds } = require("../javascript/StartupHelpers");
14const compileBooleanMatcher = require("../util/compileBooleanMatcher");
15
16/** @typedef {import("../Chunk")} Chunk */
17/** @typedef {import("../ChunkGraph")} ChunkGraph */
18/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
19
20/**
21 * @typedef {object} JsonpCompilationPluginHooks
22 * @property {SyncWaterfallHook<[string, Chunk]>} linkPreload
23 * @property {SyncWaterfallHook<[string, Chunk]>} linkPrefetch
24 */
25
26/** @type {WeakMap<Compilation, JsonpCompilationPluginHooks>} */
27const compilationHooksMap = new WeakMap();
28
29class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
30 /**
31 * @param {Compilation} compilation the compilation
32 * @returns {JsonpCompilationPluginHooks} hooks
33 */
34 static getCompilationHooks(compilation) {
35 if (!(compilation instanceof Compilation)) {
36 throw new TypeError(
37 "The 'compilation' argument must be an instance of Compilation"
38 );
39 }
40 let hooks = compilationHooksMap.get(compilation);
41 if (hooks === undefined) {
42 hooks = {
43 linkPreload: new SyncWaterfallHook(["source", "chunk"]),
44 linkPrefetch: new SyncWaterfallHook(["source", "chunk"])
45 };
46 compilationHooksMap.set(compilation, hooks);
47 }
48 return hooks;
49 }
50
51 /**
52 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
53 */
54 constructor(runtimeRequirements) {
55 super("jsonp chunk loading", RuntimeModule.STAGE_ATTACH);
56 this._runtimeRequirements = runtimeRequirements;
57 }
58
59 /**
60 * @private
61 * @param {Chunk} chunk chunk
62 * @returns {string} generated code
63 */
64 _generateBaseUri(chunk) {
65 const options = chunk.getEntryOptions();
66 if (options && options.baseUri) {
67 return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
68 }
69 return `${RuntimeGlobals.baseURI} = document.baseURI || self.location.href;`;
70 }
71
72 /**
73 * @returns {string | null} runtime code
74 */
75 generate() {
76 const compilation = /** @type {Compilation} */ (this.compilation);
77 const {
78 runtimeTemplate,
79 outputOptions: {
80 chunkLoadingGlobal,
81 hotUpdateGlobal,
82 crossOriginLoading,
83 scriptType
84 }
85 } = compilation;
86 const globalObject = runtimeTemplate.globalObject;
87 const { linkPreload, linkPrefetch } =
88 JsonpChunkLoadingRuntimeModule.getCompilationHooks(compilation);
89 const fn = RuntimeGlobals.ensureChunkHandlers;
90 const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI);
91 const withLoading = this._runtimeRequirements.has(
92 RuntimeGlobals.ensureChunkHandlers
93 );
94 const withCallback = this._runtimeRequirements.has(
95 RuntimeGlobals.chunkCallback
96 );
97 const withOnChunkLoad = this._runtimeRequirements.has(
98 RuntimeGlobals.onChunksLoaded
99 );
100 const withHmr = this._runtimeRequirements.has(
101 RuntimeGlobals.hmrDownloadUpdateHandlers
102 );
103 const withHmrManifest = this._runtimeRequirements.has(
104 RuntimeGlobals.hmrDownloadManifest
105 );
106 const withFetchPriority = this._runtimeRequirements.has(
107 RuntimeGlobals.hasFetchPriority
108 );
109 const chunkLoadingGlobalExpr = `${globalObject}[${JSON.stringify(
110 chunkLoadingGlobal
111 )}]`;
112 const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
113 const chunk = /** @type {Chunk} */ (this.chunk);
114 const withPrefetch =
115 this._runtimeRequirements.has(RuntimeGlobals.prefetchChunkHandlers) &&
116 chunk.hasChildByOrder(chunkGraph, "prefetch", true, chunkHasJs);
117 const withPreload =
118 this._runtimeRequirements.has(RuntimeGlobals.preloadChunkHandlers) &&
119 chunk.hasChildByOrder(chunkGraph, "preload", true, chunkHasJs);
120 const conditionMap = chunkGraph.getChunkConditionMap(chunk, chunkHasJs);
121 const hasJsMatcher = compileBooleanMatcher(conditionMap);
122 const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs);
123
124 const stateExpression = withHmr
125 ? `${RuntimeGlobals.hmrRuntimeStatePrefix}_jsonp`
126 : undefined;
127
128 return Template.asString([
129 withBaseURI ? this._generateBaseUri(chunk) : "// no baseURI",
130 "",
131 "// object to store loaded and loading chunks",
132 "// undefined = chunk not loaded, null = chunk preloaded/prefetched",
133 "// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded",
134 `var installedChunks = ${
135 stateExpression ? `${stateExpression} = ${stateExpression} || ` : ""
136 }{`,
137 Template.indent(
138 Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 0`).join(
139 ",\n"
140 )
141 ),
142 "};",
143 "",
144 withLoading
145 ? Template.asString([
146 `${fn}.j = ${runtimeTemplate.basicFunction(
147 `chunkId, promises${withFetchPriority ? ", fetchPriority" : ""}`,
148 hasJsMatcher !== false
149 ? Template.indent([
150 "// JSONP chunk loading for javascript",
151 `var installedChunkData = ${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;`,
152 'if(installedChunkData !== 0) { // 0 means "already installed".',
153 Template.indent([
154 "",
155 '// a Promise means "currently loading".',
156 "if(installedChunkData) {",
157 Template.indent([
158 "promises.push(installedChunkData[2]);"
159 ]),
160 "} else {",
161 Template.indent([
162 hasJsMatcher === true
163 ? "if(true) { // all chunks have JS"
164 : `if(${hasJsMatcher("chunkId")}) {`,
165 Template.indent([
166 "// setup Promise in chunk cache",
167 `var promise = new Promise(${runtimeTemplate.expressionFunction(
168 "installedChunkData = installedChunks[chunkId] = [resolve, reject]",
169 "resolve, reject"
170 )});`,
171 "promises.push(installedChunkData[2] = promise);",
172 "",
173 "// start chunk loading",
174 `var url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`,
175 "// create error before stack unwound to get useful stacktrace later",
176 "var error = new Error();",
177 `var loadingEnded = ${runtimeTemplate.basicFunction(
178 "event",
179 [
180 `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId)) {`,
181 Template.indent([
182 "installedChunkData = installedChunks[chunkId];",
183 "if(installedChunkData !== 0) installedChunks[chunkId] = undefined;",
184 "if(installedChunkData) {",
185 Template.indent([
186 "var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
187 "var realSrc = event && event.target && event.target.src;",
188 "error.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
189 "error.name = 'ChunkLoadError';",
190 "error.type = errorType;",
191 "error.request = realSrc;",
192 "installedChunkData[1](error);"
193 ]),
194 "}"
195 ]),
196 "}"
197 ]
198 )};`,
199 `${
200 RuntimeGlobals.loadScript
201 }(url, loadingEnded, "chunk-" + chunkId, chunkId${
202 withFetchPriority ? ", fetchPriority" : ""
203 });`
204 ]),
205 hasJsMatcher === true
206 ? "}"
207 : "} else installedChunks[chunkId] = 0;"
208 ]),
209 "}"
210 ]),
211 "}"
212 ])
213 : Template.indent(["installedChunks[chunkId] = 0;"])
214 )};`
215 ])
216 : "// no chunk on demand loading",
217 "",
218 withPrefetch && hasJsMatcher !== false
219 ? `${
220 RuntimeGlobals.prefetchChunkHandlers
221 }.j = ${runtimeTemplate.basicFunction("chunkId", [
222 `if((!${
223 RuntimeGlobals.hasOwnProperty
224 }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${
225 hasJsMatcher === true ? "true" : hasJsMatcher("chunkId")
226 }) {`,
227 Template.indent([
228 "installedChunks[chunkId] = null;",
229 linkPrefetch.call(
230 Template.asString([
231 "var link = document.createElement('link');",
232 crossOriginLoading
233 ? `link.crossOrigin = ${JSON.stringify(
234 crossOriginLoading
235 )};`
236 : "",
237 `if (${RuntimeGlobals.scriptNonce}) {`,
238 Template.indent(
239 `link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
240 ),
241 "}",
242 'link.rel = "prefetch";',
243 'link.as = "script";',
244 `link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`
245 ]),
246 chunk
247 ),
248 "document.head.appendChild(link);"
249 ]),
250 "}"
251 ])};`
252 : "// no prefetching",
253 "",
254 withPreload && hasJsMatcher !== false
255 ? `${
256 RuntimeGlobals.preloadChunkHandlers
257 }.j = ${runtimeTemplate.basicFunction("chunkId", [
258 `if((!${
259 RuntimeGlobals.hasOwnProperty
260 }(installedChunks, chunkId) || installedChunks[chunkId] === undefined) && ${
261 hasJsMatcher === true ? "true" : hasJsMatcher("chunkId")
262 }) {`,
263 Template.indent([
264 "installedChunks[chunkId] = null;",
265 linkPreload.call(
266 Template.asString([
267 "var link = document.createElement('link');",
268 scriptType && scriptType !== "module"
269 ? `link.type = ${JSON.stringify(scriptType)};`
270 : "",
271 "link.charset = 'utf-8';",
272 `if (${RuntimeGlobals.scriptNonce}) {`,
273 Template.indent(
274 `link.setAttribute("nonce", ${RuntimeGlobals.scriptNonce});`
275 ),
276 "}",
277 scriptType === "module"
278 ? 'link.rel = "modulepreload";'
279 : 'link.rel = "preload";',
280 scriptType === "module" ? "" : 'link.as = "script";',
281 `link.href = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId);`,
282 crossOriginLoading
283 ? crossOriginLoading === "use-credentials"
284 ? 'link.crossOrigin = "use-credentials";'
285 : Template.asString([
286 "if (link.href.indexOf(window.location.origin + '/') !== 0) {",
287 Template.indent(
288 `link.crossOrigin = ${JSON.stringify(
289 crossOriginLoading
290 )};`
291 ),
292 "}"
293 ])
294 : ""
295 ]),
296 chunk
297 ),
298 "document.head.appendChild(link);"
299 ]),
300 "}"
301 ])};`
302 : "// no preloaded",
303 "",
304 withHmr
305 ? Template.asString([
306 "var currentUpdatedModulesList;",
307 "var waitingUpdateResolves = {};",
308 "function loadUpdateChunk(chunkId, updatedModulesList) {",
309 Template.indent([
310 "currentUpdatedModulesList = updatedModulesList;",
311 `return new Promise(${runtimeTemplate.basicFunction(
312 "resolve, reject",
313 [
314 "waitingUpdateResolves[chunkId] = resolve;",
315 "// start update chunk loading",
316 `var url = ${RuntimeGlobals.publicPath} + ${RuntimeGlobals.getChunkUpdateScriptFilename}(chunkId);`,
317 "// create error before stack unwound to get useful stacktrace later",
318 "var error = new Error();",
319 `var loadingEnded = ${runtimeTemplate.basicFunction("event", [
320 "if(waitingUpdateResolves[chunkId]) {",
321 Template.indent([
322 "waitingUpdateResolves[chunkId] = undefined",
323 "var errorType = event && (event.type === 'load' ? 'missing' : event.type);",
324 "var realSrc = event && event.target && event.target.src;",
325 "error.message = 'Loading hot update chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';",
326 "error.name = 'ChunkLoadError';",
327 "error.type = errorType;",
328 "error.request = realSrc;",
329 "reject(error);"
330 ]),
331 "}"
332 ])};`,
333 `${RuntimeGlobals.loadScript}(url, loadingEnded);`
334 ]
335 )});`
336 ]),
337 "}",
338 "",
339 `${globalObject}[${JSON.stringify(
340 hotUpdateGlobal
341 )}] = ${runtimeTemplate.basicFunction(
342 "chunkId, moreModules, runtime",
343 [
344 "for(var moduleId in moreModules) {",
345 Template.indent([
346 `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
347 Template.indent([
348 "currentUpdate[moduleId] = moreModules[moduleId];",
349 "if(currentUpdatedModulesList) currentUpdatedModulesList.push(moduleId);"
350 ]),
351 "}"
352 ]),
353 "}",
354 "if(runtime) currentUpdateRuntime.push(runtime);",
355 "if(waitingUpdateResolves[chunkId]) {",
356 Template.indent([
357 "waitingUpdateResolves[chunkId]();",
358 "waitingUpdateResolves[chunkId] = undefined;"
359 ]),
360 "}"
361 ]
362 )};`,
363 "",
364 Template.getFunctionContent(
365 require("../hmr/JavascriptHotModuleReplacement.runtime.js")
366 )
367 .replace(/\$key\$/g, "jsonp")
368 .replace(/\$installedChunks\$/g, "installedChunks")
369 .replace(/\$loadUpdateChunk\$/g, "loadUpdateChunk")
370 .replace(/\$moduleCache\$/g, RuntimeGlobals.moduleCache)
371 .replace(/\$moduleFactories\$/g, RuntimeGlobals.moduleFactories)
372 .replace(
373 /\$ensureChunkHandlers\$/g,
374 RuntimeGlobals.ensureChunkHandlers
375 )
376 .replace(/\$hasOwnProperty\$/g, RuntimeGlobals.hasOwnProperty)
377 .replace(/\$hmrModuleData\$/g, RuntimeGlobals.hmrModuleData)
378 .replace(
379 /\$hmrDownloadUpdateHandlers\$/g,
380 RuntimeGlobals.hmrDownloadUpdateHandlers
381 )
382 .replace(
383 /\$hmrInvalidateModuleHandlers\$/g,
384 RuntimeGlobals.hmrInvalidateModuleHandlers
385 )
386 ])
387 : "// no HMR",
388 "",
389 withHmrManifest
390 ? Template.asString([
391 `${
392 RuntimeGlobals.hmrDownloadManifest
393 } = ${runtimeTemplate.basicFunction("", [
394 'if (typeof fetch === "undefined") throw new Error("No browser support: need fetch API");',
395 `return fetch(${RuntimeGlobals.publicPath} + ${
396 RuntimeGlobals.getUpdateManifestFilename
397 }()).then(${runtimeTemplate.basicFunction("response", [
398 "if(response.status === 404) return; // no update available",
399 'if(!response.ok) throw new Error("Failed to fetch update manifest " + response.statusText);',
400 "return response.json();"
401 ])});`
402 ])};`
403 ])
404 : "// no HMR manifest",
405 "",
406 withOnChunkLoad
407 ? `${
408 RuntimeGlobals.onChunksLoaded
409 }.j = ${runtimeTemplate.returningFunction(
410 "installedChunks[chunkId] === 0",
411 "chunkId"
412 )};`
413 : "// no on chunks loaded",
414 "",
415 withCallback || withLoading
416 ? Template.asString([
417 "// install a JSONP callback for chunk loading",
418 `var webpackJsonpCallback = ${runtimeTemplate.basicFunction(
419 "parentChunkLoadingFunction, data",
420 [
421 runtimeTemplate.destructureArray(
422 ["chunkIds", "moreModules", "runtime"],
423 "data"
424 ),
425 '// add "moreModules" to the modules object,',
426 '// then flag all "chunkIds" as loaded and fire callback',
427 "var moduleId, chunkId, i = 0;",
428 `if(chunkIds.some(${runtimeTemplate.returningFunction(
429 "installedChunks[id] !== 0",
430 "id"
431 )})) {`,
432 Template.indent([
433 "for(moduleId in moreModules) {",
434 Template.indent([
435 `if(${RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
436 Template.indent(
437 `${RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`
438 ),
439 "}"
440 ]),
441 "}",
442 `if(runtime) var result = runtime(${RuntimeGlobals.require});`
443 ]),
444 "}",
445 "if(parentChunkLoadingFunction) parentChunkLoadingFunction(data);",
446 "for(;i < chunkIds.length; i++) {",
447 Template.indent([
448 "chunkId = chunkIds[i];",
449 `if(${RuntimeGlobals.hasOwnProperty}(installedChunks, chunkId) && installedChunks[chunkId]) {`,
450 Template.indent("installedChunks[chunkId][0]();"),
451 "}",
452 "installedChunks[chunkId] = 0;"
453 ]),
454 "}",
455 withOnChunkLoad
456 ? `return ${RuntimeGlobals.onChunksLoaded}(result);`
457 : ""
458 ]
459 )}`,
460 "",
461 `var chunkLoadingGlobal = ${chunkLoadingGlobalExpr} = ${chunkLoadingGlobalExpr} || [];`,
462 "chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));",
463 "chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));"
464 ])
465 : "// no jsonp function"
466 ]);
467 }
468}
469
470module.exports = JsonpChunkLoadingRuntimeModule;
Note: See TracBrowser for help on using the repository browser.