Skip to content

Commit

Permalink
add experiments.executeModule
Browse files Browse the repository at this point in the history
rename runModule -> executeModule
improve error reporting
  • Loading branch information
sokra committed Apr 12, 2021
1 parent 0a9041e commit ea3e0a3
Show file tree
Hide file tree
Showing 11 changed files with 198 additions and 131 deletions.
4 changes: 4 additions & 0 deletions declarations/WebpackOptions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,10 @@ export interface Experiments {
* Support WebAssembly as asynchronous EcmaScript Module.
*/
asyncWebAssembly?: boolean;
/**
* Enable build-time execution of modules from the module graph for plugins and loaders.
*/
executeModule?: boolean;
/**
* Enable module and chunk layers.
*/
Expand Down
66 changes: 49 additions & 17 deletions lib/Compilation.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ const { isSourceEqual } = require("./util/source");
*/

/**
* @callback RunModuleCallback
* @callback ExecuteModuleCallback
* @param {WebpackError=} err
* @param {RunModuleResult=} result
* @param {ExecuteModuleResult=} result
* @returns {void}
*/

Expand Down Expand Up @@ -176,12 +176,12 @@ const { isSourceEqual } = require("./util/source");
*/

/**
* @typedef {Object} RunModuleOptions
* @typedef {Object} ExecuteModuleOptions
* @property {EntryOptions=} entryOptions
*/

/**
* @typedef {Object} RunModuleResult
* @typedef {Object} ExecuteModuleResult
* @property {any} exports
* @property {Map<string, { source: Source, info: AssetInfo }>} assets
* @property {LazySet<string>} fileDependencies
Expand All @@ -191,14 +191,14 @@ const { isSourceEqual } = require("./util/source");
*/

/**
* @typedef {Object} RunModuleArgument
* @typedef {Object} ExecuteModuleArgument
* @property {Module} module
* @property {object} moduleObject
* @property {CodeGenerationResult} codeGenerationResult
*/

/**
* @typedef {Object} RunModuleContext
* @typedef {Object} ExecuteModuleContext
* @property {Map<string, { source: Source, info: AssetInfo }>} assets
* @property {Chunk} chunk
* @property {ChunkGraph} chunkGraph
Expand Down Expand Up @@ -572,8 +572,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
"runtime"
]),

/** @type {SyncHook<[RunModuleArgument, RunModuleContext]>} */
runModule: new SyncHook(["options", "context"]),
/** @type {SyncHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */
executeModule: new SyncHook(["options", "context"]),

/** @type {AsyncSeriesHook<[Iterable<Module>]>} */
finishModules: new AsyncSeriesHook(["modules"]),
Expand Down Expand Up @@ -877,6 +877,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
});

this.moduleGraph = new ModuleGraph();
/** @type {ChunkGraph} */
this.chunkGraph = undefined;
/** @type {CodeGenerationResults} */
this.codeGenerationResults = undefined;
Expand Down Expand Up @@ -3970,15 +3971,21 @@ This prevents using hashes of each other and should be avoided.`);

/**
* @param {Module} module the module
* @param {RunModuleOptions} options options
* @param {RunModuleCallback} callback callback
* @param {ExecuteModuleOptions} options options
* @param {ExecuteModuleCallback} callback callback
*/
runModule(module, options, callback) {
executeModule(module, options, callback) {
// Aggregate all referenced modules and ensure they are ready
const modules = new Set([module]);
processAsyncTree(
modules,
10,
/**
* @param {Module} module the module
* @param {function(Module): void} push push more jobs
* @param {Callback} callback callback
* @returns {void}
*/
(module, push, callback) => {
this.addModuleQueue.waitFor(module, err => {
if (err) return callback(err);
Expand All @@ -3999,7 +4006,7 @@ This prevents using hashes of each other and should be avoided.`);
});
},
err => {
if (err) return callback(makeWebpackError(err, "runModule"));
if (err) return callback(err);

// Create new chunk graph, chunk and entrypoint for the build time execution
const chunkGraph = new ChunkGraph(this.moduleGraph);
Expand Down Expand Up @@ -4027,6 +4034,7 @@ This prevents using hashes of each other and should be avoided.`);

const chunks = new Set([chunk]);

/** @type {Map<string, Module>} */
const modulesById = new Map();

// Assign ids to modules and modules to the chunk
Expand All @@ -4053,6 +4061,11 @@ This prevents using hashes of each other and should be avoided.`);
const codeGenerationResults = new CodeGenerationResults();
/** @type {WebpackError[]} */
const errors = [];
/**
* @param {Module} module the module
* @param {Callback} callback callback
* @returns {void}
*/
const codeGen = (module, callback) => {
this._codeGenerationModule(
module,
Expand All @@ -4071,9 +4084,22 @@ This prevents using hashes of each other and should be avoided.`);
);
};

const reportErrors = () => {
if (errors.length > 0) {
errors.sort(
compareSelect(err => err.module, compareModulesByIdentifier)
);
for (const error of errors) {
this.errors.push(error);
}
errors.length = 0;
}
};

// Generate code for all aggregated modules
asyncLib.eachLimit(modules, 10, codeGen, err => {
if (err) return callback(makeWebpackError(err, "runModule"));
if (err) return callback(err);
reportErrors();

// for backward-compat temporary set the chunk graph
// TODO webpack 6
Expand Down Expand Up @@ -4107,13 +4133,19 @@ This prevents using hashes of each other and should be avoided.`);

// Generate code for all runtime modules
asyncLib.eachLimit(runtimeModules, 10, codeGen, err => {
if (err) return callback(makeWebpackError(err, "runModule"));
if (err) return callback(err);
reportErrors();

let exports;
/** @type {ExecuteModuleResult["fileDependencies"]} */
const fileDependencies = new LazySet();
/** @type {ExecuteModuleResult["contextDependencies"]} */
const contextDependencies = new LazySet();
/** @type {ExecuteModuleResult["missingDependencies"]} */
const missingDependencies = new LazySet();
/** @type {ExecuteModuleResult["buildDependencies"]} */
const buildDependencies = new LazySet();
/** @type {ExecuteModuleResult["assets"]} */
const assets = new Map();
try {
const {
Expand Down Expand Up @@ -4158,15 +4190,15 @@ This prevents using hashes of each other and should be avoided.`);
);
tryRunOrWebpackError(
() =>
this.hooks.runModule.call(
this.hooks.executeModule.call(
{
codeGenerationResult,
module,
moduleObject
},
context
),
"Compilation.hooks.runModule"
"Compilation.hooks.executeModule"
);
moduleObject.loaded = true;
return moduleObject.exports;
Expand All @@ -4181,7 +4213,7 @@ This prevents using hashes of each other and should be avoided.`);
}
};

/** @type {RunModuleContext} */
/** @type {ExecuteModuleContext} */
const context = {
assets,
__webpack_require__,
Expand Down
4 changes: 3 additions & 1 deletion lib/WebpackOptionsApply.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,9 @@ class WebpackOptionsApply extends OptionsApply {
new RequireJsStuffPlugin().apply(compiler);
}
new CommonJsPlugin().apply(compiler);
new LoaderPlugin().apply(compiler);
new LoaderPlugin({
enableExecuteModule: options.experiments.executeModule
}).apply(compiler);
if (options.node !== false) {
const NodeStuffPlugin = require("./NodeStuffPlugin");
new NodeStuffPlugin(options.node).apply(compiler);
Expand Down
2 changes: 1 addition & 1 deletion lib/asset/AssetModulesPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ class AssetModulesPlugin {
return result;
});

compilation.hooks.runModule.tap(
compilation.hooks.executeModule.tap(
"AssetModulesPlugin",
(options, context) => {
const { codeGenerationResult } = options;
Expand Down

0 comments on commit ea3e0a3

Please sign in to comment.