
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const InitFragment = require("./InitFragment");
const RuntimeGlobals = require("./RuntimeGlobals");
const Template = require("./Template");
const { equals } = require("./util/ArrayHelpers");
const compileBooleanMatcher = require("./util/compileBooleanMatcher");
const propertyAccess = require("./util/propertyAccess");
const { forEachRuntime, subtractRuntime } = require("./util/runtime");
/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
/** @typedef {import("./Compilation")} Compilation */
/** @typedef {import("./Dependency")} Dependency */
/** @typedef {import("./Module")} Module */
/** @typedef {import("./ModuleGraph")} ModuleGraph */
/** @typedef {import("./RequestShortener")} RequestShortener */
/** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
/**
* @param {Module} module the module
* @param {ChunkGraph} chunkGraph the chunk graph
* @returns {string} error message
*/
const noModuleIdErrorMessage = (module, chunkGraph) => {
return `Module ${module.identifier()} has no id assigned.
This should not happen.
It's in these chunks: ${
Array.from(
chunkGraph.getModuleChunksIterable(module),
c => c.name || c.id || c.debugId
).join(", ") || "none"
} (If module is in no chunk this indicates a bug in some chunk/module optimization logic)
Module has these incoming connections: ${Array.from(
chunkGraph.moduleGraph.getIncomingConnections(module),
connection =>
`\n - ${
connection.originModule && connection.originModule.identifier()
} ${connection.dependency && connection.dependency.type} ${
(connection.explanations &&
Array.from(connection.explanations).join(", ")) ||
""
}`
).join("")}`;
};
/**
* @param {string|undefined} definition global object definition
* @returns {string} save to use global object
*/
function getGlobalObject(definition) {
if (!definition) return definition;
const trimmed = definition.trim();
if (
// identifier, we do not need real identifier regarding ECMAScript/Unicode
trimmed.match(/^[_\p{L}][_0-9\p{L}]*$/iu) ||
// iife
// call expression
// expression in parentheses
trimmed.match(/^([_\p{L}][_0-9\p{L}]*)?\(.*\)$/iu)
)
return trimmed;
return `Object(${trimmed})`;
}
class RuntimeTemplate {
/**
* @param {Compilation} compilation the compilation
* @param {OutputOptions} outputOptions the compilation output options
* @param {RequestShortener} requestShortener the request shortener
*/
constructor(compilation, outputOptions, requestShortener) {
this.compilation = compilation;
this.outputOptions = outputOptions || {};
this.requestShortener = requestShortener;
this.globalObject = getGlobalObject(outputOptions.globalObject);
this.contentHashReplacement = "X".repeat(outputOptions.hashDigestLength);
}
isIIFE() {
return this.outputOptions.iife;
}
isModule() {
return this.outputOptions.module;
}
supportsConst() {
return this.outputOptions.environment.const;
}
supportsArrowFunction() {
return this.outputOptions.environment.arrowFunction;
}
supportsOptionalChaining() {
return this.outputOptions.environment.optionalChaining;
}
supportsForOf() {
return this.outputOptions.environment.forOf;
}
supportsDestructuring() {
return this.outputOptions.environment.destructuring;
}
supportsBigIntLiteral() {
return this.outputOptions.environment.bigIntLiteral;
}
supportsDynamicImport() {
return this.outputOptions.environment.dynamicImport;
}
supportsEcmaScriptModuleSyntax() {
return this.outputOptions.environment.module;
}
supportTemplateLiteral() {
return this.outputOptions.environment.templateLiteral;
}
returningFunction(returnValue, args = "") {
return this.supportsArrowFunction()
? `(${args}) => (${returnValue})`
: `function(${args}) { return ${returnValue}; }`;
}
basicFunction(args, body) {
return this.supportsArrowFunction()
? `(${args}) => {\n${Template.indent(body)}\n}`
: `function(${args}) {\n${Template.indent(body)}\n}`;
}
/**
* @param {Array<string|{expr: string}>} args args
* @returns {string} result expression
*/
concatenation(...args) {
const len = args.length;
if (len === 2) return this._es5Concatenation(args);
if (len === 0) return '""';
if (len === 1) {
return typeof args[0] === "string"
? JSON.stringify(args[0])
: `"" + ${args[0].expr}`;
}
if (!this.supportTemplateLiteral()) return this._es5Concatenation(args);
// cost comparison between template literal and concatenation:
// both need equal surroundings: `xxx` vs "xxx"
// template literal has constant cost of 3 chars for each expression
// es5 concatenation has cost of 3 + n chars for n expressions in row
// when a es5 concatenation ends with an expression it reduces cost by 3
// when a es5 concatenation starts with an single expression it reduces cost by 3
// e. g. `${a}${b}${c}` (3*3 = 9) is longer than ""+a+b+c ((3+3)-3 = 3)
// e. g. `x${a}x${b}x${c}x` (3*3 = 9) is shorter than "x"+a+"x"+b+"x"+c+"x" (4+4+4 = 12)
let templateCost = 0;
let concatenationCost = 0;
let lastWasExpr = false;
for (const arg of args) {
const isExpr = typeof arg !== "string";
if (isExpr) {
templateCost += 3;
concatenationCost += lastWasExpr ? 1 : 4;
}
lastWasExpr = isExpr;
}
if (lastWasExpr) concatenationCost -= 3;
if (typeof args[0] !== "string" && typeof args[1] === "string")
concatenationCost -= 3;
if (concatenationCost <= templateCost) return this._es5Concatenation(args);
return `\`${args
.map(arg => (typeof arg === "string" ? arg : `\${${arg.expr}}`))
.join("")}\``;
}
/**
* @param {Array<string|{expr: string}>} args args (len >= 2)
* @returns {string} result expression
* @private
*/
_es5Concatenation(args) {
const str = args
.map(arg => (typeof arg === "string" ? JSON.stringify(arg) : arg.expr))
.join(" + ");
// when the first two args are expression, we need to prepend "" + to force string
// concatenation instead of number addition.
return typeof args[0] !== "string" && typeof args[1] !== "string"
? `"" + ${str}`
: str;
}
expressionFunction(expression, args = "") {
return this.supportsArrowFunction()
? `(${args}) => (${expression})`
: `function(${args}) { ${expression}; }`;
}
emptyFunction() {
return this.supportsArrowFunction() ? "x => {}" : "function() {}";
}
destructureArray(items, value) {
return this.supportsDestructuring()
? `var [${items.join(", ")}] = ${value};`
: Template.asString(
items.map((item, i) => `var ${item} = ${value}[${i}];`)
);
}
destructureObject(items, value) {
return this.supportsDestructuring()
? `var {${items.join(", ")}} = ${value};`
: Template.asString(
items.map(item => `var ${item} = ${value}${propertyAccess([item])};`)
);
}
iife(args, body) {
return `(${this.basicFunction(args, body)})()`;
}
forEach(variable, array, body) {
return this.supportsForOf()
? `for(const ${variable} of ${array}) {\n${Template.indent(body)}\n}`
: `${array}.forEach(function(${variable}) {\n${Template.indent(
body
)}\n});`;
}
/**
* Add a comment
* @param {object} options Information content of the comment
* @param {string=} options.request request string used originally
* @param {string=} options.chunkName name of the chunk referenced
* @param {string=} options.chunkReason reason information of the chunk
* @param {string=} options.message additional message
* @param {string=} options.exportName name of the export
* @returns {string} comment
*/
comment({ request, chunkName, chunkReason, message, exportName }) {
let content;
if (this.outputOptions.pathinfo) {
content = [message, request, chunkName, chunkReason]
.filter(Boolean)
.map(item => this.requestShortener.shorten(item))
.join(" | ");
} else {
content = [message, chunkName, chunkReason]
.filter(Boolean)
.map(item => this.requestShortener.shorten(item))
.join(" | ");
}
if (!content) return "";
if (this.outputOptions.pathinfo) {
return Template.toComment(content) + " ";
} else {
return Template.toNormalComment(content) + " ";
}
}
/**
* @param {object} options generation options
* @param {string=} options.request request string used originally
* @returns {string} generated error block
*/
throwMissingModuleErrorBlock({ request }) {
const err = `Cannot find module '${request}'`;
return `var e = new Error(${JSON.stringify(
err
)}); e.code = 'MODULE_NOT_FOUND'; throw e;`;
}
/**
* @param {object} options generation options
* @param {string=} options.request request string used originally
* @returns {string} generated error function
*/
throwMissingModuleErrorFunction({ request }) {
return `function webpackMissingModule() { ${this.throwMissingModuleErrorBlock(
{ request }
)} }`;
}
/**
* @param {object} options generation options
* @param {string=} options.request request string used originally
* @returns {string} generated error IIFE
*/
missingModule({ request }) {
return `Object(${this.throwMissingModuleErrorFunction({ request })}())`;
}
/**
* @param {object} options generation options
* @param {string=} options.request request string used originally
* @returns {string} generated error statement
*/
missingModuleStatement({ request }) {
return `${this.missingModule({ request })};\n`;
}
/**
* @param {object} options generation options
* @param {string=} options.request request string used originally
* @returns {string} generated error code
*/
missingModulePromise({ request }) {
return `Promise.resolve().then(${this.throwMissingModuleErrorFunction({
request
})})`;
}
/**
* @param {Object} options options object
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {Module} options.module the module
* @param {string} options.request the request that should be printed as comment
* @param {string=} options.idExpr expression to use as id expression
* @param {"expression" | "promise" | "statements"} options.type which kind of code should be returned
* @returns {string} the code
*/
weakError({ module, chunkGraph, request, idExpr, type }) {
const moduleId = chunkGraph.getModuleId(module);
const errorMessage =
moduleId === null
? JSON.stringify("Module is not available (weak dependency)")
: idExpr
? `"Module '" + ${idExpr} + "' is not available (weak dependency)"`
: JSON.stringify(
`Module '${moduleId}' is not available (weak dependency)`
);
const comment = request ? Template.toNormalComment(request) + " " : "";
const errorStatements =
`var e = new Error(${errorMessage}); ` +
comment +
"e.code = 'MODULE_NOT_FOUND'; throw e;";
switch (type) {
case "statements":
return errorStatements;
case "promise":
return `Promise.resolve().then(${this.basicFunction(
"",
errorStatements
)})`;
case "expression":
return this.iife("", errorStatements);
}
}
/**
* @param {Object} options options object
* @param {Module} options.module the module
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {string} options.request the request that should be printed as comment
* @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
* @returns {string} the expression
*/
moduleId({ module, chunkGraph, request, weak }) {
if (!module) {
return this.missingModule({
request
});
}
const moduleId = chunkGraph.getModuleId(module);
if (moduleId === null) {
if (weak) {
return "null /* weak dependency, without id */";
}
throw new Error(
`RuntimeTemplate.moduleId(): ${noModuleIdErrorMessage(
module,
chunkGraph
)}`
);
}
return `${this.comment({ request })}${JSON.stringify(moduleId)}`;
}
/**
* @param {Object} options options object
* @param {Module} options.module the module
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {string} options.request the request that should be printed as comment
* @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @returns {string} the expression
*/
moduleRaw({ module, chunkGraph, request, weak, runtimeRequirements }) {
if (!module) {
return this.missingModule({
request
});
}
const moduleId = chunkGraph.getModuleId(module);
if (moduleId === null) {
if (weak) {
// only weak referenced modules don't get an id
// we can always emit an error emitting code here
return this.weakError({
module,
chunkGraph,
request,
type: "expression"
});
}
throw new Error(
`RuntimeTemplate.moduleId(): ${noModuleIdErrorMessage(
module,
chunkGraph
)}`
);
}
runtimeRequirements.add(RuntimeGlobals.require);
return `__webpack_require__(${this.moduleId({
module,
chunkGraph,
request,
weak
})})`;
}
/**
* @param {Object} options options object
* @param {Module} options.module the module
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {string} options.request the request that should be printed as comment
* @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @returns {string} the expression
*/
moduleExports({ module, chunkGraph, request, weak, runtimeRequirements }) {
return this.moduleRaw({
module,
chunkGraph,
request,
weak,
runtimeRequirements
});
}
/**
* @param {Object} options options object
* @param {Module} options.module the module
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {string} options.request the request that should be printed as comment
* @param {boolean=} options.strict if the current module is in strict esm mode
* @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @returns {string} the expression
*/
moduleNamespace({
module,
chunkGraph,
request,
strict,
weak,
runtimeRequirements
}) {
if (!module) {
return this.missingModule({
request
});
}
if (chunkGraph.getModuleId(module) === null) {
if (weak) {
// only weak referenced modules don't get an id
// we can always emit an error emitting code here
return this.weakError({
module,
chunkGraph,
request,
type: "expression"
});
}
throw new Error(
`RuntimeTemplate.moduleNamespace(): ${noModuleIdErrorMessage(
module,
chunkGraph
)}`
);
}
const moduleId = this.moduleId({
module,
chunkGraph,
request,
weak
});
const exportsType = module.getExportsType(chunkGraph.moduleGraph, strict);
switch (exportsType) {
case "namespace":
return this.moduleRaw({
module,
chunkGraph,
request,
weak,
runtimeRequirements
});
case "default-with-named":
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 3)`;
case "default-only":
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 1)`;
case "dynamic":
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 7)`;
}
}
/**
* @param {Object} options options object
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {AsyncDependenciesBlock=} options.block the current dependencies block
* @param {Module} options.module the module
* @param {string} options.request the request that should be printed as comment
* @param {string} options.message a message for the comment
* @param {boolean=} options.strict if the current module is in strict esm mode
* @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @returns {string} the promise expression
*/
moduleNamespacePromise({
chunkGraph,
block,
module,
request,
message,
strict,
weak,
runtimeRequirements
}) {
if (!module) {
return this.missingModulePromise({
request
});
}
const moduleId = chunkGraph.getModuleId(module);
if (moduleId === null) {
if (weak) {
// only weak referenced modules don't get an id
// we can always emit an error emitting code here
return this.weakError({
module,
chunkGraph,
request,
type: "promise"
});
}
throw new Error(
`RuntimeTemplate.moduleNamespacePromise(): ${noModuleIdErrorMessage(
module,
chunkGraph
)}`
);
}
const promise = this.blockPromise({
chunkGraph,
block,
message,
runtimeRequirements
});
let appending;
let idExpr = JSON.stringify(chunkGraph.getModuleId(module));
const comment = this.comment({
request
});
let header = "";
if (weak) {
if (idExpr.length > 8) {
// 'var x="nnnnnn";x,"+x+",x' vs '"nnnnnn",nnnnnn,"nnnnnn"'
header += `var id = ${idExpr}; `;
idExpr = "id";
}
runtimeRequirements.add(RuntimeGlobals.moduleFactories);
header += `if(!${
RuntimeGlobals.moduleFactories
}[${idExpr}]) { ${this.weakError({
module,
chunkGraph,
request,
idExpr,
type: "statements"
})} } `;
}
const moduleIdExpr = this.moduleId({
module,
chunkGraph,
request,
weak
});
const exportsType = module.getExportsType(chunkGraph.moduleGraph, strict);
let fakeType = 16;
switch (exportsType) {
case "namespace":
if (header) {
const rawModule = this.moduleRaw({
module,
chunkGraph,
request,
weak,
runtimeRequirements
});
appending = `.then(${this.basicFunction(
"",
`${header}return ${rawModule};`
)})`;
} else {
runtimeRequirements.add(RuntimeGlobals.require);
appending = `.then(__webpack_require__.bind(__webpack_require__, ${comment}${idExpr}))`;
}
break;
case "dynamic":
fakeType |= 4;
/* fall through */
case "default-with-named":
fakeType |= 2;
/* fall through */
case "default-only":
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
if (chunkGraph.moduleGraph.isAsync(module)) {
if (header) {
const rawModule = this.moduleRaw({
module,
chunkGraph,
request,
weak,
runtimeRequirements
});
appending = `.then(${this.basicFunction(
"",
`${header}return ${rawModule};`
)})`;
} else {
runtimeRequirements.add(RuntimeGlobals.require);
appending = `.then(__webpack_require__.bind(__webpack_require__, ${comment}${idExpr}))`;
}
appending += `.then(${this.returningFunction(
`${RuntimeGlobals.createFakeNamespaceObject}(m, ${fakeType})`,
"m"
)})`;
} else {
fakeType |= 1;
if (header) {
const returnExpression = `${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, ${fakeType})`;
appending = `.then(${this.basicFunction(
"",
`${header}return ${returnExpression};`
)})`;
} else {
appending = `.then(${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, ${fakeType}))`;
}
}
break;
}
return `${promise || "Promise.resolve()"}${appending}`;
}
/**
* @param {Object} options options object
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {RuntimeSpec=} options.runtime runtime for which this code will be generated
* @param {RuntimeSpec | boolean=} options.runtimeCondition only execute the statement in some runtimes
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @returns {string} expression
*/
runtimeConditionExpression({
chunkGraph,
runtimeCondition,
runtime,
runtimeRequirements
}) {
if (runtimeCondition === undefined) return "true";
if (typeof runtimeCondition === "boolean") return `${runtimeCondition}`;
/** @type {Set<string>} */
const positiveRuntimeIds = new Set();
forEachRuntime(runtimeCondition, runtime =>
positiveRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`)
);
/** @type {Set<string>} */
const negativeRuntimeIds = new Set();
forEachRuntime(subtractRuntime(runtime, runtimeCondition), runtime =>
negativeRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`)
);
runtimeRequirements.add(RuntimeGlobals.runtimeId);
return compileBooleanMatcher.fromLists(
Array.from(positiveRuntimeIds),
Array.from(negativeRuntimeIds)
)(RuntimeGlobals.runtimeId);
}
/**
*
* @param {Object} options options object
* @param {boolean=} options.update whether a new variable should be created or the existing one updated
* @param {Module} options.module the module
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {string} options.request the request that should be printed as comment
* @param {string} options.importVar name of the import variable
* @param {Module} options.originModule module in which the statement is emitted
* @param {boolean=} options.weak true, if this is a weak dependency
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @returns {[string, string]} the import statement and the compat statement
*/
importStatement({
update,
module,
chunkGraph,
request,
importVar,
originModule,
weak,
runtimeRequirements
}) {
if (!module) {
return [
this.missingModuleStatement({
request
}),
""
];
}
if (chunkGraph.getModuleId(module) === null) {
if (weak) {
// only weak referenced modules don't get an id
// we can always emit an error emitting code here
return [
this.weakError({
module,
chunkGraph,
request,
type: "statements"
}),
""
];
}
throw new Error(
`RuntimeTemplate.importStatement(): ${noModuleIdErrorMessage(
module,
chunkGraph
)}`
);
}
const moduleId = this.moduleId({
module,
chunkGraph,
request,
weak
});
const optDeclaration = update ? "" : "var ";
const exportsType = module.getExportsType(
chunkGraph.moduleGraph,
originModule.buildMeta.strictHarmonyModule
);
runtimeRequirements.add(RuntimeGlobals.require);
const importContent = `/* harmony import */ ${optDeclaration}${importVar} = __webpack_require__(${moduleId});\n`;
if (exportsType === "dynamic") {
runtimeRequirements.add(RuntimeGlobals.compatGetDefaultExport);
return [
importContent,
`/* harmony import */ ${optDeclaration}${importVar}_default = /*#__PURE__*/${RuntimeGlobals.compatGetDefaultExport}(${importVar});\n`
];
}
return [importContent, ""];
}
/**
* @param {Object} options options
* @param {ModuleGraph} options.moduleGraph the module graph
* @param {Module} options.module the module
* @param {string} options.request the request
* @param {string | string[]} options.exportName the export name
* @param {Module} options.originModule the origin module
* @param {boolean|undefined} options.asiSafe true, if location is safe for ASI, a bracket can be emitted
* @param {boolean} options.isCall true, if expression will be called
* @param {boolean} options.callContext when false, call context will not be preserved
* @param {boolean} options.defaultInterop when true and accessing the default exports, interop code will be generated
* @param {string} options.importVar the identifier name of the import variable
* @param {InitFragment[]} options.initFragments init fragments will be added here
* @param {RuntimeSpec} options.runtime runtime for which this code will be generated
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @returns {string} expression
*/
exportFromImport({
moduleGraph,
module,
request,
exportName,
originModule,
asiSafe,
isCall,
callContext,
defaultInterop,
importVar,
initFragments,
runtime,
runtimeRequirements
}) {
if (!module) {
return this.missingModule({
request
});
}
if (!Array.isArray(exportName)) {
exportName = exportName ? [exportName] : [];
}
const exportsType = module.getExportsType(
moduleGraph,
originModule.buildMeta.strictHarmonyModule
);
if (defaultInterop) {
if (exportName.length > 0 && exportName[0] === "default") {
switch (exportsType) {
case "dynamic":
if (isCall) {
return `${importVar}_default()${propertyAccess(exportName, 1)}`;
} else {
return asiSafe
? `(${importVar}_default()${propertyAccess(exportName, 1)})`
: asiSafe === false
? `;(${importVar}_default()${propertyAccess(exportName, 1)})`
: `${importVar}_default.a${propertyAccess(exportName, 1)}`;
}
case "default-only":
case "default-with-named":
exportName = exportName.slice(1);
break;
}
} else if (exportName.length > 0) {
if (exportsType === "default-only") {
return (
"/* non-default import from non-esm module */undefined" +
propertyAccess(exportName, 1)
);
} else if (
exportsType !== "namespace" &&
exportName[0] === "__esModule"
) {
return "/* __esModule */true";
}
} else if (
exportsType === "default-only" ||
exportsType === "default-with-named"
) {
runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
initFragments.push(
new InitFragment(
`var ${importVar}_namespace_cache;\n`,
InitFragment.STAGE_CONSTANTS,
-1,
`${importVar}_namespace_cache`
)
);
return `/*#__PURE__*/ ${
asiSafe ? "" : asiSafe === false ? ";" : "Object"
}(${importVar}_namespace_cache || (${importVar}_namespace_cache = ${
RuntimeGlobals.createFakeNamespaceObject
}(${importVar}${exportsType === "default-only" ? "" : ", 2"})))`;
}
}
if (exportName.length > 0) {
const exportsInfo = moduleGraph.getExportsInfo(module);
const used = exportsInfo.getUsedName(exportName, runtime);
if (!used) {
const comment = Template.toNormalComment(
`unused export ${propertyAccess(exportName)}`
);
return `${comment} undefined`;
}
const comment = equals(used, exportName)
? ""
: Template.toNormalComment(propertyAccess(exportName)) + " ";
const access = `${importVar}${comment}${propertyAccess(used)}`;
if (isCall && callContext === false) {
return asiSafe
? `(0,${access})`
: asiSafe === false
? `;(0,${access})`
: `/*#__PURE__*/Object(${access})`;
}
return access;
} else {
return importVar;
}
}
/**
* @param {Object} options options
* @param {AsyncDependenciesBlock} options.block the async block
* @param {string} options.message the message
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @returns {string} expression
*/
blockPromise({ block, message, chunkGraph, runtimeRequirements }) {
if (!block) {
const comment = this.comment({
message
});
return `Promise.resolve(${comment.trim()})`;
}
const chunkGroup = chunkGraph.getBlockChunkGroup(block);
if (!chunkGroup || chunkGroup.chunks.length === 0) {
const comment = this.comment({
message
});
return `Promise.resolve(${comment.trim()})`;
}
const chunks = chunkGroup.chunks.filter(
chunk => !chunk.hasRuntime() && chunk.id !== null
);
const comment = this.comment({
message,
chunkName: block.chunkName
});
if (chunks.length === 1) {
const chunkId = JSON.stringify(chunks[0].id);
runtimeRequirements.add(RuntimeGlobals.ensureChunk);
return `${RuntimeGlobals.ensureChunk}(${comment}${chunkId})`;
} else if (chunks.length > 0) {
runtimeRequirements.add(RuntimeGlobals.ensureChunk);
const requireChunkId = chunk =>
`${RuntimeGlobals.ensureChunk}(${JSON.stringify(chunk.id)})`;
return `Promise.all(${comment.trim()}[${chunks
.map(requireChunkId)
.join(", ")}])`;
} else {
return `Promise.resolve(${comment.trim()})`;
}
}
/**
* @param {Object} options options
* @param {AsyncDependenciesBlock} options.block the async block
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @param {string=} options.request request string used originally
* @returns {string} expression
*/
asyncModuleFactory({ block, chunkGraph, runtimeRequirements, request }) {
const dep = block.dependencies[0];
const module = chunkGraph.moduleGraph.getModule(dep);
const ensureChunk = this.blockPromise({
block,
message: "",
chunkGraph,
runtimeRequirements
});
const factory = this.returningFunction(
this.moduleRaw({
module,
chunkGraph,
request,
runtimeRequirements
})
);
return this.returningFunction(
ensureChunk.startsWith("Promise.resolve(")
? `${factory}`
: `${ensureChunk}.then(${this.returningFunction(factory)})`
);
}
/**
* @param {Object} options options
* @param {Dependency} options.dependency the dependency
* @param {ChunkGraph} options.chunkGraph the chunk graph
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @param {string=} options.request request string used originally
* @returns {string} expression
*/
syncModuleFactory({ dependency, chunkGraph, runtimeRequirements, request }) {
const module = chunkGraph.moduleGraph.getModule(dependency);
const factory = this.returningFunction(
this.moduleRaw({
module,
chunkGraph,
request,
runtimeRequirements
})
);
return this.returningFunction(factory);
}
/**
* @param {Object} options options
* @param {string} options.exportsArgument the name of the exports object
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
* @returns {string} statement
*/
defineEsModuleFlagStatement({ exportsArgument, runtimeRequirements }) {
runtimeRequirements.add(RuntimeGlobals.makeNamespaceObject);
runtimeRequirements.add(RuntimeGlobals.exports);
return `${RuntimeGlobals.makeNamespaceObject}(${exportsArgument});\n`;
}
/**
* @param {Object} options options object
* @param {Module} options.module the module
* @param {string} options.publicPath the public path
* @param {RuntimeSpec=} options.runtime runtime
* @param {CodeGenerationResults} options.codeGenerationResults the code generation results
* @returns {string} the url of the asset
*/
assetUrl({ publicPath, runtime, module, codeGenerationResults }) {
if (!module) {
return "data:,";
}
const codeGen = codeGenerationResults.get(module, runtime);
const { data } = codeGen;
const url = data.get("url");
if (url) return url.toString();
const filename = data.get("filename");
return publicPath + filename;
}
}
module.exports = RuntimeTemplate;
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042/*MIT License http://www.opensource.org/licenses/mit-license.phpAuthor Tobias Koppers @sokra*/"use strict";const InitFragment = require("./InitFragment");const RuntimeGlobals = require("./RuntimeGlobals");const Template = require("./Template");const { equals } = require("./util/ArrayHelpers");const compileBooleanMatcher = require("./util/compileBooleanMatcher");const propertyAccess = require("./util/propertyAccess");const { forEachRuntime, subtractRuntime } = require("./util/runtime");/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions *//** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock *//** @typedef {import("./ChunkGraph")} ChunkGraph *//** @typedef {import("./CodeGenerationResults")} CodeGenerationResults *//** @typedef {import("./Compilation")} Compilation *//** @typedef {import("./Dependency")} Dependency *//** @typedef {import("./Module")} Module *//** @typedef {import("./ModuleGraph")} ModuleGraph *//** @typedef {import("./RequestShortener")} RequestShortener *//** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec *//*** @param {Module} module the module* @param {ChunkGraph} chunkGraph the chunk graph* @returns {string} error message*/const noModuleIdErrorMessage = (module, chunkGraph) => {return `Module ${module.identifier()} has no id assigned.This should not happen.It's in these chunks: ${Array.from(chunkGraph.getModuleChunksIterable(module),c => c.name || c.id || c.debugId).join(", ") || "none"} (If module is in no chunk this indicates a bug in some chunk/module optimization logic)Module has these incoming connections: ${Array.from(chunkGraph.moduleGraph.getIncomingConnections(module),connection =>`\n - ${connection.originModule && connection.originModule.identifier()} ${connection.dependency && connection.dependency.type} ${(connection.explanations &&Array.from(connection.explanations).join(", ")) ||""}`).join("")}`;};/*** @param {string|undefined} definition global object definition* @returns {string} save to use global object*/function getGlobalObject(definition) {if (!definition) return definition;const trimmed = definition.trim();if (// identifier, we do not need real identifier regarding ECMAScript/Unicodetrimmed.match(/^[_\p{L}][_0-9\p{L}]*$/iu) ||// iife// call expression// expression in parenthesestrimmed.match(/^([_\p{L}][_0-9\p{L}]*)?\(.*\)$/iu))return trimmed;return `Object(${trimmed})`;}class RuntimeTemplate {/*** @param {Compilation} compilation the compilation* @param {OutputOptions} outputOptions the compilation output options* @param {RequestShortener} requestShortener the request shortener*/constructor(compilation, outputOptions, requestShortener) {this.compilation = compilation;this.outputOptions = outputOptions || {};this.requestShortener = requestShortener;this.globalObject = getGlobalObject(outputOptions.globalObject);this.contentHashReplacement = "X".repeat(outputOptions.hashDigestLength);}isIIFE() {return this.outputOptions.iife;}isModule() {return this.outputOptions.module;}supportsConst() {return this.outputOptions.environment.const;}supportsArrowFunction() {return this.outputOptions.environment.arrowFunction;}supportsOptionalChaining() {return this.outputOptions.environment.optionalChaining;}supportsForOf() {return this.outputOptions.environment.forOf;}supportsDestructuring() {return this.outputOptions.environment.destructuring;}supportsBigIntLiteral() {return this.outputOptions.environment.bigIntLiteral;}supportsDynamicImport() {return this.outputOptions.environment.dynamicImport;}supportsEcmaScriptModuleSyntax() {return this.outputOptions.environment.module;}supportTemplateLiteral() {return this.outputOptions.environment.templateLiteral;}returningFunction(returnValue, args = "") {return this.supportsArrowFunction()? `(${args}) => (${returnValue})`: `function(${args}) { return ${returnValue}; }`;}basicFunction(args, body) {return this.supportsArrowFunction()? `(${args}) => {\n${Template.indent(body)}\n}`: `function(${args}) {\n${Template.indent(body)}\n}`;}/*** @param {Array<string|{expr: string}>} args args* @returns {string} result expression*/concatenation(...args) {const len = args.length;if (len === 2) return this._es5Concatenation(args);if (len === 0) return '""';if (len === 1) {return typeof args[0] === "string"? JSON.stringify(args[0]): `"" + ${args[0].expr}`;}if (!this.supportTemplateLiteral()) return this._es5Concatenation(args);// cost comparison between template literal and concatenation:// both need equal surroundings: `xxx` vs "xxx"// template literal has constant cost of 3 chars for each expression// es5 concatenation has cost of 3 + n chars for n expressions in row// when a es5 concatenation ends with an expression it reduces cost by 3// when a es5 concatenation starts with an single expression it reduces cost by 3// e. g. `${a}${b}${c}` (3*3 = 9) is longer than ""+a+b+c ((3+3)-3 = 3)// e. g. `x${a}x${b}x${c}x` (3*3 = 9) is shorter than "x"+a+"x"+b+"x"+c+"x" (4+4+4 = 12)let templateCost = 0;let concatenationCost = 0;let lastWasExpr = false;for (const arg of args) {const isExpr = typeof arg !== "string";if (isExpr) {templateCost += 3;concatenationCost += lastWasExpr ? 1 : 4;}lastWasExpr = isExpr;}if (lastWasExpr) concatenationCost -= 3;if (typeof args[0] !== "string" && typeof args[1] === "string")concatenationCost -= 3;if (concatenationCost <= templateCost) return this._es5Concatenation(args);return `\`${args.map(arg => (typeof arg === "string" ? arg : `\${${arg.expr}}`)).join("")}\``;}/*** @param {Array<string|{expr: string}>} args args (len >= 2)* @returns {string} result expression* @private*/_es5Concatenation(args) {const str = args.map(arg => (typeof arg === "string" ? JSON.stringify(arg) : arg.expr)).join(" + ");// when the first two args are expression, we need to prepend "" + to force string// concatenation instead of number addition.return typeof args[0] !== "string" && typeof args[1] !== "string"? `"" + ${str}`: str;}expressionFunction(expression, args = "") {return this.supportsArrowFunction()? `(${args}) => (${expression})`: `function(${args}) { ${expression}; }`;}emptyFunction() {return this.supportsArrowFunction() ? "x => {}" : "function() {}";}destructureArray(items, value) {return this.supportsDestructuring()? `var [${items.join(", ")}] = ${value};`: Template.asString(items.map((item, i) => `var ${item} = ${value}[${i}];`));}destructureObject(items, value) {return this.supportsDestructuring()? `var {${items.join(", ")}} = ${value};`: Template.asString(items.map(item => `var ${item} = ${value}${propertyAccess([item])};`));}iife(args, body) {return `(${this.basicFunction(args, body)})()`;}forEach(variable, array, body) {return this.supportsForOf()? `for(const ${variable} of ${array}) {\n${Template.indent(body)}\n}`: `${array}.forEach(function(${variable}) {\n${Template.indent(body)}\n});`;}/*** Add a comment* @param {object} options Information content of the comment* @param {string=} options.request request string used originally* @param {string=} options.chunkName name of the chunk referenced* @param {string=} options.chunkReason reason information of the chunk* @param {string=} options.message additional message* @param {string=} options.exportName name of the export* @returns {string} comment*/comment({ request, chunkName, chunkReason, message, exportName }) {let content;if (this.outputOptions.pathinfo) {content = [message, request, chunkName, chunkReason].filter(Boolean).map(item => this.requestShortener.shorten(item)).join(" | ");} else {content = [message, chunkName, chunkReason].filter(Boolean).map(item => this.requestShortener.shorten(item)).join(" | ");}if (!content) return "";if (this.outputOptions.pathinfo) {return Template.toComment(content) + " ";} else {return Template.toNormalComment(content) + " ";}}/*** @param {object} options generation options* @param {string=} options.request request string used originally* @returns {string} generated error block*/throwMissingModuleErrorBlock({ request }) {const err = `Cannot find module '${request}'`;return `var e = new Error(${JSON.stringify(err)}); e.code = 'MODULE_NOT_FOUND'; throw e;`;}/*** @param {object} options generation options* @param {string=} options.request request string used originally* @returns {string} generated error function*/throwMissingModuleErrorFunction({ request }) {return `function webpackMissingModule() { ${this.throwMissingModuleErrorBlock({ request })} }`;}/*** @param {object} options generation options* @param {string=} options.request request string used originally* @returns {string} generated error IIFE*/missingModule({ request }) {return `Object(${this.throwMissingModuleErrorFunction({ request })}())`;}/*** @param {object} options generation options* @param {string=} options.request request string used originally* @returns {string} generated error statement*/missingModuleStatement({ request }) {return `${this.missingModule({ request })};\n`;}/*** @param {object} options generation options* @param {string=} options.request request string used originally* @returns {string} generated error code*/missingModulePromise({ request }) {return `Promise.resolve().then(${this.throwMissingModuleErrorFunction({request})})`;}/*** @param {Object} options options object* @param {ChunkGraph} options.chunkGraph the chunk graph* @param {Module} options.module the module* @param {string} options.request the request that should be printed as comment* @param {string=} options.idExpr expression to use as id expression* @param {"expression" | "promise" | "statements"} options.type which kind of code should be returned* @returns {string} the code*/weakError({ module, chunkGraph, request, idExpr, type }) {const moduleId = chunkGraph.getModuleId(module);const errorMessage =moduleId === null? JSON.stringify("Module is not available (weak dependency)"): idExpr? `"Module '" + ${idExpr} + "' is not available (weak dependency)"`: JSON.stringify(`Module '${moduleId}' is not available (weak dependency)`);const comment = request ? Template.toNormalComment(request) + " " : "";const errorStatements =`var e = new Error(${errorMessage}); ` +comment +"e.code = 'MODULE_NOT_FOUND'; throw e;";switch (type) {case "statements":return errorStatements;case "promise":return `Promise.resolve().then(${this.basicFunction("",errorStatements)})`;case "expression":return this.iife("", errorStatements);}}/*** @param {Object} options options object* @param {Module} options.module the module* @param {ChunkGraph} options.chunkGraph the chunk graph* @param {string} options.request the request that should be printed as comment* @param {boolean=} options.weak if the dependency is weak (will create a nice error message)* @returns {string} the expression*/moduleId({ module, chunkGraph, request, weak }) {if (!module) {return this.missingModule({request});}const moduleId = chunkGraph.getModuleId(module);if (moduleId === null) {if (weak) {return "null /* weak dependency, without id */";}throw new Error(`RuntimeTemplate.moduleId(): ${noModuleIdErrorMessage(module,chunkGraph)}`);}return `${this.comment({ request })}${JSON.stringify(moduleId)}`;}/*** @param {Object} options options object* @param {Module} options.module the module* @param {ChunkGraph} options.chunkGraph the chunk graph* @param {string} options.request the request that should be printed as comment* @param {boolean=} options.weak if the dependency is weak (will create a nice error message)* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements* @returns {string} the expression*/moduleRaw({ module, chunkGraph, request, weak, runtimeRequirements }) {if (!module) {return this.missingModule({request});}const moduleId = chunkGraph.getModuleId(module);if (moduleId === null) {if (weak) {// only weak referenced modules don't get an id// we can always emit an error emitting code herereturn this.weakError({module,chunkGraph,request,type: "expression"});}throw new Error(`RuntimeTemplate.moduleId(): ${noModuleIdErrorMessage(module,chunkGraph)}`);}runtimeRequirements.add(RuntimeGlobals.require);return `__webpack_require__(${this.moduleId({module,chunkGraph,request,weak})})`;}/*** @param {Object} options options object* @param {Module} options.module the module* @param {ChunkGraph} options.chunkGraph the chunk graph* @param {string} options.request the request that should be printed as comment* @param {boolean=} options.weak if the dependency is weak (will create a nice error message)* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements* @returns {string} the expression*/moduleExports({ module, chunkGraph, request, weak, runtimeRequirements }) {return this.moduleRaw({module,chunkGraph,request,weak,runtimeRequirements});}/*** @param {Object} options options object* @param {Module} options.module the module* @param {ChunkGraph} options.chunkGraph the chunk graph* @param {string} options.request the request that should be printed as comment* @param {boolean=} options.strict if the current module is in strict esm mode* @param {boolean=} options.weak if the dependency is weak (will create a nice error message)* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements* @returns {string} the expression*/moduleNamespace({module,chunkGraph,request,strict,weak,runtimeRequirements}) {if (!module) {return this.missingModule({request});}if (chunkGraph.getModuleId(module) === null) {if (weak) {// only weak referenced modules don't get an id// we can always emit an error emitting code herereturn this.weakError({module,chunkGraph,request,type: "expression"});}throw new Error(`RuntimeTemplate.moduleNamespace(): ${noModuleIdErrorMessage(module,chunkGraph)}`);}const moduleId = this.moduleId({module,chunkGraph,request,weak});const exportsType = module.getExportsType(chunkGraph.moduleGraph, strict);switch (exportsType) {case "namespace":return this.moduleRaw({module,chunkGraph,request,weak,runtimeRequirements});case "default-with-named":runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 3)`;case "default-only":runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 1)`;case "dynamic":runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 7)`;}}/*** @param {Object} options options object* @param {ChunkGraph} options.chunkGraph the chunk graph* @param {AsyncDependenciesBlock=} options.block the current dependencies block* @param {Module} options.module the module* @param {string} options.request the request that should be printed as comment* @param {string} options.message a message for the comment* @param {boolean=} options.strict if the current module is in strict esm mode* @param {boolean=} options.weak if the dependency is weak (will create a nice error message)* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements* @returns {string} the promise expression*/moduleNamespacePromise({chunkGraph,block,module,request,message,strict,weak,runtimeRequirements}) {if (!module) {return this.missingModulePromise({request});}const moduleId = chunkGraph.getModuleId(module);if (moduleId === null) {if (weak) {// only weak referenced modules don't get an id// we can always emit an error emitting code herereturn this.weakError({module,chunkGraph,request,type: "promise"});}throw new Error(`RuntimeTemplate.moduleNamespacePromise(): ${noModuleIdErrorMessage(module,chunkGraph)}`);}const promise = this.blockPromise({chunkGraph,block,message,runtimeRequirements});let appending;let idExpr = JSON.stringify(chunkGraph.getModuleId(module));const comment = this.comment({request});let header = "";if (weak) {if (idExpr.length > 8) {// 'var x="nnnnnn";x,"+x+",x' vs '"nnnnnn",nnnnnn,"nnnnnn"'header += `var id = ${idExpr}; `;idExpr = "id";}runtimeRequirements.add(RuntimeGlobals.moduleFactories);header += `if(!${RuntimeGlobals.moduleFactories}[${idExpr}]) { ${this.weakError({module,chunkGraph,request,idExpr,type: "statements"})} } `;}const moduleIdExpr = this.moduleId({module,chunkGraph,request,weak});const exportsType = module.getExportsType(chunkGraph.moduleGraph, strict);let fakeType = 16;switch (exportsType) {case "namespace":if (header) {const rawModule = this.moduleRaw({module,chunkGraph,request,weak,runtimeRequirements});appending = `.then(${this.basicFunction("",`${header}return ${rawModule};`)})`;} else {runtimeRequirements.add(RuntimeGlobals.require);appending = `.then(__webpack_require__.bind(__webpack_require__, ${comment}${idExpr}))`;}break;case "dynamic":fakeType |= 4;/* fall through */case "default-with-named":fakeType |= 2;/* fall through */case "default-only":runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);if (chunkGraph.moduleGraph.isAsync(module)) {if (header) {const rawModule = this.moduleRaw({module,chunkGraph,request,weak,runtimeRequirements});appending = `.then(${this.basicFunction("",`${header}return ${rawModule};`)})`;} else {runtimeRequirements.add(RuntimeGlobals.require);appending = `.then(__webpack_require__.bind(__webpack_require__, ${comment}${idExpr}))`;}appending += `.then(${this.returningFunction(`${RuntimeGlobals.createFakeNamespaceObject}(m, ${fakeType})`,"m")})`;} else {fakeType |= 1;if (header) {const returnExpression = `${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, ${fakeType})`;appending = `.then(${this.basicFunction("",`${header}return ${returnExpression};`)})`;} else {appending = `.then(${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, ${fakeType}))`;}}break;}return `${promise || "Promise.resolve()"}${appending}`;}/*** @param {Object} options options object* @param {ChunkGraph} options.chunkGraph the chunk graph* @param {RuntimeSpec=} options.runtime runtime for which this code will be generated* @param {RuntimeSpec | boolean=} options.runtimeCondition only execute the statement in some runtimes* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements* @returns {string} expression*/runtimeConditionExpression({chunkGraph,runtimeCondition,runtime,runtimeRequirements}) {if (runtimeCondition === undefined) return "true";if (typeof runtimeCondition === "boolean") return `${runtimeCondition}`;/** @type {Set<string>} */const positiveRuntimeIds = new Set();forEachRuntime(runtimeCondition, runtime =>positiveRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`));/** @type {Set<string>} */const negativeRuntimeIds = new Set();forEachRuntime(subtractRuntime(runtime, runtimeCondition), runtime =>negativeRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`));runtimeRequirements.add(RuntimeGlobals.runtimeId);return compileBooleanMatcher.fromLists(Array.from(positiveRuntimeIds),Array.from(negativeRuntimeIds))(RuntimeGlobals.runtimeId);}/**** @param {Object} options options object* @param {boolean=} options.update whether a new variable should be created or the existing one updated* @param {Module} options.module the module* @param {ChunkGraph} options.chunkGraph the chunk graph* @param {string} options.request the request that should be printed as comment* @param {string} options.importVar name of the import variable* @param {Module} options.originModule module in which the statement is emitted* @param {boolean=} options.weak true, if this is a weak dependency* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements* @returns {[string, string]} the import statement and the compat statement*/importStatement({update,module,chunkGraph,request,importVar,originModule,weak,runtimeRequirements}) {if (!module) {return [this.missingModuleStatement({request}),""];}if (chunkGraph.getModuleId(module) === null) {if (weak) {// only weak referenced modules don't get an id// we can always emit an error emitting code herereturn [this.weakError({module,chunkGraph,request,type: "statements"}),""];}throw new Error(`RuntimeTemplate.importStatement(): ${noModuleIdErrorMessage(module,chunkGraph)}`);}const moduleId = this.moduleId({module,chunkGraph,request,weak});const optDeclaration = update ? "" : "var ";const exportsType = module.getExportsType(chunkGraph.moduleGraph,originModule.buildMeta.strictHarmonyModule);runtimeRequirements.add(RuntimeGlobals.require);const importContent = `/* harmony import */ ${optDeclaration}${importVar} = __webpack_require__(${moduleId});\n`;if (exportsType === "dynamic") {runtimeRequirements.add(RuntimeGlobals.compatGetDefaultExport);return [importContent,`/* harmony import */ ${optDeclaration}${importVar}_default = /*#__PURE__*/${RuntimeGlobals.compatGetDefaultExport}(${importVar});\n`];}return [importContent, ""];}/*** @param {Object} options options* @param {ModuleGraph} options.moduleGraph the module graph* @param {Module} options.module the module* @param {string} options.request the request* @param {string | string[]} options.exportName the export name* @param {Module} options.originModule the origin module* @param {boolean|undefined} options.asiSafe true, if location is safe for ASI, a bracket can be emitted* @param {boolean} options.isCall true, if expression will be called* @param {boolean} options.callContext when false, call context will not be preserved* @param {boolean} options.defaultInterop when true and accessing the default exports, interop code will be generated* @param {string} options.importVar the identifier name of the import variable* @param {InitFragment[]} options.initFragments init fragments will be added here* @param {RuntimeSpec} options.runtime runtime for which this code will be generated* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements* @returns {string} expression*/exportFromImport({moduleGraph,module,request,exportName,originModule,asiSafe,isCall,callContext,defaultInterop,importVar,initFragments,runtime,runtimeRequirements}) {if (!module) {return this.missingModule({request});}if (!Array.isArray(exportName)) {exportName = exportName ? [exportName] : [];}const exportsType = module.getExportsType(moduleGraph,originModule.buildMeta.strictHarmonyModule);if (defaultInterop) {if (exportName.length > 0 && exportName[0] === "default") {switch (exportsType) {case "dynamic":if (isCall) {return `${importVar}_default()${propertyAccess(exportName, 1)}`;} else {return asiSafe? `(${importVar}_default()${propertyAccess(exportName, 1)})`: asiSafe === false? `;(${importVar}_default()${propertyAccess(exportName, 1)})`: `${importVar}_default.a${propertyAccess(exportName, 1)}`;}case "default-only":case "default-with-named":exportName = exportName.slice(1);break;}} else if (exportName.length > 0) {if (exportsType === "default-only") {return ("/* non-default import from non-esm module */undefined" +propertyAccess(exportName, 1));} else if (exportsType !== "namespace" &&exportName[0] === "__esModule") {return "/* __esModule */true";}} else if (exportsType === "default-only" ||exportsType === "default-with-named") {runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);initFragments.push(new InitFragment(`var ${importVar}_namespace_cache;\n`,InitFragment.STAGE_CONSTANTS,-1,`${importVar}_namespace_cache`));return `/*#__PURE__*/ ${asiSafe ? "" : asiSafe === false ? ";" : "Object"}(${importVar}_namespace_cache || (${importVar}_namespace_cache = ${RuntimeGlobals.createFakeNamespaceObject}(${importVar}${exportsType === "default-only" ? "" : ", 2"})))`;}}if (exportName.length > 0) {const exportsInfo = moduleGraph.getExportsInfo(module);const used = exportsInfo.getUsedName(exportName, runtime);if (!used) {const comment = Template.toNormalComment(`unused export ${propertyAccess(exportName)}`);return `${comment} undefined`;}const comment = equals(used, exportName)? "": Template.toNormalComment(propertyAccess(exportName)) + " ";const access = `${importVar}${comment}${propertyAccess(used)}`;if (isCall && callContext === false) {return asiSafe? `(0,${access})`: asiSafe === false? `;(0,${access})`: `/*#__PURE__*/Object(${access})`;}return access;} else {return importVar;}}/*** @param {Object} options options* @param {AsyncDependenciesBlock} options.block the async block* @param {string} options.message the message* @param {ChunkGraph} options.chunkGraph the chunk graph* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements* @returns {string} expression*/blockPromise({ block, message, chunkGraph, runtimeRequirements }) {if (!block) {const comment = this.comment({message});return `Promise.resolve(${comment.trim()})`;}const chunkGroup = chunkGraph.getBlockChunkGroup(block);if (!chunkGroup || chunkGroup.chunks.length === 0) {const comment = this.comment({message});return `Promise.resolve(${comment.trim()})`;}const chunks = chunkGroup.chunks.filter(chunk => !chunk.hasRuntime() && chunk.id !== null);const comment = this.comment({message,chunkName: block.chunkName});if (chunks.length === 1) {const chunkId = JSON.stringify(chunks[0].id);runtimeRequirements.add(RuntimeGlobals.ensureChunk);return `${RuntimeGlobals.ensureChunk}(${comment}${chunkId})`;} else if (chunks.length > 0) {runtimeRequirements.add(RuntimeGlobals.ensureChunk);const requireChunkId = chunk =>`${RuntimeGlobals.ensureChunk}(${JSON.stringify(chunk.id)})`;return `Promise.all(${comment.trim()}[${chunks.map(requireChunkId).join(", ")}])`;} else {return `Promise.resolve(${comment.trim()})`;}}/*** @param {Object} options options* @param {AsyncDependenciesBlock} options.block the async block* @param {ChunkGraph} options.chunkGraph the chunk graph* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements* @param {string=} options.request request string used originally* @returns {string} expression*/asyncModuleFactory({ block, chunkGraph, runtimeRequirements, request }) {const dep = block.dependencies[0];const module = chunkGraph.moduleGraph.getModule(dep);const ensureChunk = this.blockPromise({block,message: "",chunkGraph,runtimeRequirements});const factory = this.returningFunction(this.moduleRaw({module,chunkGraph,request,runtimeRequirements}));return this.returningFunction(ensureChunk.startsWith("Promise.resolve(")? `${factory}`: `${ensureChunk}.then(${this.returningFunction(factory)})`);}/*** @param {Object} options options* @param {Dependency} options.dependency the dependency* @param {ChunkGraph} options.chunkGraph the chunk graph* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements* @param {string=} options.request request string used originally* @returns {string} expression*/syncModuleFactory({ dependency, chunkGraph, runtimeRequirements, request }) {const module = chunkGraph.moduleGraph.getModule(dependency);const factory = this.returningFunction(this.moduleRaw({module,chunkGraph,request,runtimeRequirements}));return this.returningFunction(factory);}/*** @param {Object} options options* @param {string} options.exportsArgument the name of the exports object* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements* @returns {string} statement*/defineEsModuleFlagStatement({ exportsArgument, runtimeRequirements }) {runtimeRequirements.add(RuntimeGlobals.makeNamespaceObject);runtimeRequirements.add(RuntimeGlobals.exports);return `${RuntimeGlobals.makeNamespaceObject}(${exportsArgument});\n`;}/*** @param {Object} options options object* @param {Module} options.module the module* @param {string} options.publicPath the public path* @param {RuntimeSpec=} options.runtime runtime* @param {CodeGenerationResults} options.codeGenerationResults the code generation results* @returns {string} the url of the asset*/assetUrl({ publicPath, runtime, module, codeGenerationResults }) {if (!module) {return "data:,";}const codeGen = codeGenerationResults.get(module, runtime);const { data } = codeGen;const url = data.get("url");if (url) return url.toString();const filename = data.get("filename");return publicPath + filename;}}module.exports = RuntimeTemplate;