source: trip-planner-front/node_modules/webpack/lib/web/JsonpChunkLoadingRuntimeModule.js@ 8d391a1

Last change on this file since 8d391a1 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

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