source: frontend/node_modules/webpack/lib/sharing/ConsumeSharedRuntimeModule.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: 12.9 KB
Line 
1/*
2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
4*/
5
6"use strict";
7
8const RuntimeGlobals = require("../RuntimeGlobals");
9const RuntimeModule = require("../RuntimeModule");
10const Template = require("../Template");
11const { compareModulesById } = require("../util/comparators");
12const {
13 parseVersionRuntimeCode,
14 rangeToStringRuntimeCode,
15 satisfyRuntimeCode,
16 versionLtRuntimeCode
17} = require("../util/semver");
18
19/** @typedef {import("webpack-sources").Source} Source */
20/** @typedef {import("../Chunk")} Chunk */
21/** @typedef {import("../Chunk").ChunkId} ChunkId */
22/** @typedef {import("../ChunkGraph")} ChunkGraph */
23/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
24/** @typedef {import("../Compilation")} Compilation */
25/** @typedef {import("../Module")} Module */
26/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
27/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
28
29class ConsumeSharedRuntimeModule extends RuntimeModule {
30 /**
31 * @param {ReadOnlyRuntimeRequirements} runtimeRequirements runtime requirements
32 */
33 constructor(runtimeRequirements) {
34 super("consumes", RuntimeModule.STAGE_ATTACH);
35 this._runtimeRequirements = runtimeRequirements;
36 }
37
38 /**
39 * Generates runtime code for this runtime module.
40 * @returns {string | null} runtime code
41 */
42 generate() {
43 const compilation = /** @type {Compilation} */ (this.compilation);
44 const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
45 const codeGenerationResults =
46 /** @type {CodeGenerationResults} */
47 (compilation.codeGenerationResults);
48 const { runtimeTemplate } = compilation;
49 /** @type {Record<ChunkId, ModuleId[]>} */
50 const chunkToModuleMapping = {};
51 /** @type {Map<ModuleId, Source>} */
52 const moduleIdToSourceMapping = new Map();
53 /** @type {ModuleId[]} */
54 const initialConsumes = [];
55 /**
56 * @param {Iterable<Module>} modules modules
57 * @param {Chunk} chunk the chunk
58 * @param {ModuleId[]} list list of ids
59 */
60 const addModules = (modules, chunk, list) => {
61 for (const m of modules) {
62 const module = m;
63 const id = /** @type {ModuleId} */ (chunkGraph.getModuleId(module));
64 list.push(id);
65 moduleIdToSourceMapping.set(
66 id,
67 codeGenerationResults.getSource(
68 module,
69 chunk.runtime,
70 "consume-shared"
71 )
72 );
73 }
74 };
75 const byId = compareModulesById(chunkGraph);
76 for (const chunk of /** @type {Chunk} */ (
77 this.chunk
78 ).getAllReferencedChunks()) {
79 const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
80 chunk,
81 "consume-shared",
82 byId
83 );
84 if (!modules) continue;
85 addModules(
86 modules,
87 chunk,
88 (chunkToModuleMapping[/** @type {ChunkId} */ (chunk.id)] = [])
89 );
90 }
91 for (const chunk of /** @type {Chunk} */ (
92 this.chunk
93 ).getAllInitialChunks()) {
94 const modules = chunkGraph.getOrderedChunkModulesIterableBySourceType(
95 chunk,
96 "consume-shared",
97 byId
98 );
99 if (!modules) continue;
100 addModules(modules, chunk, initialConsumes);
101 }
102 if (moduleIdToSourceMapping.size === 0) return null;
103 return Template.asString([
104 parseVersionRuntimeCode(runtimeTemplate),
105 versionLtRuntimeCode(runtimeTemplate),
106 rangeToStringRuntimeCode(runtimeTemplate),
107 satisfyRuntimeCode(runtimeTemplate),
108 `var exists = ${runtimeTemplate.basicFunction("scope, key", [
109 `return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key);`
110 ])}`,
111 `var get = ${runtimeTemplate.basicFunction("entry", [
112 "entry.loaded = 1;",
113 "return entry.get()"
114 ])};`,
115 `var eagerOnly = ${runtimeTemplate.basicFunction("versions", [
116 `return Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
117 "filtered, version",
118 Template.indent([
119 "if (versions[version].eager) {",
120 Template.indent(["filtered[version] = versions[version];"]),
121 "}",
122 "return filtered;"
123 ])
124 )}, {});`
125 ])};`,
126 `var findLatestVersion = ${runtimeTemplate.basicFunction(
127 "scope, key, eager",
128 [
129 "var versions = eager ? eagerOnly(scope[key]) : scope[key];",
130 `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
131 "a, b",
132 ["return !a || versionLt(a, b) ? b : a;"]
133 )}, 0);`,
134 "return key && versions[key];"
135 ]
136 )};`,
137 `var findSatisfyingVersion = ${runtimeTemplate.basicFunction(
138 "scope, key, requiredVersion, eager",
139 [
140 "var versions = eager ? eagerOnly(scope[key]) : scope[key];",
141 `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
142 "a, b",
143 [
144 "if (!satisfy(requiredVersion, b)) return a;",
145 "return !a || versionLt(a, b) ? b : a;"
146 ]
147 )}, 0);`,
148 "return key && versions[key]"
149 ]
150 )};`,
151 `var findSingletonVersionKey = ${runtimeTemplate.basicFunction(
152 "scope, key, eager",
153 [
154 "var versions = eager ? eagerOnly(scope[key]) : scope[key];",
155 `return Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
156 "a, b",
157 ["return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;"]
158 )}, 0);`
159 ]
160 )};`,
161 `var getInvalidSingletonVersionMessage = ${runtimeTemplate.basicFunction(
162 "scope, key, version, requiredVersion",
163 [
164 'return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"'
165 ]
166 )};`,
167 `var getInvalidVersionMessage = ${runtimeTemplate.basicFunction(
168 "scope, scopeName, key, requiredVersion, eager",
169 [
170 "var versions = scope[key];",
171 'return "No satisfying version (" + rangeToString(requiredVersion) + ")" + (eager ? " for eager consumption" : "") + " of shared module " + key + " found in shared scope " + scopeName + ".\\n" +',
172 `\t"Available versions: " + Object.keys(versions).map(${runtimeTemplate.basicFunction(
173 "key",
174 ['return key + " from " + versions[key].from;']
175 )}).join(", ");`
176 ]
177 )};`,
178 `var fail = ${runtimeTemplate.basicFunction("msg", [
179 "throw new Error(msg);"
180 ])}`,
181 `var failAsNotExist = ${runtimeTemplate.basicFunction("scopeName, key", [
182 'return fail("Shared module " + key + " doesn\'t exist in shared scope " + scopeName);'
183 ])}`,
184 `var warn = /*#__PURE__*/ ${
185 compilation.outputOptions.ignoreBrowserWarnings
186 ? runtimeTemplate.basicFunction("", "")
187 : runtimeTemplate.basicFunction("msg", [
188 'if (typeof console !== "undefined" && console.warn) console.warn(msg);'
189 ])
190 };`,
191 `var init = ${runtimeTemplate.returningFunction(
192 Template.asString([
193 "function(scopeName, key, eager, c, d) {",
194 Template.indent([
195 `var promise = ${RuntimeGlobals.initializeSharing}(scopeName);`,
196 // if we require eager shared, we expect it to be already loaded before it requested, no need to wait the whole scope loaded.
197 "if (promise && promise.then && !eager) { ",
198 Template.indent([
199 `return promise.then(fn.bind(fn, scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, false, c, d));`
200 ]),
201 "}",
202 `return fn(scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, eager, c, d);`
203 ]),
204 "}"
205 ]),
206 "fn"
207 )};`,
208 "",
209 `var useFallback = ${runtimeTemplate.basicFunction(
210 "scopeName, key, fallback",
211 ["return fallback ? fallback() : failAsNotExist(scopeName, key);"]
212 )}`,
213 `var load = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
214 "scopeName, scope, key, eager, fallback",
215 [
216 "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
217 "return get(findLatestVersion(scope, key, eager));"
218 ]
219 )});`,
220 `var loadVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
221 "scopeName, scope, key, eager, requiredVersion, fallback",
222 [
223 "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
224 "var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);",
225 "if (satisfyingVersion) return get(satisfyingVersion);",
226 "warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager))",
227 "return get(findLatestVersion(scope, key, eager));"
228 ]
229 )});`,
230 `var loadStrictVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
231 "scopeName, scope, key, eager, requiredVersion, fallback",
232 [
233 "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
234 "var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);",
235 "if (satisfyingVersion) return get(satisfyingVersion);",
236 "if (fallback) return fallback();",
237 "fail(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager));"
238 ]
239 )});`,
240 `var loadSingleton = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
241 "scopeName, scope, key, eager, fallback",
242 [
243 "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
244 "var version = findSingletonVersionKey(scope, key, eager);",
245 "return get(scope[key][version]);"
246 ]
247 )});`,
248 `var loadSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
249 "scopeName, scope, key, eager, requiredVersion, fallback",
250 [
251 "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
252 "var version = findSingletonVersionKey(scope, key, eager);",
253 "if (!satisfy(requiredVersion, version)) {",
254 Template.indent([
255 "warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));"
256 ]),
257 "}",
258 "return get(scope[key][version]);"
259 ]
260 )});`,
261 `var loadStrictSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
262 "scopeName, scope, key, eager, requiredVersion, fallback",
263 [
264 "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);",
265 "var version = findSingletonVersionKey(scope, key, eager);",
266 "if (!satisfy(requiredVersion, version)) {",
267 Template.indent([
268 "fail(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));"
269 ]),
270 "}",
271 "return get(scope[key][version]);"
272 ]
273 )});`,
274 "var installedModules = {};",
275 "var moduleToHandlerMapping = {",
276 Template.indent(
277 Array.from(
278 moduleIdToSourceMapping,
279 ([key, source]) => `${JSON.stringify(key)}: ${source.source()}`
280 ).join(",\n")
281 ),
282 "};",
283
284 initialConsumes.length > 0
285 ? Template.asString([
286 `var initialConsumes = ${JSON.stringify(initialConsumes)};`,
287 `initialConsumes.forEach(${runtimeTemplate.basicFunction("id", [
288 `${
289 RuntimeGlobals.moduleFactories
290 }[id] = ${runtimeTemplate.basicFunction("module", [
291 "// Handle case when module is used sync",
292 "installedModules[id] = 0;",
293 `delete ${RuntimeGlobals.moduleCache}[id];`,
294 "var factory = moduleToHandlerMapping[id]();",
295 'if(typeof factory !== "function") throw new Error("Shared module is not available for eager consumption: " + id);',
296 "module.exports = factory();"
297 ])}`
298 ])});`
299 ])
300 : "// no consumes in initial chunks",
301 this._runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)
302 ? Template.asString([
303 `var chunkMapping = ${JSON.stringify(
304 chunkToModuleMapping,
305 null,
306 "\t"
307 )};`,
308 "var startedInstallModules = {};",
309 `${
310 RuntimeGlobals.ensureChunkHandlers
311 }.consumes = ${runtimeTemplate.basicFunction("chunkId, promises", [
312 `if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`,
313 Template.indent([
314 `chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction(
315 "id",
316 [
317 `if(${RuntimeGlobals.hasOwnProperty}(installedModules, id)) return promises.push(installedModules[id]);`,
318 "if(!startedInstallModules[id]) {",
319 `var onFactory = ${runtimeTemplate.basicFunction(
320 "factory",
321 [
322 "installedModules[id] = 0;",
323 `${
324 RuntimeGlobals.moduleFactories
325 }[id] = ${runtimeTemplate.basicFunction("module", [
326 `delete ${RuntimeGlobals.moduleCache}[id];`,
327 "module.exports = factory();"
328 ])}`
329 ]
330 )};`,
331 "startedInstallModules[id] = true;",
332 `var onError = ${runtimeTemplate.basicFunction("error", [
333 "delete installedModules[id];",
334 `${
335 RuntimeGlobals.moduleFactories
336 }[id] = ${runtimeTemplate.basicFunction("module", [
337 `delete ${RuntimeGlobals.moduleCache}[id];`,
338 "throw error;"
339 ])}`
340 ])};`,
341 "try {",
342 Template.indent([
343 "var promise = moduleToHandlerMapping[id]();",
344 "if(promise.then) {",
345 Template.indent(
346 "promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));"
347 ),
348 "} else onFactory(promise);"
349 ]),
350 "} catch(e) { onError(e); }",
351 "}"
352 ]
353 )});`
354 ]),
355 "}"
356 ])}`
357 ])
358 : "// no chunk loading of consumes"
359 ]);
360 }
361}
362
363module.exports = ConsumeSharedRuntimeModule;
Note: See TracBrowser for help on using the repository browser.