Skip to content

Commit

Permalink
improve TLA consistency
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Jan 29, 2021
1 parent 8ce54a0 commit 495cabb
Show file tree
Hide file tree
Showing 39 changed files with 728 additions and 323 deletions.
14 changes: 14 additions & 0 deletions lib/RuntimeGlobals.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,17 @@ exports.systemContext = "__webpack_require__.y";
* the baseURI of current document
*/
exports.baseURI = "__webpack_require__.b";

/**
* Creates an async module. The body function must be a async function.
* "module.exports" will be decorated with an AsyncModulePromise.
* The body function will be called.
* To handle async dependencies correctly do this: "([a, b, c] = await handleDependencies([a, b, c]));".
* If "hasAwaitAfterDependencies" is truthy, "handleDependencies()" must be called at the end of the body function.
* Signature: function(
* module: Module,
* body: (handleDependencies: (deps: AsyncModulePromise[]) => Promise<any[]> & () => void,
* hasAwaitAfterDependencies?: boolean
* ) => void
*/
exports.asyncModule = "__webpack_require__.a";
8 changes: 8 additions & 0 deletions lib/RuntimePlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
const RuntimeGlobals = require("./RuntimeGlobals");
const RuntimeRequirementsDependency = require("./dependencies/RuntimeRequirementsDependency");
const JavascriptModulesPlugin = require("./javascript/JavascriptModulesPlugin");
const AsyncModuleRuntimeModule = require("./runtime/AsyncModuleRuntimeModule");
const AutoPublicPathRuntimeModule = require("./runtime/AutoPublicPathRuntimeModule");
const CompatGetDefaultExportRuntimeModule = require("./runtime/CompatGetDefaultExportRuntimeModule");
const CompatRuntimeModule = require("./runtime/CompatRuntimeModule");
Expand Down Expand Up @@ -48,6 +49,7 @@ const GLOBALS_ON_REQUIRE = [
RuntimeGlobals.publicPath,
RuntimeGlobals.scriptNonce,
RuntimeGlobals.uncaughtErrorHandler,
RuntimeGlobals.asyncModule,
RuntimeGlobals.wasmInstances,
RuntimeGlobals.instantiateWasm,
RuntimeGlobals.shareScopeMap,
Expand Down Expand Up @@ -194,6 +196,12 @@ class RuntimePlugin {
compilation.addRuntimeModule(chunk, new GlobalRuntimeModule());
return true;
});
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.asyncModule)
.tap("RuntimePlugin", chunk => {
compilation.addRuntimeModule(chunk, new AsyncModuleRuntimeModule());
return true;
});
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.systemContext)
.tap("RuntimePlugin", chunk => {
Expand Down
2 changes: 1 addition & 1 deletion lib/RuntimeTemplate.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class RuntimeTemplate {

returningFunction(returnValue, args = "") {
return this.supportsArrowFunction()
? `(${args}) => ${returnValue}`
? `(${args}) => (${returnValue})`
: `function(${args}) { return ${returnValue}; }`;
}

Expand Down
14 changes: 12 additions & 2 deletions lib/async-modules/AwaitDependenciesInitFragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

const InitFragment = require("../InitFragment");
const RuntimeGlobals = require("../RuntimeGlobals");
const Template = require("../Template");

/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
Expand Down Expand Up @@ -45,11 +46,20 @@ class AwaitDependenciesInitFragment extends InitFragment {
}
if (promises.size === 1) {
for (const p of promises) {
return `${p} = await Promise.resolve(${p});\n`;
return Template.asString([
`var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${p}]);`,
`${p} = (__webpack_async_dependencies__.then ? await __webpack_async_dependencies__ : __webpack_async_dependencies__)[0];`,
""
]);
}
}
const sepPromises = Array.from(promises).join(", ");
return `([${sepPromises}] = await Promise.all([${sepPromises}]));\n`;
// TODO check if destructuring is supported
return Template.asString([
`var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${sepPromises}]);`,
`([${sepPromises}] = __webpack_async_dependencies__.then ? await __webpack_async_dependencies__ : __webpack_async_dependencies__);`,
""
]);
}
}

Expand Down
9 changes: 5 additions & 4 deletions lib/dependencies/HarmonyCompatibilityDependency.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,16 @@ HarmonyCompatibilityDependency.Template = class HarmonyExportDependencyTemplate
}
if (moduleGraph.isAsync(module)) {
runtimeRequirements.add(RuntimeGlobals.module);
const used = exportsInfo.isUsed(runtime);
if (used) runtimeRequirements.add(RuntimeGlobals.exports);
runtimeRequirements.add(RuntimeGlobals.asyncModule);
initFragments.push(
new InitFragment(
`${module.moduleArgument}.exports = (async () => {\n`,
`${RuntimeGlobals.asyncModule}(${module.moduleArgument}, async (__webpack_handle_async_dependencies__) => {\n`,
InitFragment.STAGE_ASYNC_BOUNDARY,
0,
undefined,
used ? `\nreturn ${module.exportsArgument};\n})();` : "\n})();"
module.buildMeta.async
? `\n__webpack_handle_async_dependencies__();\n}, 1);`
: "\n});"
)
);
}
Expand Down
137 changes: 137 additions & 0 deletions lib/runtime/AsyncModuleRuntimeModule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
*/

"use strict";

const RuntimeGlobals = require("../RuntimeGlobals");
const Template = require("../Template");
const HelperRuntimeModule = require("./HelperRuntimeModule");

class AsyncModuleRuntimeModule extends HelperRuntimeModule {
constructor() {
super("async module");
}

/**
* @returns {string} runtime code
*/
generate() {
const { runtimeTemplate } = this.compilation;
const fn = RuntimeGlobals.asyncModule;
return Template.asString([
'var webpackThen = typeof Symbol === "function" ? Symbol("webpack then") : "__webpack_then__";',
'var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__";',
`var completeQueue = ${runtimeTemplate.basicFunction("queue", [
"if(queue) {",
Template.indent(
runtimeTemplate.supportsArrowFunction()
? [
"queue.forEach(fn => fn.r--);",
"queue.forEach(fn => fn.r-- ? fn.r++ : fn());"
]
: [
"queue.forEach(function(fn) { fn.r--; });",
"queue.forEach(function(fn) { fn.r-- ? fn.r++ : fn(); });"
]
),
"}"
])}`,
`var completeFunction = ${
runtimeTemplate.supportsArrowFunction()
? "fn => !--fn.r && fn()"
: "function(fn) { !--fn.r && fn(); }"
};`,
`var queueFunction = ${
runtimeTemplate.supportsArrowFunction()
? "(queue, fn) => queue ? queue.push(fn) : completeFunction(fn)"
: "function(queue, fn) { queue ? queue.push(fn) : completeFunction(fn); }"
};`,
`var wrapDeps = ${runtimeTemplate.returningFunction(
`deps.map(${runtimeTemplate.basicFunction("dep", [
'if(dep !== null && typeof dep === "object") {',
Template.indent([
"if(dep[webpackThen]) return dep;",
"if(dep.then) {",
Template.indent([
"var queue = [], result;",
`dep.then(${runtimeTemplate.basicFunction("r", [
"obj[webpackExports] = r;",
"completeQueue(queue);",
"queue = 0;"
])});`,
"var obj = { [webpackThen]: (fn, reject) => { queueFunction(queue, fn); dep.catch(reject); } };",
"return obj;"
]),
"}"
]),
"}",
"return { [webpackThen]: (fn) => { completeFunction(fn); }, [webpackExports]: dep };"
])})`,
"deps"
)};`,
`${fn} = ${runtimeTemplate.basicFunction("module, body, hasAwait", [
"var queue = hasAwait && [];",
"var exports = module.exports;",
"var currentDeps;",
"var outerResolve;",
"var reject;",
"var isEvaluating = true;",
"var nested = false;",
`var whenAll = ${runtimeTemplate.basicFunction(
"deps, onResolve, onReject",
[
"if (nested) return;",
"nested = true;",
"onResolve.r += deps.length;",
`deps.map(${runtimeTemplate.basicFunction("dep, i", [
"dep[webpackThen](onResolve, onReject);"
])});`,
"nested = false;"
]
)};`,
`var promise = new Promise(${runtimeTemplate.basicFunction(
"resolve, rej",
[
"reject = rej;",
`outerResolve = ${runtimeTemplate.basicFunction("", [
"resolve(exports);",
"completeQueue(queue);",
"queue = 0;"
])};`
]
)});`,
"promise[webpackExports] = exports;",
`promise[webpackThen] = ${runtimeTemplate.basicFunction(
"fn, rejectFn",
[
"if (isEvaluating) { return completeFunction(fn); }",
"if (currentDeps) whenAll(currentDeps, fn, rejectFn);",
"queueFunction(queue, fn);",
"promise.catch(rejectFn);"
]
)};`,
"module.exports = promise;",
`body(${runtimeTemplate.basicFunction("deps", [
"if(!deps) return outerResolve();",
"currentDeps = wrapDeps(deps);",
"var fn, result;",
`var promise = new Promise(${runtimeTemplate.basicFunction(
"resolve, reject",
[
`fn = ${runtimeTemplate.returningFunction(
"resolve(result = currentDeps.map(d => d[webpackExports]))"
)}`,
"fn.r = 0;",
"whenAll(currentDeps, fn, reject);"
]
)});`,
"return fn.r ? promise : result;"
])}).then(outerResolve, reject);`,
"isEvaluating = false;"
])};`
]);
}
}

module.exports = AsyncModuleRuntimeModule;
2 changes: 1 addition & 1 deletion lib/sharing/ShareRuntimeModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class ShareRuntimeModule extends RuntimeModule {
"// runs all init snippets from all modules reachable",
`var scope = ${RuntimeGlobals.shareScopeMap}[name];`,
`var warn = ${runtimeTemplate.returningFunction(
'typeof console !== "undefined" && console.warn && console.warn(msg);',
'typeof console !== "undefined" && console.warn && console.warn(msg)',
"msg"
)};`,
`var uniqueName = ${JSON.stringify(uniqueName || undefined)};`,
Expand Down
46 changes: 24 additions & 22 deletions lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,30 +155,32 @@ class AsyncWebAssemblyJavascriptGenerator extends Generator {
chunkGraph.getRenderedModuleHash(module, runtime)
)}` + (importsObj ? `, ${importsObj})` : `)`);

if (promises.length > 0)
runtimeRequirements.add(RuntimeGlobals.asyncModule);

const source = new RawSource(
`${importsCode}${
promises.length > 1
? Template.asString([
`${module.moduleArgument}.exports = Promise.all([${promises.join(
", "
)}]).then(${runtimeTemplate.basicFunction(
`[${promises.join(", ")}]`,
`${importsCompatCode}return ${instantiateCall};`
)})`
])
: promises.length === 1
? Template.asString([
`${module.moduleArgument}.exports = Promise.resolve(${
promises[0]
}).then(${runtimeTemplate.basicFunction(
promises[0],
`${importsCompatCode}return ${instantiateCall};`
)})`
])
: `${importsCompatCode}${module.moduleArgument}.exports = ${instantiateCall}`
}`
promises.length > 0
? Template.asString([
`var __webpack_instantiate__ = ${runtimeTemplate.basicFunction(
`[${promises.join(", ")}]`,
`${importsCompatCode}return ${instantiateCall};`
)}`,
`${RuntimeGlobals.asyncModule}(${
module.moduleArgument
}, ${runtimeTemplate.basicFunction(
"__webpack_handle_async_dependencies__",
[
importsCode,
`var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([${promises.join(
", "
)}]);`,
"return __webpack_async_dependencies__.then ? __webpack_async_dependencies__.then(__webpack_instantiate__) : __webpack_instantiate__(__webpack_async_dependencies__);"
]
)}, 1);`
])
: `${importsCode}${importsCompatCode}module.exports = ${instantiateCall};`
);

return InitFragment.addToSource(source, initFragments, generateContext);
}
}
Expand Down
Loading

0 comments on commit 495cabb

Please sign in to comment.