2 MIT License http://www.opensource.org/licenses/mit-license.php
3 Author Tobias Koppers @sokra
8 const InitFragment = require("./InitFragment");
9 const RuntimeGlobals = require("./RuntimeGlobals");
10 const Template = require("./Template");
11 const { equals } = require("./util/ArrayHelpers");
12 const compileBooleanMatcher = require("./util/compileBooleanMatcher");
13 const propertyAccess = require("./util/propertyAccess");
14 const { forEachRuntime, subtractRuntime } = require("./util/runtime");
16 /** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
17 /** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
18 /** @typedef {import("./ChunkGraph")} ChunkGraph */
19 /** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
20 /** @typedef {import("./Compilation")} Compilation */
21 /** @typedef {import("./Dependency")} Dependency */
22 /** @typedef {import("./Module")} Module */
23 /** @typedef {import("./ModuleGraph")} ModuleGraph */
24 /** @typedef {import("./RequestShortener")} RequestShortener */
25 /** @typedef {import("./util/runtime").RuntimeSpec} RuntimeSpec */
28 * @param {Module} module the module
29 * @param {ChunkGraph} chunkGraph the chunk graph
30 * @returns {string} error message
32 const noModuleIdErrorMessage = (module, chunkGraph) => {
33 return `Module ${module.identifier()} has no id assigned.
34 This should not happen.
35 It's in these chunks: ${
37 chunkGraph.getModuleChunksIterable(module),
38 c => c.name || c.id || c.debugId
39 ).join(", ") || "none"
40 } (If module is in no chunk this indicates a bug in some chunk/module optimization logic)
41 Module has these incoming connections: ${Array.from(
42 chunkGraph.moduleGraph.getIncomingConnections(module),
45 connection.originModule && connection.originModule.identifier()
46 } ${connection.dependency && connection.dependency.type} ${
47 (connection.explanations &&
48 Array.from(connection.explanations).join(", ")) ||
55 * @param {string|undefined} definition global object definition
56 * @returns {string} save to use global object
58 function getGlobalObject(definition) {
59 if (!definition) return definition;
60 const trimmed = definition.trim();
63 // identifier, we do not need real identifier regarding ECMAScript/Unicode
64 trimmed.match(/^[_\p{L}][_0-9\p{L}]*$/iu) ||
67 // expression in parentheses
68 trimmed.match(/^([_\p{L}][_0-9\p{L}]*)?\(.*\)$/iu)
72 return `Object(${trimmed})`;
75 class RuntimeTemplate {
77 * @param {Compilation} compilation the compilation
78 * @param {OutputOptions} outputOptions the compilation output options
79 * @param {RequestShortener} requestShortener the request shortener
81 constructor(compilation, outputOptions, requestShortener) {
82 this.compilation = compilation;
83 this.outputOptions = outputOptions || {};
84 this.requestShortener = requestShortener;
85 this.globalObject = getGlobalObject(outputOptions.globalObject);
86 this.contentHashReplacement = "X".repeat(outputOptions.hashDigestLength);
90 return this.outputOptions.iife;
94 return this.outputOptions.module;
98 return this.outputOptions.environment.const;
101 supportsArrowFunction() {
102 return this.outputOptions.environment.arrowFunction;
105 supportsOptionalChaining() {
106 return this.outputOptions.environment.optionalChaining;
110 return this.outputOptions.environment.forOf;
113 supportsDestructuring() {
114 return this.outputOptions.environment.destructuring;
117 supportsBigIntLiteral() {
118 return this.outputOptions.environment.bigIntLiteral;
121 supportsDynamicImport() {
122 return this.outputOptions.environment.dynamicImport;
125 supportsEcmaScriptModuleSyntax() {
126 return this.outputOptions.environment.module;
129 supportTemplateLiteral() {
130 return this.outputOptions.environment.templateLiteral;
133 returningFunction(returnValue, args = "") {
134 return this.supportsArrowFunction()
135 ? `(${args}) => (${returnValue})`
136 : `function(${args}) { return ${returnValue}; }`;
139 basicFunction(args, body) {
140 return this.supportsArrowFunction()
141 ? `(${args}) => {\n${Template.indent(body)}\n}`
142 : `function(${args}) {\n${Template.indent(body)}\n}`;
146 * @param {Array<string|{expr: string}>} args args
147 * @returns {string} result expression
149 concatenation(...args) {
150 const len = args.length;
152 if (len === 2) return this._es5Concatenation(args);
153 if (len === 0) return '""';
155 return typeof args[0] === "string"
156 ? JSON.stringify(args[0])
157 : `"" + ${args[0].expr}`;
159 if (!this.supportTemplateLiteral()) return this._es5Concatenation(args);
161 // cost comparison between template literal and concatenation:
162 // both need equal surroundings: `xxx` vs "xxx"
163 // template literal has constant cost of 3 chars for each expression
164 // es5 concatenation has cost of 3 + n chars for n expressions in row
165 // when a es5 concatenation ends with an expression it reduces cost by 3
166 // when a es5 concatenation starts with an single expression it reduces cost by 3
167 // e. g. `${a}${b}${c}` (3*3 = 9) is longer than ""+a+b+c ((3+3)-3 = 3)
168 // 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)
170 let templateCost = 0;
171 let concatenationCost = 0;
173 let lastWasExpr = false;
174 for (const arg of args) {
175 const isExpr = typeof arg !== "string";
178 concatenationCost += lastWasExpr ? 1 : 4;
180 lastWasExpr = isExpr;
182 if (lastWasExpr) concatenationCost -= 3;
183 if (typeof args[0] !== "string" && typeof args[1] === "string")
184 concatenationCost -= 3;
186 if (concatenationCost <= templateCost) return this._es5Concatenation(args);
189 .map(arg => (typeof arg === "string" ? arg : `\${${arg.expr}}`))
194 * @param {Array<string|{expr: string}>} args args (len >= 2)
195 * @returns {string} result expression
198 _es5Concatenation(args) {
200 .map(arg => (typeof arg === "string" ? JSON.stringify(arg) : arg.expr))
203 // when the first two args are expression, we need to prepend "" + to force string
204 // concatenation instead of number addition.
205 return typeof args[0] !== "string" && typeof args[1] !== "string"
210 expressionFunction(expression, args = "") {
211 return this.supportsArrowFunction()
212 ? `(${args}) => (${expression})`
213 : `function(${args}) { ${expression}; }`;
217 return this.supportsArrowFunction() ? "x => {}" : "function() {}";
220 destructureArray(items, value) {
221 return this.supportsDestructuring()
222 ? `var [${items.join(", ")}] = ${value};`
224 items.map((item, i) => `var ${item} = ${value}[${i}];`)
228 destructureObject(items, value) {
229 return this.supportsDestructuring()
230 ? `var {${items.join(", ")}} = ${value};`
232 items.map(item => `var ${item} = ${value}${propertyAccess([item])};`)
237 return `(${this.basicFunction(args, body)})()`;
240 forEach(variable, array, body) {
241 return this.supportsForOf()
242 ? `for(const ${variable} of ${array}) {\n${Template.indent(body)}\n}`
243 : `${array}.forEach(function(${variable}) {\n${Template.indent(
250 * @param {object} options Information content of the comment
251 * @param {string=} options.request request string used originally
252 * @param {string=} options.chunkName name of the chunk referenced
253 * @param {string=} options.chunkReason reason information of the chunk
254 * @param {string=} options.message additional message
255 * @param {string=} options.exportName name of the export
256 * @returns {string} comment
258 comment({ request, chunkName, chunkReason, message, exportName }) {
260 if (this.outputOptions.pathinfo) {
261 content = [message, request, chunkName, chunkReason]
263 .map(item => this.requestShortener.shorten(item))
266 content = [message, chunkName, chunkReason]
268 .map(item => this.requestShortener.shorten(item))
271 if (!content) return "";
272 if (this.outputOptions.pathinfo) {
273 return Template.toComment(content) + " ";
275 return Template.toNormalComment(content) + " ";
280 * @param {object} options generation options
281 * @param {string=} options.request request string used originally
282 * @returns {string} generated error block
284 throwMissingModuleErrorBlock({ request }) {
285 const err = `Cannot find module '${request}'`;
286 return `var e = new Error(${JSON.stringify(
288 )}); e.code = 'MODULE_NOT_FOUND'; throw e;`;
292 * @param {object} options generation options
293 * @param {string=} options.request request string used originally
294 * @returns {string} generated error function
296 throwMissingModuleErrorFunction({ request }) {
297 return `function webpackMissingModule() { ${this.throwMissingModuleErrorBlock(
303 * @param {object} options generation options
304 * @param {string=} options.request request string used originally
305 * @returns {string} generated error IIFE
307 missingModule({ request }) {
308 return `Object(${this.throwMissingModuleErrorFunction({ request })}())`;
312 * @param {object} options generation options
313 * @param {string=} options.request request string used originally
314 * @returns {string} generated error statement
316 missingModuleStatement({ request }) {
317 return `${this.missingModule({ request })};\n`;
321 * @param {object} options generation options
322 * @param {string=} options.request request string used originally
323 * @returns {string} generated error code
325 missingModulePromise({ request }) {
326 return `Promise.resolve().then(${this.throwMissingModuleErrorFunction({
332 * @param {Object} options options object
333 * @param {ChunkGraph} options.chunkGraph the chunk graph
334 * @param {Module} options.module the module
335 * @param {string} options.request the request that should be printed as comment
336 * @param {string=} options.idExpr expression to use as id expression
337 * @param {"expression" | "promise" | "statements"} options.type which kind of code should be returned
338 * @returns {string} the code
340 weakError({ module, chunkGraph, request, idExpr, type }) {
341 const moduleId = chunkGraph.getModuleId(module);
344 ? JSON.stringify("Module is not available (weak dependency)")
346 ? `"Module '" + ${idExpr} + "' is not available (weak dependency)"`
348 `Module '${moduleId}' is not available (weak dependency)`
350 const comment = request ? Template.toNormalComment(request) + " " : "";
351 const errorStatements =
352 `var e = new Error(${errorMessage}); ` +
354 "e.code = 'MODULE_NOT_FOUND'; throw e;";
357 return errorStatements;
359 return `Promise.resolve().then(${this.basicFunction(
364 return this.iife("", errorStatements);
369 * @param {Object} options options object
370 * @param {Module} options.module the module
371 * @param {ChunkGraph} options.chunkGraph the chunk graph
372 * @param {string} options.request the request that should be printed as comment
373 * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
374 * @returns {string} the expression
376 moduleId({ module, chunkGraph, request, weak }) {
378 return this.missingModule({
382 const moduleId = chunkGraph.getModuleId(module);
383 if (moduleId === null) {
385 return "null /* weak dependency, without id */";
388 `RuntimeTemplate.moduleId(): ${noModuleIdErrorMessage(
394 return `${this.comment({ request })}${JSON.stringify(moduleId)}`;
398 * @param {Object} options options object
399 * @param {Module} options.module the module
400 * @param {ChunkGraph} options.chunkGraph the chunk graph
401 * @param {string} options.request the request that should be printed as comment
402 * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
403 * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
404 * @returns {string} the expression
406 moduleRaw({ module, chunkGraph, request, weak, runtimeRequirements }) {
408 return this.missingModule({
412 const moduleId = chunkGraph.getModuleId(module);
413 if (moduleId === null) {
415 // only weak referenced modules don't get an id
416 // we can always emit an error emitting code here
417 return this.weakError({
425 `RuntimeTemplate.moduleId(): ${noModuleIdErrorMessage(
431 runtimeRequirements.add(RuntimeGlobals.require);
432 return `__webpack_require__(${this.moduleId({
441 * @param {Object} options options object
442 * @param {Module} options.module the module
443 * @param {ChunkGraph} options.chunkGraph the chunk graph
444 * @param {string} options.request the request that should be printed as comment
445 * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
446 * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
447 * @returns {string} the expression
449 moduleExports({ module, chunkGraph, request, weak, runtimeRequirements }) {
450 return this.moduleRaw({
460 * @param {Object} options options object
461 * @param {Module} options.module the module
462 * @param {ChunkGraph} options.chunkGraph the chunk graph
463 * @param {string} options.request the request that should be printed as comment
464 * @param {boolean=} options.strict if the current module is in strict esm mode
465 * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
466 * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
467 * @returns {string} the expression
478 return this.missingModule({
482 if (chunkGraph.getModuleId(module) === null) {
484 // only weak referenced modules don't get an id
485 // we can always emit an error emitting code here
486 return this.weakError({
494 `RuntimeTemplate.moduleNamespace(): ${noModuleIdErrorMessage(
500 const moduleId = this.moduleId({
506 const exportsType = module.getExportsType(chunkGraph.moduleGraph, strict);
507 switch (exportsType) {
509 return this.moduleRaw({
516 case "default-with-named":
517 runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
518 return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 3)`;
520 runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
521 return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 1)`;
523 runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
524 return `${RuntimeGlobals.createFakeNamespaceObject}(${moduleId}, 7)`;
529 * @param {Object} options options object
530 * @param {ChunkGraph} options.chunkGraph the chunk graph
531 * @param {AsyncDependenciesBlock=} options.block the current dependencies block
532 * @param {Module} options.module the module
533 * @param {string} options.request the request that should be printed as comment
534 * @param {string} options.message a message for the comment
535 * @param {boolean=} options.strict if the current module is in strict esm mode
536 * @param {boolean=} options.weak if the dependency is weak (will create a nice error message)
537 * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
538 * @returns {string} the promise expression
540 moduleNamespacePromise({
551 return this.missingModulePromise({
555 const moduleId = chunkGraph.getModuleId(module);
556 if (moduleId === null) {
558 // only weak referenced modules don't get an id
559 // we can always emit an error emitting code here
560 return this.weakError({
568 `RuntimeTemplate.moduleNamespacePromise(): ${noModuleIdErrorMessage(
574 const promise = this.blockPromise({
582 let idExpr = JSON.stringify(chunkGraph.getModuleId(module));
583 const comment = this.comment({
588 if (idExpr.length > 8) {
589 // 'var x="nnnnnn";x,"+x+",x' vs '"nnnnnn",nnnnnn,"nnnnnn"'
590 header += `var id = ${idExpr}; `;
593 runtimeRequirements.add(RuntimeGlobals.moduleFactories);
595 RuntimeGlobals.moduleFactories
596 }[${idExpr}]) { ${this.weakError({
604 const moduleIdExpr = this.moduleId({
610 const exportsType = module.getExportsType(chunkGraph.moduleGraph, strict);
612 switch (exportsType) {
615 const rawModule = this.moduleRaw({
622 appending = `.then(${this.basicFunction(
624 `${header}return ${rawModule};`
627 runtimeRequirements.add(RuntimeGlobals.require);
628 appending = `.then(__webpack_require__.bind(__webpack_require__, ${comment}${idExpr}))`;
634 case "default-with-named":
638 runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
639 if (chunkGraph.moduleGraph.isAsync(module)) {
641 const rawModule = this.moduleRaw({
648 appending = `.then(${this.basicFunction(
650 `${header}return ${rawModule};`
653 runtimeRequirements.add(RuntimeGlobals.require);
654 appending = `.then(__webpack_require__.bind(__webpack_require__, ${comment}${idExpr}))`;
656 appending += `.then(${this.returningFunction(
657 `${RuntimeGlobals.createFakeNamespaceObject}(m, ${fakeType})`,
663 const returnExpression = `${RuntimeGlobals.createFakeNamespaceObject}(${moduleIdExpr}, ${fakeType})`;
664 appending = `.then(${this.basicFunction(
666 `${header}return ${returnExpression};`
669 appending = `.then(${RuntimeGlobals.createFakeNamespaceObject}.bind(__webpack_require__, ${comment}${idExpr}, ${fakeType}))`;
675 return `${promise || "Promise.resolve()"}${appending}`;
679 * @param {Object} options options object
680 * @param {ChunkGraph} options.chunkGraph the chunk graph
681 * @param {RuntimeSpec=} options.runtime runtime for which this code will be generated
682 * @param {RuntimeSpec | boolean=} options.runtimeCondition only execute the statement in some runtimes
683 * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
684 * @returns {string} expression
686 runtimeConditionExpression({
692 if (runtimeCondition === undefined) return "true";
693 if (typeof runtimeCondition === "boolean") return `${runtimeCondition}`;
694 /** @type {Set<string>} */
695 const positiveRuntimeIds = new Set();
696 forEachRuntime(runtimeCondition, runtime =>
697 positiveRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`)
699 /** @type {Set<string>} */
700 const negativeRuntimeIds = new Set();
701 forEachRuntime(subtractRuntime(runtime, runtimeCondition), runtime =>
702 negativeRuntimeIds.add(`${chunkGraph.getRuntimeId(runtime)}`)
704 runtimeRequirements.add(RuntimeGlobals.runtimeId);
705 return compileBooleanMatcher.fromLists(
706 Array.from(positiveRuntimeIds),
707 Array.from(negativeRuntimeIds)
708 )(RuntimeGlobals.runtimeId);
713 * @param {Object} options options object
714 * @param {boolean=} options.update whether a new variable should be created or the existing one updated
715 * @param {Module} options.module the module
716 * @param {ChunkGraph} options.chunkGraph the chunk graph
717 * @param {string} options.request the request that should be printed as comment
718 * @param {string} options.importVar name of the import variable
719 * @param {Module} options.originModule module in which the statement is emitted
720 * @param {boolean=} options.weak true, if this is a weak dependency
721 * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
722 * @returns {[string, string]} the import statement and the compat statement
736 this.missingModuleStatement({
742 if (chunkGraph.getModuleId(module) === null) {
744 // only weak referenced modules don't get an id
745 // we can always emit an error emitting code here
757 `RuntimeTemplate.importStatement(): ${noModuleIdErrorMessage(
763 const moduleId = this.moduleId({
769 const optDeclaration = update ? "" : "var ";
771 const exportsType = module.getExportsType(
772 chunkGraph.moduleGraph,
773 originModule.buildMeta.strictHarmonyModule
775 runtimeRequirements.add(RuntimeGlobals.require);
776 const importContent = `/* harmony import */ ${optDeclaration}${importVar} = __webpack_require__(${moduleId});\n`;
778 if (exportsType === "dynamic") {
779 runtimeRequirements.add(RuntimeGlobals.compatGetDefaultExport);
782 `/* harmony import */ ${optDeclaration}${importVar}_default = /*#__PURE__*/${RuntimeGlobals.compatGetDefaultExport}(${importVar});\n`
785 return [importContent, ""];
789 * @param {Object} options options
790 * @param {ModuleGraph} options.moduleGraph the module graph
791 * @param {Module} options.module the module
792 * @param {string} options.request the request
793 * @param {string | string[]} options.exportName the export name
794 * @param {Module} options.originModule the origin module
795 * @param {boolean|undefined} options.asiSafe true, if location is safe for ASI, a bracket can be emitted
796 * @param {boolean} options.isCall true, if expression will be called
797 * @param {boolean} options.callContext when false, call context will not be preserved
798 * @param {boolean} options.defaultInterop when true and accessing the default exports, interop code will be generated
799 * @param {string} options.importVar the identifier name of the import variable
800 * @param {InitFragment[]} options.initFragments init fragments will be added here
801 * @param {RuntimeSpec} options.runtime runtime for which this code will be generated
802 * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
803 * @returns {string} expression
821 return this.missingModule({
825 if (!Array.isArray(exportName)) {
826 exportName = exportName ? [exportName] : [];
828 const exportsType = module.getExportsType(
830 originModule.buildMeta.strictHarmonyModule
833 if (defaultInterop) {
834 if (exportName.length > 0 && exportName[0] === "default") {
835 switch (exportsType) {
838 return `${importVar}_default()${propertyAccess(exportName, 1)}`;
841 ? `(${importVar}_default()${propertyAccess(exportName, 1)})`
843 ? `;(${importVar}_default()${propertyAccess(exportName, 1)})`
844 : `${importVar}_default.a${propertyAccess(exportName, 1)}`;
847 case "default-with-named":
848 exportName = exportName.slice(1);
851 } else if (exportName.length > 0) {
852 if (exportsType === "default-only") {
854 "/* non-default import from non-esm module */undefined" +
855 propertyAccess(exportName, 1)
858 exportsType !== "namespace" &&
859 exportName[0] === "__esModule"
861 return "/* __esModule */true";
864 exportsType === "default-only" ||
865 exportsType === "default-with-named"
867 runtimeRequirements.add(RuntimeGlobals.createFakeNamespaceObject);
870 `var ${importVar}_namespace_cache;\n`,
871 InitFragment.STAGE_CONSTANTS,
873 `${importVar}_namespace_cache`
876 return `/*#__PURE__*/ ${
877 asiSafe ? "" : asiSafe === false ? ";" : "Object"
878 }(${importVar}_namespace_cache || (${importVar}_namespace_cache = ${
879 RuntimeGlobals.createFakeNamespaceObject
880 }(${importVar}${exportsType === "default-only" ? "" : ", 2"})))`;
884 if (exportName.length > 0) {
885 const exportsInfo = moduleGraph.getExportsInfo(module);
886 const used = exportsInfo.getUsedName(exportName, runtime);
888 const comment = Template.toNormalComment(
889 `unused export ${propertyAccess(exportName)}`
891 return `${comment} undefined`;
893 const comment = equals(used, exportName)
895 : Template.toNormalComment(propertyAccess(exportName)) + " ";
896 const access = `${importVar}${comment}${propertyAccess(used)}`;
897 if (isCall && callContext === false) {
902 : `/*#__PURE__*/Object(${access})`;
911 * @param {Object} options options
912 * @param {AsyncDependenciesBlock} options.block the async block
913 * @param {string} options.message the message
914 * @param {ChunkGraph} options.chunkGraph the chunk graph
915 * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
916 * @returns {string} expression
918 blockPromise({ block, message, chunkGraph, runtimeRequirements }) {
920 const comment = this.comment({
923 return `Promise.resolve(${comment.trim()})`;
925 const chunkGroup = chunkGraph.getBlockChunkGroup(block);
926 if (!chunkGroup || chunkGroup.chunks.length === 0) {
927 const comment = this.comment({
930 return `Promise.resolve(${comment.trim()})`;
932 const chunks = chunkGroup.chunks.filter(
933 chunk => !chunk.hasRuntime() && chunk.id !== null
935 const comment = this.comment({
937 chunkName: block.chunkName
939 if (chunks.length === 1) {
940 const chunkId = JSON.stringify(chunks[0].id);
941 runtimeRequirements.add(RuntimeGlobals.ensureChunk);
942 return `${RuntimeGlobals.ensureChunk}(${comment}${chunkId})`;
943 } else if (chunks.length > 0) {
944 runtimeRequirements.add(RuntimeGlobals.ensureChunk);
945 const requireChunkId = chunk =>
946 `${RuntimeGlobals.ensureChunk}(${JSON.stringify(chunk.id)})`;
947 return `Promise.all(${comment.trim()}[${chunks
951 return `Promise.resolve(${comment.trim()})`;
956 * @param {Object} options options
957 * @param {AsyncDependenciesBlock} options.block the async block
958 * @param {ChunkGraph} options.chunkGraph the chunk graph
959 * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
960 * @param {string=} options.request request string used originally
961 * @returns {string} expression
963 asyncModuleFactory({ block, chunkGraph, runtimeRequirements, request }) {
964 const dep = block.dependencies[0];
965 const module = chunkGraph.moduleGraph.getModule(dep);
966 const ensureChunk = this.blockPromise({
972 const factory = this.returningFunction(
980 return this.returningFunction(
981 ensureChunk.startsWith("Promise.resolve(")
983 : `${ensureChunk}.then(${this.returningFunction(factory)})`
988 * @param {Object} options options
989 * @param {Dependency} options.dependency the dependency
990 * @param {ChunkGraph} options.chunkGraph the chunk graph
991 * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
992 * @param {string=} options.request request string used originally
993 * @returns {string} expression
995 syncModuleFactory({ dependency, chunkGraph, runtimeRequirements, request }) {
996 const module = chunkGraph.moduleGraph.getModule(dependency);
997 const factory = this.returningFunction(
1005 return this.returningFunction(factory);
1009 * @param {Object} options options
1010 * @param {string} options.exportsArgument the name of the exports object
1011 * @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
1012 * @returns {string} statement
1014 defineEsModuleFlagStatement({ exportsArgument, runtimeRequirements }) {
1015 runtimeRequirements.add(RuntimeGlobals.makeNamespaceObject);
1016 runtimeRequirements.add(RuntimeGlobals.exports);
1017 return `${RuntimeGlobals.makeNamespaceObject}(${exportsArgument});\n`;
1021 * @param {Object} options options object
1022 * @param {Module} options.module the module
1023 * @param {string} options.publicPath the public path
1024 * @param {RuntimeSpec=} options.runtime runtime
1025 * @param {CodeGenerationResults} options.codeGenerationResults the code generation results
1026 * @returns {string} the url of the asset
1028 assetUrl({ publicPath, runtime, module, codeGenerationResults }) {
1032 const codeGen = codeGenerationResults.get(module, runtime);
1033 const { data } = codeGen;
1034 const url = data.get("url");
1035 if (url) return url.toString();
1036 const filename = data.get("filename");
1037 return publicPath + filename;
1041 module.exports = RuntimeTemplate;