diff --git a/lib/Compilation.js b/lib/Compilation.js index 866b2608e48..4d28d52681a 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -3332,6 +3332,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o dependencyTemplates, runtimeTemplate, runtime, + runtimes, codeGenerationResults: results, compilation: this }); diff --git a/lib/DependencyTemplate.js b/lib/DependencyTemplate.js index 67a4d7b8305..3352be7f661 100644 --- a/lib/DependencyTemplate.js +++ b/lib/DependencyTemplate.js @@ -26,7 +26,8 @@ * @property {ChunkGraph} chunkGraph the chunk graph * @property {Set} runtimeRequirements the requirements for runtime * @property {Module} module current module - * @property {RuntimeSpec} runtime current runtimes, for which code is generated + * @property {RuntimeSpec} runtime current runtime, for which code is generated + * @property {RuntimeSpec[]} [runtimes] current runtimes, for which code is generated * @property {InitFragment[]} initFragments mutable array of init fragments for the current module * @property {ConcatenationScope=} concatenationScope when in a concatenated module, information about other concatenated modules * @property {CodeGenerationResults} codeGenerationResults the code generation results diff --git a/lib/Generator.js b/lib/Generator.js index 3423b05e258..9c55b589e98 100644 --- a/lib/Generator.js +++ b/lib/Generator.js @@ -27,6 +27,7 @@ * @property {ChunkGraph} chunkGraph the chunk graph * @property {Set} runtimeRequirements the requirements for runtime * @property {RuntimeSpec} runtime the runtime + * @property {RuntimeSpec[]} [runtimes] the runtimes * @property {ConcatenationScope=} concatenationScope when in concatenated module, information about other concatenated modules * @property {CodeGenerationResults=} codeGenerationResults code generation results of other modules (need to have a codeGenerationDependency to use that) * @property {string} type which kind of code should be generated diff --git a/lib/Module.js b/lib/Module.js index aede5945566..90c8579fcf8 100644 --- a/lib/Module.js +++ b/lib/Module.js @@ -56,7 +56,8 @@ const makeSerializable = require("./util/makeSerializable"); * @property {RuntimeTemplate} runtimeTemplate the runtime template * @property {ModuleGraph} moduleGraph the module graph * @property {ChunkGraph} chunkGraph the chunk graph - * @property {RuntimeSpec} runtime the runtimes code should be generated for + * @property {RuntimeSpec} runtime the runtime code should be generated for + * @property {RuntimeSpec[]} [runtimes] the runtimes code should be generated for * @property {ConcatenationScope=} concatenationScope when in concatenated module, information about other concatenated modules * @property {CodeGenerationResults} codeGenerationResults code generation results of other modules (need to have a codeGenerationDependency to use that) * @property {Compilation=} compilation the compilation diff --git a/lib/NormalModule.js b/lib/NormalModule.js index 4d1264f9b3c..a72a7758db5 100644 --- a/lib/NormalModule.js +++ b/lib/NormalModule.js @@ -1175,6 +1175,7 @@ class NormalModule extends Module { moduleGraph, chunkGraph, runtime, + runtimes, concatenationScope, codeGenerationResults, sourceTypes @@ -1208,6 +1209,7 @@ class NormalModule extends Module { chunkGraph, runtimeRequirements, runtime, + runtimes, concatenationScope, codeGenerationResults, getData, diff --git a/lib/dependencies/PureExpressionDependency.js b/lib/dependencies/PureExpressionDependency.js index 3ee70286d1d..70ed68cb113 100644 --- a/lib/dependencies/PureExpressionDependency.js +++ b/lib/dependencies/PureExpressionDependency.js @@ -7,7 +7,7 @@ const { UsageState } = require("../ExportsInfo"); const makeSerializable = require("../util/makeSerializable"); -const { filterRuntime } = require("../util/runtime"); +const { filterRuntime, deepMergeRuntime } = require("../util/runtime"); const NullDependency = require("./NullDependency"); /** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ @@ -84,7 +84,14 @@ PureExpressionDependency.Template = class PureExpressionDependencyTemplate exten apply( dependency, source, - { chunkGraph, moduleGraph, runtime, runtimeTemplate, runtimeRequirements } + { + chunkGraph, + moduleGraph, + runtime, + runtimes, + runtimeTemplate, + runtimeRequirements + } ) { const dep = /** @type {PureExpressionDependency} */ (dependency); @@ -92,7 +99,8 @@ PureExpressionDependency.Template = class PureExpressionDependencyTemplate exten if (usedByExports !== false) { const selfModule = moduleGraph.getParentModule(dep); const exportsInfo = moduleGraph.getExportsInfo(selfModule); - const runtimeCondition = filterRuntime(runtime, runtime => { + const merged = deepMergeRuntime(runtimes, runtime); + const runtimeCondition = filterRuntime(merged, runtime => { for (const exportName of usedByExports) { if (exportsInfo.getUsed(exportName, runtime) !== UsageState.Unused) { return true; @@ -104,7 +112,7 @@ PureExpressionDependency.Template = class PureExpressionDependencyTemplate exten if (runtimeCondition !== false) { const condition = runtimeTemplate.runtimeConditionExpression({ chunkGraph, - runtime, + runtime: merged, runtimeCondition, runtimeRequirements }); diff --git a/lib/javascript/JavascriptGenerator.js b/lib/javascript/JavascriptGenerator.js index d13eb8a07f5..1cb9b61f393 100644 --- a/lib/javascript/JavascriptGenerator.js +++ b/lib/javascript/JavascriptGenerator.js @@ -197,6 +197,7 @@ class JavascriptGenerator extends Generator { chunkGraph: generateContext.chunkGraph, module, runtime: generateContext.runtime, + runtimes: generateContext.runtimes, runtimeRequirements: generateContext.runtimeRequirements, concatenationScope: generateContext.concatenationScope, codeGenerationResults: generateContext.codeGenerationResults, diff --git a/lib/util/runtime.js b/lib/util/runtime.js index cdc29c24db7..dd05408ea0f 100644 --- a/lib/util/runtime.js +++ b/lib/util/runtime.js @@ -57,7 +57,7 @@ exports.getEntryRuntime = (compilation, name, options) => { * @param {boolean} deterministicOrder enforce a deterministic order * @returns {void} */ -exports.forEachRuntime = (runtime, fn, deterministicOrder = false) => { +const forEachRuntime = (runtime, fn, deterministicOrder = false) => { if (runtime === undefined) { fn(undefined); } else if (typeof runtime === "string") { @@ -69,6 +69,7 @@ exports.forEachRuntime = (runtime, fn, deterministicOrder = false) => { } } }; +exports.forEachRuntime = forEachRuntime; const getRuntimesKey = set => { set.sort(); @@ -218,6 +219,22 @@ const mergeRuntime = (a, b) => { }; exports.mergeRuntime = mergeRuntime; +/** + * @param {RuntimeSpec[]} runtimes first + * @param {RuntimeSpec} runtime second + * @returns {RuntimeSpec} merged + */ +exports.deepMergeRuntime = (runtimes, runtime) => { + if (!Array.isArray(runtimes)) { + return runtime; + } + let merged = runtime; + for (const r of runtimes) { + merged = mergeRuntime(runtime, r); + } + return merged; +}; + /** * @param {RuntimeCondition} a first * @param {RuntimeCondition} b second diff --git a/types.d.ts b/types.d.ts index 251d0adfd3d..bd5d14c3ce1 100644 --- a/types.d.ts +++ b/types.d.ts @@ -1241,10 +1241,15 @@ declare interface CodeGenerationContext { chunkGraph: ChunkGraph; /** - * the runtimes code should be generated for + * the runtime code should be generated for */ runtime: RuntimeSpec; + /** + * the runtimes code should be generated for + */ + runtimes?: RuntimeSpec[]; + /** * when in concatenated module, information about other concatenated modules */ @@ -2765,10 +2770,15 @@ declare interface DependencyTemplateContext { module: Module; /** - * current runtimes, for which code is generated + * current runtime, for which code is generated */ runtime: RuntimeSpec; + /** + * current runtimes, for which code is generated + */ + runtimes?: RuntimeSpec[]; + /** * mutable array of init fragments for the current module */ @@ -4371,6 +4381,11 @@ declare interface GenerateContext { */ runtime: RuntimeSpec; + /** + * the runtimes + */ + runtimes?: RuntimeSpec[]; + /** * when in concatenated module, information about other concatenated modules */ @@ -13005,6 +13020,10 @@ declare namespace exports { export let runtimeEqual: (a: RuntimeSpec, b: RuntimeSpec) => boolean; export let compareRuntime: (a: RuntimeSpec, b: RuntimeSpec) => 0 | 1 | -1; export let mergeRuntime: (a: RuntimeSpec, b: RuntimeSpec) => RuntimeSpec; + export let deepMergeRuntime: ( + runtimes: RuntimeSpec[], + runtime: RuntimeSpec + ) => RuntimeSpec; export let mergeRuntimeCondition: ( a: RuntimeCondition, b: RuntimeCondition,