fix behavior of runtime option for async entries

add runtimeName option to set the runtime name but not the runtime chunk
This commit is contained in:
Tobias Koppers 2021-01-05 12:27:33 +01:00
parent 3edfa4b79d
commit 7fa009e254
10 changed files with 108 additions and 36 deletions

View File

@ -126,6 +126,10 @@ export type UmdNamedDefine = boolean;
* The name of the runtime chunk. If set a runtime chunk with this name is created or an existing entrypoint is used as runtime.
*/
export type EntryRuntime = string;
/**
* The name of the runtime that the entry will be associated to. Optimization for modules will be done per runtime.
*/
export type EntryRuntimeName = string;
/**
* The method of loading WebAssembly Modules (methods included by default are 'fetch' (web/WebWorker), 'async-node' (node.js), but others might be added by plugins).
*/
@ -1029,6 +1033,10 @@ export interface EntryDescription {
* The name of the runtime chunk. If set a runtime chunk with this name is created or an existing entrypoint is used as runtime.
*/
runtime?: EntryRuntime;
/**
* The name of the runtime that the entry will be associated to. Optimization for modules will be done per runtime.
*/
runtimeName?: EntryRuntimeName;
/**
* The method of loading WebAssembly Modules (methods included by default are 'fetch' (web/WebWorker), 'async-node' (node.js), but others might be added by plugins).
*/
@ -2684,6 +2692,10 @@ export interface EntryDescriptionNormalized {
* The name of the runtime chunk. If set a runtime chunk with this name is created or an existing entrypoint is used as runtime.
*/
runtime?: EntryRuntime;
/**
* The name of the runtime that the entry will be associated to. Optimization for modules will be done per runtime.
*/
runtimeName?: EntryRuntimeName;
/**
* The method of loading WebAssembly Modules (methods included by default are 'fetch' (web/WebWorker), 'async-node' (node.js), but others might be added by plugins).
*/

View File

@ -2514,6 +2514,47 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
});
}
/**
* @template T
* @param {function(EntryOptions, string): T} selector get value from entry options
* @param {function(T, T): T} merge merge multiple values when referenced by multiple runtimes
* @param {string} name name of the entry
* @param {EntryOptions=} options optionally already received entry options
* @returns {T} selected and merged options
*/
_getRuntimeOptions(selector, merge, name, options) {
if (!options) {
const entry = this.entries.get(name);
if (!entry) return selector(undefined, name);
options = entry.options;
}
let { dependOn } = options;
if (dependOn) {
let first = true;
/** @type {T} */
let result;
const queue = new Set(dependOn);
for (const name of queue) {
const dep = this.entries.get(name);
if (!dep) continue;
const { dependOn } = dep.options;
if (dependOn) {
for (const name of dependOn) {
queue.add(name);
}
} else if (first) {
result = selector(dep.options, name);
first = false;
} else {
result = merge(result, selector(dep.options, name));
}
}
return result;
} else {
return selector(options, name);
}
}
/**
* @param {Module} module module to report from
* @param {DependenciesBlock[]} blocks blocks to report from
@ -2904,7 +2945,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
* @returns {Entrypoint} the new or existing entrypoint
*/
addAsyncEntrypoint(options, module, loc, request) {
const name = options.name;
const { name, runtime } = options;
if (name) {
const entrypoint = this.namedChunkGroups.get(name);
if (entrypoint instanceof Entrypoint) {
@ -2925,7 +2966,6 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
chunk.filenameTemplate = options.filename;
}
const entrypoint = new Entrypoint(options, false);
entrypoint.setRuntimeChunk(chunk);
entrypoint.setEntrypointChunk(chunk);
if (name) {
this.namedChunkGroups.set(name, entrypoint);
@ -2933,6 +2973,18 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
this.chunkGroups.push(entrypoint);
this.asyncEntrypoints.push(entrypoint);
connectChunkGroupAndChunk(entrypoint, chunk);
if (runtime) {
let chunk = this.namedChunks.get(runtime);
if (!chunk) {
chunk = this.addChunk(runtime);
chunk.preventIntegration = true;
}
entrypoint.unshiftChunk(chunk);
chunk.addGroup(entrypoint);
entrypoint.setRuntimeChunk(chunk);
} else {
entrypoint.setRuntimeChunk(chunk);
}
if (module) {
entrypoint.addOrigin(module, loc, request);
}

View File

@ -60,6 +60,7 @@ class EntryOptionPlugin {
name,
filename: desc.filename,
runtime: desc.runtime,
runtimeName: desc.runtimeName,
layer: desc.layer,
dependOn: desc.dependOn,
chunkLoading: desc.chunkLoading,

View File

@ -180,7 +180,12 @@ class FlagDependencyUsagePlugin {
b.groupOptions &&
b.groupOptions.entryOptions
) {
processModule(b, b.groupOptions.entryOptions.runtime, true);
const entryOptions = b.groupOptions.entryOptions;
processModule(
b,
entryOptions.runtime || entryOptions.runtimeName,
true
);
} else {
queue.enqueue(b);
}

View File

@ -356,7 +356,10 @@ const visitModules = (
entrypoint.index = nextChunkGroupIndex++;
cgi = {
chunkGroup: entrypoint,
runtime: entrypoint.options.runtime || entrypoint.name,
runtime:
entrypoint.options.runtime ||
entrypoint.options.runtimeName ||
entrypoint.name,
minAvailableModules: EMPTY_SET,
minAvailableModulesOwned: false,
availableModulesToBeMerged: [],
@ -386,7 +389,7 @@ const visitModules = (
action: PROCESS_ENTRY_BLOCK,
block: b,
module: module,
chunk: entrypoint.chunks[0],
chunk: entrypoint.getEntrypointChunk(),
chunkGroup: entrypoint,
chunkGroupInfo: cgi
});

View File

@ -459,6 +459,7 @@ const getNormalizedEntryStatic = entry => {
filename: value.filename,
layer: value.layer,
runtime: value.runtime,
runtimeName: value.runtimeName,
chunkLoading: value.chunkLoading,
wasmLoading: value.wasmLoading,
dependOn:

View File

@ -263,8 +263,8 @@ class WorkerPlugin {
entryOptions.name = options.name;
}
if (!entryOptions.runtime) {
entryOptions.runtime = `${cachedContextify(
if (!entryOptions.runtime && !entryOptions.runtimeName) {
entryOptions.runtimeName = `${cachedContextify(
parser.state.module.identifier()
)}|${formatLocation(expr.loc)}`;
}

View File

@ -20,35 +20,12 @@ const SortableSet = require("./SortableSet");
* @returns {RuntimeSpec} runtime
*/
exports.getEntryRuntime = (compilation, name, options) => {
let dependOn;
let runtime;
if (options) {
({ dependOn, runtime } = options);
} else {
const entry = compilation.entries.get(name);
if (!entry) return name;
({ dependOn, runtime } = entry.options);
}
if (dependOn) {
/** @type {RuntimeSpec} */
let result = undefined;
const queue = new Set(dependOn);
for (const name of queue) {
const dep = compilation.entries.get(name);
if (!dep) continue;
const { dependOn, runtime } = dep.options;
if (dependOn) {
for (const name of dependOn) {
queue.add(name);
}
} else {
result = mergeRuntimeOwned(result, runtime || name);
}
}
return result || name;
} else {
return runtime || name;
}
return compilation._getRuntimeOptions(
(options, name) => options.runtime || options.runtimeName || name,
mergeRuntimeOwned,
name,
options
);
};
/**

View File

@ -473,6 +473,9 @@
"runtime": {
"$ref": "#/definitions/EntryRuntime"
},
"runtimeName": {
"$ref": "#/definitions/EntryRuntimeName"
},
"wasmLoading": {
"$ref": "#/definitions/WasmLoading"
}
@ -521,6 +524,9 @@
"runtime": {
"$ref": "#/definitions/EntryRuntime"
},
"runtimeName": {
"$ref": "#/definitions/EntryRuntimeName"
},
"wasmLoading": {
"$ref": "#/definitions/WasmLoading"
}
@ -596,6 +602,11 @@
"type": "string",
"minLength": 1
},
"EntryRuntimeName": {
"description": "The name of the runtime that the entry will be associated to. Optimization for modules will be done per runtime.",
"type": "string",
"minLength": 1
},
"EntryStatic": {
"description": "A static entry description.",
"anyOf": [

10
types.d.ts vendored
View File

@ -2931,6 +2931,11 @@ declare interface EntryDescription {
*/
runtime?: string;
/**
* The name of the runtime that the entry will be associated to. Optimization for modules will be done per runtime.
*/
runtimeName?: string;
/**
* The method of loading WebAssembly Modules (methods included by default are 'fetch' (web/WebWorker), 'async-node' (node.js), but others might be added by plugins).
*/
@ -2976,6 +2981,11 @@ declare interface EntryDescriptionNormalized {
*/
runtime?: string;
/**
* The name of the runtime that the entry will be associated to. Optimization for modules will be done per runtime.
*/
runtimeName?: string;
/**
* The method of loading WebAssembly Modules (methods included by default are 'fetch' (web/WebWorker), 'async-node' (node.js), but others might be added by plugins).
*/