123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
- "use strict";
- const RuntimeGlobals = require("../RuntimeGlobals");
- const RuntimeModule = require("../RuntimeModule");
- const Template = require("../Template");
- const {
- parseVersionRuntimeCode,
- versionLtRuntimeCode,
- rangeToStringRuntimeCode,
- satisfyRuntimeCode
- } = require("../util/semver");
- /** @typedef {import("webpack-sources").Source} Source */
- /** @typedef {import("../Chunk")} Chunk */
- /** @typedef {import("../Module")} Module */
- /** @typedef {import("./ConsumeSharedModule")} ConsumeSharedModule */
- class ConsumeSharedRuntimeModule extends RuntimeModule {
- constructor(runtimeRequirements) {
- super("consumes", RuntimeModule.STAGE_ATTACH);
- this._runtimeRequirements = runtimeRequirements;
- }
- /**
- * @returns {string} runtime code
- */
- generate() {
- const { compilation, chunkGraph } = this;
- const { runtimeTemplate, codeGenerationResults } = compilation;
- const chunkToModuleMapping = {};
- /** @type {Map<string | number, Source>} */
- const moduleIdToSourceMapping = new Map();
- const initialConsumes = [];
- /**
- *
- * @param {Iterable<Module>} modules modules
- * @param {Chunk} chunk the chunk
- * @param {(string | number)[]} list list of ids
- */
- const addModules = (modules, chunk, list) => {
- for (const m of modules) {
- const module = /** @type {ConsumeSharedModule} */ (m);
- const id = chunkGraph.getModuleId(module);
- list.push(id);
- moduleIdToSourceMapping.set(
- id,
- codeGenerationResults.getSource(
- module,
- chunk.runtime,
- "consume-shared"
- )
- );
- }
- };
- for (const chunk of this.chunk.getAllAsyncChunks()) {
- const modules = chunkGraph.getChunkModulesIterableBySourceType(
- chunk,
- "consume-shared"
- );
- if (!modules) continue;
- addModules(modules, chunk, (chunkToModuleMapping[chunk.id] = []));
- }
- for (const chunk of this.chunk.getAllInitialChunks()) {
- const modules = chunkGraph.getChunkModulesIterableBySourceType(
- chunk,
- "consume-shared"
- );
- if (!modules) continue;
- addModules(modules, chunk, initialConsumes);
- }
- if (moduleIdToSourceMapping.size === 0) return null;
- return Template.asString([
- parseVersionRuntimeCode(runtimeTemplate),
- versionLtRuntimeCode(runtimeTemplate),
- rangeToStringRuntimeCode(runtimeTemplate),
- satisfyRuntimeCode(runtimeTemplate),
- `var ensureExistence = ${runtimeTemplate.basicFunction("scopeName, key", [
- `var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
- `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) throw new Error("Shared module " + key + " doesn't exist in shared scope " + scopeName);`,
- "return scope;"
- ])};`,
- `var findVersion = ${runtimeTemplate.basicFunction("scope, key", [
- "var versions = scope[key];",
- `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
- "a, b",
- ["return !a || versionLt(a, b) ? b : a;"]
- )}, 0);`,
- "return key && versions[key]"
- ])};`,
- `var findSingletonVersionKey = ${runtimeTemplate.basicFunction(
- "scope, key",
- [
- "var versions = scope[key];",
- `return Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
- "a, b",
- ["return !a || (!versions[a].loaded && versionLt(a, b)) ? b : a;"]
- )}, 0);`
- ]
- )};`,
- `var getInvalidSingletonVersionMessage = ${runtimeTemplate.basicFunction(
- "scope, key, version, requiredVersion",
- [
- `return "Unsatisfied version " + version + " from " + (version && scope[key][version].from) + " of shared singleton module " + key + " (required " + rangeToString(requiredVersion) + ")"`
- ]
- )};`,
- `var getSingleton = ${runtimeTemplate.basicFunction(
- "scope, scopeName, key, requiredVersion",
- [
- "var version = findSingletonVersionKey(scope, key);",
- "return get(scope[key][version]);"
- ]
- )};`,
- `var getSingletonVersion = ${runtimeTemplate.basicFunction(
- "scope, scopeName, key, requiredVersion",
- [
- "var version = findSingletonVersionKey(scope, key);",
- "if (!satisfy(requiredVersion, version)) " +
- 'typeof console !== "undefined" && console.warn && console.warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));',
- "return get(scope[key][version]);"
- ]
- )};`,
- `var getStrictSingletonVersion = ${runtimeTemplate.basicFunction(
- "scope, scopeName, key, requiredVersion",
- [
- "var version = findSingletonVersionKey(scope, key);",
- "if (!satisfy(requiredVersion, version)) " +
- "throw new Error(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));",
- "return get(scope[key][version]);"
- ]
- )};`,
- `var findValidVersion = ${runtimeTemplate.basicFunction(
- "scope, key, requiredVersion",
- [
- "var versions = scope[key];",
- `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction(
- "a, b",
- [
- "if (!satisfy(requiredVersion, b)) return a;",
- "return !a || versionLt(a, b) ? b : a;"
- ]
- )}, 0);`,
- "return key && versions[key]"
- ]
- )};`,
- `var getInvalidVersionMessage = ${runtimeTemplate.basicFunction(
- "scope, scopeName, key, requiredVersion",
- [
- "var versions = scope[key];",
- 'return "No satisfying version (" + rangeToString(requiredVersion) + ") of shared module " + key + " found in shared scope " + scopeName + ".\\n" +',
- `\t"Available versions: " + Object.keys(versions).map(${runtimeTemplate.basicFunction(
- "key",
- ['return key + " from " + versions[key].from;']
- )}).join(", ");`
- ]
- )};`,
- `var getValidVersion = ${runtimeTemplate.basicFunction(
- "scope, scopeName, key, requiredVersion",
- [
- "var entry = findValidVersion(scope, key, requiredVersion);",
- "if(entry) return get(entry);",
- "throw new Error(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));"
- ]
- )};`,
- `var warnInvalidVersion = ${runtimeTemplate.basicFunction(
- "scope, scopeName, key, requiredVersion",
- [
- 'typeof console !== "undefined" && console.warn && console.warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion));'
- ]
- )};`,
- `var get = ${runtimeTemplate.basicFunction("entry", [
- "entry.loaded = 1;",
- "return entry.get()"
- ])};`,
- `var init = ${runtimeTemplate.returningFunction(
- Template.asString([
- "function(scopeName, a, b, c) {",
- Template.indent([
- `var promise = ${RuntimeGlobals.initializeSharing}(scopeName);`,
- `if (promise && promise.then) return promise.then(fn.bind(fn, scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], a, b, c));`,
- `return fn(scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], a, b, c);`
- ]),
- "}"
- ]),
- "fn"
- )};`,
- "",
- `var load = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key",
- [
- "ensureExistence(scopeName, key);",
- "return get(findVersion(scope, key));"
- ]
- )});`,
- `var loadFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key, fallback",
- [
- `return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) ? get(findVersion(scope, key)) : fallback();`
- ]
- )});`,
- `var loadVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key, version",
- [
- "ensureExistence(scopeName, key);",
- "return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));"
- ]
- )});`,
- `var loadSingleton = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key",
- [
- "ensureExistence(scopeName, key);",
- "return getSingleton(scope, scopeName, key);"
- ]
- )});`,
- `var loadSingletonVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key, version",
- [
- "ensureExistence(scopeName, key);",
- "return getSingletonVersion(scope, scopeName, key, version);"
- ]
- )});`,
- `var loadStrictVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key, version",
- [
- "ensureExistence(scopeName, key);",
- "return getValidVersion(scope, scopeName, key, version);"
- ]
- )});`,
- `var loadStrictSingletonVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key, version",
- [
- "ensureExistence(scopeName, key);",
- "return getStrictSingletonVersion(scope, scopeName, key, version);"
- ]
- )});`,
- `var loadVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key, version, fallback",
- [
- `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`,
- "return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));"
- ]
- )});`,
- `var loadSingletonFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key, fallback",
- [
- `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`,
- "return getSingleton(scope, scopeName, key);"
- ]
- )});`,
- `var loadSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key, version, fallback",
- [
- `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`,
- "return getSingletonVersion(scope, scopeName, key, version);"
- ]
- )});`,
- `var loadStrictVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key, version, fallback",
- [
- `var entry = scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) && findValidVersion(scope, key, version);`,
- `return entry ? get(entry) : fallback();`
- ]
- )});`,
- `var loadStrictSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction(
- "scopeName, scope, key, version, fallback",
- [
- `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`,
- "return getStrictSingletonVersion(scope, scopeName, key, version);"
- ]
- )});`,
- "var installedModules = {};",
- "var moduleToHandlerMapping = {",
- Template.indent(
- Array.from(
- moduleIdToSourceMapping,
- ([key, source]) => `${JSON.stringify(key)}: ${source.source()}`
- ).join(",\n")
- ),
- "};",
- initialConsumes.length > 0
- ? Template.asString([
- `var initialConsumes = ${JSON.stringify(initialConsumes)};`,
- `initialConsumes.forEach(${runtimeTemplate.basicFunction("id", [
- `${
- RuntimeGlobals.moduleFactories
- }[id] = ${runtimeTemplate.basicFunction("module", [
- "// Handle case when module is used sync",
- "installedModules[id] = 0;",
- `delete ${RuntimeGlobals.moduleCache}[id];`,
- "var factory = moduleToHandlerMapping[id]();",
- 'if(typeof factory !== "function") throw new Error("Shared module is not available for eager consumption: " + id);',
- `module.exports = factory();`
- ])}`
- ])});`
- ])
- : "// no consumes in initial chunks",
- this._runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)
- ? Template.asString([
- `var chunkMapping = ${JSON.stringify(
- chunkToModuleMapping,
- null,
- "\t"
- )};`,
- `${
- RuntimeGlobals.ensureChunkHandlers
- }.consumes = ${runtimeTemplate.basicFunction("chunkId, promises", [
- `if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`,
- Template.indent([
- `chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction(
- "id",
- [
- `if(${RuntimeGlobals.hasOwnProperty}(installedModules, id)) return promises.push(installedModules[id]);`,
- `var onFactory = ${runtimeTemplate.basicFunction(
- "factory",
- [
- "installedModules[id] = 0;",
- `${
- RuntimeGlobals.moduleFactories
- }[id] = ${runtimeTemplate.basicFunction("module", [
- `delete ${RuntimeGlobals.moduleCache}[id];`,
- "module.exports = factory();"
- ])}`
- ]
- )};`,
- `var onError = ${runtimeTemplate.basicFunction("error", [
- "delete installedModules[id];",
- `${
- RuntimeGlobals.moduleFactories
- }[id] = ${runtimeTemplate.basicFunction("module", [
- `delete ${RuntimeGlobals.moduleCache}[id];`,
- "throw error;"
- ])}`
- ])};`,
- "try {",
- Template.indent([
- "var promise = moduleToHandlerMapping[id]();",
- "if(promise.then) {",
- Template.indent(
- "promises.push(installedModules[id] = promise.then(onFactory)['catch'](onError));"
- ),
- "} else onFactory(promise);"
- ]),
- "} catch(e) { onError(e); }"
- ]
- )});`
- ]),
- "}"
- ])}`
- ])
- : "// no chunk loading of consumes"
- ]);
- }
- }
- module.exports = ConsumeSharedRuntimeModule;
|