189 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
| 	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;
 |