From 7a795115dcb7eab13726e408614aea07cf875d0a Mon Sep 17 00:00:00 2001 From: Kirill Zaytsev Date: Wed, 24 Jan 2024 12:24:10 +0400 Subject: [PATCH] fix: Consumption of eager shared modules --- lib/sharing/ConsumeSharedModule.js | 33 +-- lib/sharing/ConsumeSharedRuntimeModule.js | 241 ++++++++++------------ 2 files changed, 123 insertions(+), 151 deletions(-) diff --git a/lib/sharing/ConsumeSharedModule.js b/lib/sharing/ConsumeSharedModule.js index 0ad41d31396..570b52be034 100644 --- a/lib/sharing/ConsumeSharedModule.js +++ b/lib/sharing/ConsumeSharedModule.js @@ -206,26 +206,31 @@ class ConsumeSharedModule extends Module { }); } } - let fn = "load"; - const args = [JSON.stringify(shareScope), JSON.stringify(shareKey)]; + + const args = [ + JSON.stringify(shareScope), + JSON.stringify(shareKey), + JSON.stringify(eager) + ]; if (requiredVersion) { - if (strictVersion) { - fn += "Strict"; - } - if (singleton) { - fn += "Singleton"; - } args.push(stringifyHoley(requiredVersion)); - fn += "VersionCheck"; - } else { - if (singleton) { - fn += "Singleton"; - } } if (fallbackCode) { - fn += "Fallback"; args.push(fallbackCode); } + + let fn; + + if (requiredVersion) { + if (strictVersion) { + fn = singleton ? "loadStrictSingletonVersion" : "loadStrictVersion"; + } else { + fn = singleton ? "loadSingletonVersion" : "loadVersion"; + } + } else { + fn = singleton ? "loadSingleton" : "load"; + } + const code = runtimeTemplate.returningFunction(`${fn}(${args.join(", ")})`); const sources = new Map(); sources.set("consume-shared", new RawSource(code)); diff --git a/lib/sharing/ConsumeSharedRuntimeModule.js b/lib/sharing/ConsumeSharedRuntimeModule.js index 223facceead..0d5e4883528 100644 --- a/lib/sharing/ConsumeSharedRuntimeModule.js +++ b/lib/sharing/ConsumeSharedRuntimeModule.js @@ -88,63 +88,39 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { 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 exists = ${runtimeTemplate.basicFunction("scope, key", [ + `return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key);` + ])}`, + `var get = ${runtimeTemplate.basicFunction("entry", [ + "entry.loaded = 1;", + "return entry.get()" ])};`, - `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 eagerOnly = ${runtimeTemplate.basicFunction("versions", [ + `return Object.keys(versions).reduce(${runtimeTemplate.basicFunction( + "filtered, version", + Template.indent([ + "if (versions[version].eager) {", + Template.indent(["filtered[version] = versions[version];"]), + "}", + "return filtered;" + ]) + )}, {});` ])};`, - `var findSingletonVersionKey = ${runtimeTemplate.basicFunction( - "scope, key", + `var findLatestVersion = ${runtimeTemplate.basicFunction( + "scope, key, eager", [ - "var versions = scope[key];", - `return Object.keys(versions).reduce(${runtimeTemplate.basicFunction( + "var versions = eager ? eagerOnly(scope[key]) : scope[key];", + `var key = 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)) 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]);" + ["return !a || versionLt(a, b) ? b : a;"] + )}, 0);`, + "return key && versions[key];" ] )};`, - `var findValidVersion = ${runtimeTemplate.basicFunction( - "scope, key, requiredVersion", + `var findSatisfyingVersion = ${runtimeTemplate.basicFunction( + "scope, key, requiredVersion, eager", [ - "var versions = scope[key];", + "var versions = eager ? eagerOnly(scope[key]) : scope[key];", `var key = Object.keys(versions).reduce(${runtimeTemplate.basicFunction( "a, b", [ @@ -155,136 +131,127 @@ class ConsumeSharedRuntimeModule extends RuntimeModule { "return key && versions[key]" ] )};`, + `var findSingletonVersionKey = ${runtimeTemplate.basicFunction( + "scope, key, eager", + [ + "var versions = eager ? eagerOnly(scope[key]) : 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 getInvalidVersionMessage = ${runtimeTemplate.basicFunction( - "scope, scopeName, key, requiredVersion", + "scope, scopeName, key, requiredVersion, eager", [ "var versions = scope[key];", - 'return "No satisfying version (" + rangeToString(requiredVersion) + ") of shared module " + key + " found in shared scope " + scopeName + ".\\n" +', + 'return "No satisfying version (" + rangeToString(requiredVersion) + ")" + (eager ? " for eager consumption" : "") + " 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 warn = ${ + `var fail = ${runtimeTemplate.basicFunction("msg", [ + "throw new Error(msg);" + ])}`, + `var failAsNotExist = ${runtimeTemplate.basicFunction("scopeName, key", [ + 'return fail("Shared module " + key + " doesn\'t exist in shared scope " + scopeName);' + ])}`, + `var warn = /*#__PURE__*/ ${ compilation.outputOptions.ignoreBrowserWarnings ? runtimeTemplate.basicFunction("", "") : runtimeTemplate.basicFunction("msg", [ 'if (typeof console !== "undefined" && console.warn) console.warn(msg);' ]) };`, - `var warnInvalidVersion = ${runtimeTemplate.basicFunction( - "scope, scopeName, key, requiredVersion", - [ - "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) {", + "function(scopeName, key, eager, c, d) {", 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);` + // if we require eager shared, we expect it to be already loaded before it requested, no need to wait the whole scope loaded. + "if (promise && promise.then && !eager) { ", + Template.indent([ + `return promise.then(fn.bind(fn, scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, false, c, d));` + ]), + "}", + `return fn(scopeName, ${RuntimeGlobals.shareScopeMap}[scopeName], key, eager, c, d);` ]), "}" ]), "fn" )};`, "", + `var useFallback = ${runtimeTemplate.basicFunction( + "scopeName, key, fallback", + ["return fallback ? fallback() : failAsNotExist(scopeName, key);"] + )}`, `var load = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key", + "scopeName, scope, key, eager, fallback", [ - "ensureExistence(scopeName, key);", - "return get(findVersion(scope, key));" + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "return get(findLatestVersion(scope, key, eager));" ] )});`, - `var loadFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, fallback", + `var loadVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( + "scopeName, scope, key, eager, requiredVersion, fallback", [ - `return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) ? get(findVersion(scope, key)) : fallback();` + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);", + "if (satisfyingVersion) return get(satisfyingVersion);", + "warn(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager))", + "return get(findLatestVersion(scope, key, eager));" ] )});`, - `var loadVersionCheck = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version", + `var loadStrictVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( + "scopeName, scope, key, eager, requiredVersion, fallback", [ - "ensureExistence(scopeName, key);", - "return get(findValidVersion(scope, key, version) || warnInvalidVersion(scope, scopeName, key, version) || findVersion(scope, key));" + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "var satisfyingVersion = findSatisfyingVersion(scope, key, requiredVersion, eager);", + "if (satisfyingVersion) return get(satisfyingVersion);", + "if (fallback) return fallback();", + "fail(getInvalidVersionMessage(scope, scopeName, key, requiredVersion, eager));" ] )});`, `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", + "scopeName, scope, key, eager, fallback", [ - "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);" + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "var version = findSingletonVersionKey(scope, key, eager);", + "return get(scope[key][version]);" ] )});`, - `var loadStrictVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version, fallback", + `var loadSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( + "scopeName, scope, key, eager, requiredVersion, fallback", [ - `var entry = scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) && findValidVersion(scope, key, version);`, - `return entry ? get(entry) : fallback();` + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "var version = findSingletonVersionKey(scope, key, eager);", + "if (!satisfy(requiredVersion, version)) {", + Template.indent([ + "warn(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));" + ]), + "}", + "return get(scope[key][version]);" ] )});`, - `var loadStrictSingletonVersionCheckFallback = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( - "scopeName, scope, key, version, fallback", + `var loadStrictSingletonVersion = /*#__PURE__*/ init(${runtimeTemplate.basicFunction( + "scopeName, scope, key, eager, requiredVersion, fallback", [ - `if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`, - "return getStrictSingletonVersion(scope, scopeName, key, version);" + "if (!exists(scope, key)) return useFallback(scopeName, key, fallback);", + "var version = findSingletonVersionKey(scope, key, eager);", + "if (!satisfy(requiredVersion, version)) {", + Template.indent([ + "fail(getInvalidSingletonVersionMessage(scope, key, version, requiredVersion));" + ]), + "}", + "return get(scope[key][version]);" ] )});`, "var installedModules = {};",