123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- */
- "use strict";
- const RuntimeGlobals = require("../RuntimeGlobals");
- const Template = require("../Template");
- const HelperRuntimeModule = require("./HelperRuntimeModule");
- /** @typedef {import("../Compilation")} Compilation */
- class AsyncModuleRuntimeModule extends HelperRuntimeModule {
- /**
- * @param {boolean=} deferInterop if defer import is used.
- */
- constructor(deferInterop = false) {
- super("async module");
- this._deferInterop = deferInterop;
- }
- /**
- * @returns {string | null} runtime code
- */
- generate() {
- const compilation = /** @type {Compilation} */ (this.compilation);
- const { runtimeTemplate } = compilation;
- const fn = RuntimeGlobals.asyncModule;
- const defer = this._deferInterop;
- return Template.asString([
- 'var hasSymbol = typeof Symbol === "function";',
- 'var webpackQueues = hasSymbol ? Symbol("webpack queues") : "__webpack_queues__";',
- `var webpackExports = ${
- defer ? `${RuntimeGlobals.asyncModuleExportSymbol}= ` : ""
- }hasSymbol ? Symbol("webpack exports") : "${RuntimeGlobals.exports}";`,
- 'var webpackError = hasSymbol ? Symbol("webpack error") : "__webpack_error__";',
- defer
- ? `var webpackDone = ${RuntimeGlobals.asyncModuleDoneSymbol} = hasSymbol ? Symbol("webpack done") : "__webpack_done__";`
- : "",
- defer
- ? `var webpackDefer = ${RuntimeGlobals.makeDeferredNamespaceObjectSymbol} = hasSymbol ? Symbol("webpack defer") : "__webpack_defer__";`
- : "",
- `var resolveQueue = ${runtimeTemplate.basicFunction("queue", [
- "if(queue && queue.d < 1) {",
- Template.indent([
- "queue.d = 1;",
- `queue.forEach(${runtimeTemplate.expressionFunction(
- "fn.r--",
- "fn"
- )});`,
- `queue.forEach(${runtimeTemplate.expressionFunction(
- "fn.r-- ? fn.r++ : fn()",
- "fn"
- )});`
- ]),
- "}"
- ])}`,
- `var wrapDeps = ${runtimeTemplate.returningFunction(
- `deps.map(${runtimeTemplate.basicFunction("dep", [
- 'if(dep !== null && typeof dep === "object") {',
- Template.indent([
- defer
- ? Template.asString([
- "if(!dep[webpackQueues] && dep[webpackDefer]) {",
- Template.indent([
- "var asyncDeps = dep[webpackDefer];",
- `var hasUnresolvedAsyncSubgraph = asyncDeps.some(${runtimeTemplate.basicFunction(
- "id",
- [
- "var cache = __webpack_module_cache__[id];",
- "return !cache || cache[webpackDone] === false;"
- ]
- )});`,
- "if (hasUnresolvedAsyncSubgraph) {",
- Template.indent([
- "var d = dep;",
- "dep = {",
- Template.indent([
- "then(callback) {",
- Template.indent([
- "Promise.all(asyncDeps.map(__webpack_require__))",
- `.then(${runtimeTemplate.returningFunction(
- "callback(d)"
- )});`
- ]),
- "}"
- ]),
- "};"
- ]),
- "} else return dep;"
- ]),
- "}"
- ])
- : "",
- "if(dep[webpackQueues]) return dep;",
- "if(dep.then) {",
- Template.indent([
- "var queue = [];",
- "queue.d = 0;",
- `dep.then(${runtimeTemplate.basicFunction("r", [
- "obj[webpackExports] = r;",
- "resolveQueue(queue);"
- ])}, ${runtimeTemplate.basicFunction("e", [
- "obj[webpackError] = e;",
- "resolveQueue(queue);"
- ])});`,
- "var obj = {};",
- defer ? "obj[webpackDefer] = false;" : "",
- `obj[webpackQueues] = ${runtimeTemplate.expressionFunction(
- "fn(queue)",
- "fn"
- )};`,
- "return obj;"
- ]),
- "}"
- ]),
- "}",
- "var ret = {};",
- `ret[webpackQueues] = ${runtimeTemplate.emptyFunction()};`,
- "ret[webpackExports] = dep;",
- "return ret;"
- ])})`,
- "deps"
- )};`,
- `${fn} = ${runtimeTemplate.basicFunction("module, body, hasAwait", [
- "var queue;",
- "hasAwait && ((queue = []).d = -1);",
- "var depQueues = new Set();",
- "var exports = module.exports;",
- "var currentDeps;",
- "var outerResolve;",
- "var reject;",
- `var promise = new Promise(${runtimeTemplate.basicFunction(
- "resolve, rej",
- ["reject = rej;", "outerResolve = resolve;"]
- )});`,
- "promise[webpackExports] = exports;",
- `promise[webpackQueues] = ${runtimeTemplate.expressionFunction(
- `queue && fn(queue), depQueues.forEach(fn), promise["catch"](${runtimeTemplate.emptyFunction()})`,
- "fn"
- )};`,
- "module.exports = promise;",
- `var handle = ${runtimeTemplate.basicFunction("deps", [
- "currentDeps = wrapDeps(deps);",
- "var fn;",
- `var getResult = ${runtimeTemplate.returningFunction(
- `currentDeps.map(${runtimeTemplate.basicFunction("d", [
- defer ? "if(d[webpackDefer]) return d;" : "",
- "if(d[webpackError]) throw d[webpackError];",
- "return d[webpackExports];"
- ])})`
- )}`,
- `var promise = new Promise(${runtimeTemplate.basicFunction(
- "resolve",
- [
- `fn = ${runtimeTemplate.expressionFunction(
- "resolve(getResult)",
- ""
- )};`,
- "fn.r = 0;",
- `var fnQueue = ${runtimeTemplate.expressionFunction(
- "q !== queue && !depQueues.has(q) && (depQueues.add(q), q && !q.d && (fn.r++, q.push(fn)))",
- "q"
- )};`,
- `currentDeps.map(${runtimeTemplate.expressionFunction(
- `${
- defer ? "dep[webpackDefer]||" : ""
- }dep[webpackQueues](fnQueue)`,
- "dep"
- )});`
- ]
- )});`,
- "return fn.r ? promise : getResult();"
- ])}`,
- `var done = ${runtimeTemplate.expressionFunction(
- `(err ? reject(promise[webpackError] = err) : outerResolve(exports)), resolveQueue(queue)${
- defer ? ", promise[webpackDone] = true" : ""
- }`,
- "err"
- )}`,
- "body(handle, done);",
- "queue && queue.d < 0 && (queue.d = 0);"
- ])};`
- ]);
- }
- }
- module.exports = AsyncModuleRuntimeModule;
|