mirror of https://github.com/webpack/webpack.git
Merge pull request #13102 from webpack/feature/built-time-execution
This commit is contained in:
commit
03961f3391
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const WebpackError = require("./WebpackError");
|
|||
* @returns {Module[]} sorted version of original modules
|
||||
*/
|
||||
const sortModules = modules => {
|
||||
return modules.slice().sort((a, b) => {
|
||||
return modules.sort((a, b) => {
|
||||
const aIdent = a.identifier();
|
||||
const bIdent = b.identifier();
|
||||
/* istanbul ignore next */
|
||||
|
|
@ -52,11 +52,11 @@ const createModulesListMessage = (modules, moduleGraph) => {
|
|||
class CaseSensitiveModulesWarning extends WebpackError {
|
||||
/**
|
||||
* Creates an instance of CaseSensitiveModulesWarning.
|
||||
* @param {Module[]} modules modules that were detected
|
||||
* @param {Iterable<Module>} modules modules that were detected
|
||||
* @param {ModuleGraph} moduleGraph the module graph
|
||||
*/
|
||||
constructor(modules, moduleGraph) {
|
||||
const sortedModules = sortModules(modules);
|
||||
const sortedModules = sortModules(Array.from(modules));
|
||||
const modulesList = createModulesListMessage(sortedModules, moduleGraph);
|
||||
super(`There are multiple modules with names that only differ in casing.
|
||||
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,10 @@ const {
|
|||
connectChunkGroupAndChunk,
|
||||
connectChunkGroupParentAndChild
|
||||
} = require("./GraphHelpers");
|
||||
const { makeWebpackError } = require("./HookWebpackError");
|
||||
const {
|
||||
makeWebpackError,
|
||||
tryRunOrWebpackError
|
||||
} = require("./HookWebpackError");
|
||||
const MainTemplate = require("./MainTemplate");
|
||||
const Module = require("./Module");
|
||||
const ModuleDependencyError = require("./ModuleDependencyError");
|
||||
|
|
@ -71,6 +74,7 @@ const {
|
|||
soonFrozenObjectDeprecation,
|
||||
createFakeHook
|
||||
} = require("./util/deprecation");
|
||||
const processAsyncTree = require("./util/processAsyncTree");
|
||||
const { getRuntimeKey } = require("./util/runtime");
|
||||
const { isSourceEqual } = require("./util/source");
|
||||
|
||||
|
|
@ -119,6 +123,13 @@ const { isSourceEqual } = require("./util/source");
|
|||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback ExecuteModuleCallback
|
||||
* @param {WebpackError=} err
|
||||
* @param {ExecuteModuleResult=} result
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback DepBlockVarDependenciesCallback
|
||||
* @param {Dependency} dependency
|
||||
|
|
@ -158,6 +169,42 @@ const { isSourceEqual } = require("./util/source");
|
|||
* @property {ChunkGraph} chunkGraph the chunk graph
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} RuntimeRequirementsContext
|
||||
* @property {ChunkGraph} chunkGraph the chunk graph
|
||||
* @property {CodeGenerationResults} codeGenerationResults the code generation results
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ExecuteModuleOptions
|
||||
* @property {EntryOptions=} entryOptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ExecuteModuleResult
|
||||
* @property {any} exports
|
||||
* @property {Map<string, { source: Source, info: AssetInfo }>} assets
|
||||
* @property {LazySet<string>} fileDependencies
|
||||
* @property {LazySet<string>} contextDependencies
|
||||
* @property {LazySet<string>} missingDependencies
|
||||
* @property {LazySet<string>} buildDependencies
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ExecuteModuleArgument
|
||||
* @property {Module} module
|
||||
* @property {object} moduleObject
|
||||
* @property {CodeGenerationResult} codeGenerationResult
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ExecuteModuleContext
|
||||
* @property {Map<string, { source: Source, info: AssetInfo }>} assets
|
||||
* @property {Chunk} chunk
|
||||
* @property {ChunkGraph} chunkGraph
|
||||
* @property {Function} __webpack_require__
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} EntryData
|
||||
* @property {Dependency[]} dependencies dependencies of the entrypoint that should be evaluated at startup
|
||||
|
|
@ -525,6 +572,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
"runtime"
|
||||
]),
|
||||
|
||||
/** @type {SyncHook<[ExecuteModuleArgument, ExecuteModuleContext]>} */
|
||||
executeModule: new SyncHook(["options", "context"]),
|
||||
|
||||
/** @type {AsyncSeriesHook<[Iterable<Module>]>} */
|
||||
finishModules: new AsyncSeriesHook(["modules"]),
|
||||
/** @type {AsyncSeriesHook<[Module]>} */
|
||||
|
|
@ -568,32 +618,35 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
/** @type {SyncBailHook<[], boolean>} */
|
||||
shouldRecord: new SyncBailHook([]),
|
||||
|
||||
/** @type {SyncHook<[Chunk, Set<string>]>} */
|
||||
/** @type {SyncHook<[Chunk, Set<string>, RuntimeRequirementsContext]>} */
|
||||
additionalChunkRuntimeRequirements: new SyncHook([
|
||||
"chunk",
|
||||
"runtimeRequirements"
|
||||
"runtimeRequirements",
|
||||
"context"
|
||||
]),
|
||||
/** @type {HookMap<SyncBailHook<[Chunk, Set<string>]>>} */
|
||||
/** @type {HookMap<SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext]>>} */
|
||||
runtimeRequirementInChunk: new HookMap(
|
||||
() => new SyncBailHook(["chunk", "runtimeRequirements"])
|
||||
() => new SyncBailHook(["chunk", "runtimeRequirements", "context"])
|
||||
),
|
||||
/** @type {SyncHook<[Module, Set<string>]>} */
|
||||
/** @type {SyncHook<[Module, Set<string>, RuntimeRequirementsContext]>} */
|
||||
additionalModuleRuntimeRequirements: new SyncHook([
|
||||
"module",
|
||||
"runtimeRequirements"
|
||||
"runtimeRequirements",
|
||||
"context"
|
||||
]),
|
||||
/** @type {HookMap<SyncBailHook<[Module, Set<string>]>>} */
|
||||
/** @type {HookMap<SyncBailHook<[Module, Set<string>, RuntimeRequirementsContext]>>} */
|
||||
runtimeRequirementInModule: new HookMap(
|
||||
() => new SyncBailHook(["module", "runtimeRequirements"])
|
||||
() => new SyncBailHook(["module", "runtimeRequirements", "context"])
|
||||
),
|
||||
/** @type {SyncHook<[Chunk, Set<string>]>} */
|
||||
/** @type {SyncHook<[Chunk, Set<string>, RuntimeRequirementsContext]>} */
|
||||
additionalTreeRuntimeRequirements: new SyncHook([
|
||||
"chunk",
|
||||
"runtimeRequirements"
|
||||
"runtimeRequirements",
|
||||
"context"
|
||||
]),
|
||||
/** @type {HookMap<SyncBailHook<[Chunk, Set<string>]>>} */
|
||||
/** @type {HookMap<SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext]>>} */
|
||||
runtimeRequirementInTree: new HookMap(
|
||||
() => new SyncBailHook(["chunk", "runtimeRequirements"])
|
||||
() => new SyncBailHook(["chunk", "runtimeRequirements", "context"])
|
||||
),
|
||||
|
||||
/** @type {SyncHook<[RuntimeModule, Chunk]>} */
|
||||
|
|
@ -824,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;
|
||||
|
|
@ -928,6 +982,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
this.builtModules = new WeakSet();
|
||||
/** @type {WeakSet<Module>} */
|
||||
this.codeGeneratedModules = new WeakSet();
|
||||
/** @type {WeakSet<Module>} */
|
||||
this.buildTimeExecutedModules = new WeakSet();
|
||||
/** @private @type {Map<Module, Callback[]>} */
|
||||
this._rebuildingModules = new Map();
|
||||
/** @type {Set<string>} */
|
||||
|
|
@ -1435,6 +1491,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
* @property {Partial<ModuleFactoryCreateDataContextInfo>=} contextInfo
|
||||
* @property {string=} context
|
||||
* @property {boolean=} recursive recurse into dependencies of the created module
|
||||
* @property {boolean=} connectOrigin connect the resolved module with the origin module
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
@ -1449,7 +1506,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
originModule,
|
||||
contextInfo,
|
||||
context,
|
||||
recursive = true
|
||||
recursive = true,
|
||||
connectOrigin = recursive
|
||||
},
|
||||
callback
|
||||
) {
|
||||
|
|
@ -1497,7 +1555,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
for (let i = 0; i < dependencies.length; i++) {
|
||||
const dependency = dependencies[i];
|
||||
moduleGraph.setResolvedModule(
|
||||
recursive ? originModule : null,
|
||||
connectOrigin ? originModule : null,
|
||||
dependency,
|
||||
module
|
||||
);
|
||||
|
|
@ -2644,59 +2702,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {void}
|
||||
*/
|
||||
processRuntimeRequirements() {
|
||||
const { chunkGraph } = this;
|
||||
|
||||
const additionalModuleRuntimeRequirements = this.hooks
|
||||
.additionalModuleRuntimeRequirements;
|
||||
const runtimeRequirementInModule = this.hooks.runtimeRequirementInModule;
|
||||
for (const module of this.modules) {
|
||||
if (chunkGraph.getNumberOfModuleChunks(module) > 0) {
|
||||
for (const runtime of chunkGraph.getModuleRuntimes(module)) {
|
||||
let set;
|
||||
const runtimeRequirements = this.codeGenerationResults.getRuntimeRequirements(
|
||||
module,
|
||||
runtime
|
||||
);
|
||||
if (runtimeRequirements && runtimeRequirements.size > 0) {
|
||||
set = new Set(runtimeRequirements);
|
||||
} else if (additionalModuleRuntimeRequirements.isUsed()) {
|
||||
set = new Set();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
additionalModuleRuntimeRequirements.call(module, set);
|
||||
|
||||
for (const r of set) {
|
||||
const hook = runtimeRequirementInModule.get(r);
|
||||
if (hook !== undefined) hook.call(module, set);
|
||||
}
|
||||
chunkGraph.addModuleRuntimeRequirements(module, runtime, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const chunk of this.chunks) {
|
||||
const set = new Set();
|
||||
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
|
||||
const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
|
||||
module,
|
||||
chunk.runtime
|
||||
);
|
||||
for (const r of runtimeRequirements) set.add(r);
|
||||
}
|
||||
this.hooks.additionalChunkRuntimeRequirements.call(chunk, set);
|
||||
|
||||
for (const r of set) {
|
||||
this.hooks.runtimeRequirementInChunk.for(r).call(chunk, set);
|
||||
}
|
||||
|
||||
chunkGraph.addChunkRuntimeRequirements(chunk, set);
|
||||
}
|
||||
|
||||
_getChunkGraphEntries() {
|
||||
/** @type {Set<Chunk>} */
|
||||
const treeEntries = new Set();
|
||||
for (const ep of this.entrypoints.values()) {
|
||||
|
|
@ -2707,8 +2713,74 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
const chunk = ep.getRuntimeChunk();
|
||||
if (chunk) treeEntries.add(chunk);
|
||||
}
|
||||
return treeEntries;
|
||||
}
|
||||
|
||||
for (const treeEntry of treeEntries) {
|
||||
/**
|
||||
* @param {Object} options options
|
||||
* @param {ChunkGraph=} options.chunkGraph the chunk graph
|
||||
* @param {Iterable<Module>=} options.modules modules
|
||||
* @param {Iterable<Chunk>=} options.chunks chunks
|
||||
* @param {CodeGenerationResults=} options.codeGenerationResults codeGenerationResults
|
||||
* @param {Iterable<Chunk>=} options.chunkGraphEntries chunkGraphEntries
|
||||
* @returns {void}
|
||||
*/
|
||||
processRuntimeRequirements({
|
||||
chunkGraph = this.chunkGraph,
|
||||
modules = this.modules,
|
||||
chunks = this.chunks,
|
||||
codeGenerationResults = this.codeGenerationResults,
|
||||
chunkGraphEntries = this._getChunkGraphEntries()
|
||||
} = {}) {
|
||||
const context = { chunkGraph, codeGenerationResults };
|
||||
const additionalModuleRuntimeRequirements = this.hooks
|
||||
.additionalModuleRuntimeRequirements;
|
||||
const runtimeRequirementInModule = this.hooks.runtimeRequirementInModule;
|
||||
for (const module of modules) {
|
||||
if (chunkGraph.getNumberOfModuleChunks(module) > 0) {
|
||||
for (const runtime of chunkGraph.getModuleRuntimes(module)) {
|
||||
let set;
|
||||
const runtimeRequirements = codeGenerationResults.getRuntimeRequirements(
|
||||
module,
|
||||
runtime
|
||||
);
|
||||
if (runtimeRequirements && runtimeRequirements.size > 0) {
|
||||
set = new Set(runtimeRequirements);
|
||||
} else if (additionalModuleRuntimeRequirements.isUsed()) {
|
||||
set = new Set();
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
additionalModuleRuntimeRequirements.call(module, set, context);
|
||||
|
||||
for (const r of set) {
|
||||
const hook = runtimeRequirementInModule.get(r);
|
||||
if (hook !== undefined) hook.call(module, set, context);
|
||||
}
|
||||
chunkGraph.addModuleRuntimeRequirements(module, runtime, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const chunk of chunks) {
|
||||
const set = new Set();
|
||||
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
|
||||
const runtimeRequirements = chunkGraph.getModuleRuntimeRequirements(
|
||||
module,
|
||||
chunk.runtime
|
||||
);
|
||||
for (const r of runtimeRequirements) set.add(r);
|
||||
}
|
||||
this.hooks.additionalChunkRuntimeRequirements.call(chunk, set, context);
|
||||
|
||||
for (const r of set) {
|
||||
this.hooks.runtimeRequirementInChunk.for(r).call(chunk, set, context);
|
||||
}
|
||||
|
||||
chunkGraph.addChunkRuntimeRequirements(chunk, set);
|
||||
}
|
||||
|
||||
for (const treeEntry of chunkGraphEntries) {
|
||||
const set = new Set();
|
||||
for (const chunk of treeEntry.getAllReferencedChunks()) {
|
||||
const runtimeRequirements = chunkGraph.getChunkRuntimeRequirements(
|
||||
|
|
@ -2717,22 +2789,30 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
for (const r of runtimeRequirements) set.add(r);
|
||||
}
|
||||
|
||||
this.hooks.additionalTreeRuntimeRequirements.call(treeEntry, set);
|
||||
this.hooks.additionalTreeRuntimeRequirements.call(
|
||||
treeEntry,
|
||||
set,
|
||||
context
|
||||
);
|
||||
|
||||
for (const r of set) {
|
||||
this.hooks.runtimeRequirementInTree.for(r).call(treeEntry, set);
|
||||
this.hooks.runtimeRequirementInTree
|
||||
.for(r)
|
||||
.call(treeEntry, set, context);
|
||||
}
|
||||
|
||||
chunkGraph.addTreeRuntimeRequirements(treeEntry, set);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO webpack 6 make chunkGraph argument non-optional
|
||||
/**
|
||||
* @param {Chunk} chunk target chunk
|
||||
* @param {RuntimeModule} module runtime module
|
||||
* @param {ChunkGraph} chunkGraph the chunk graph
|
||||
* @returns {void}
|
||||
*/
|
||||
addRuntimeModule(chunk, module) {
|
||||
addRuntimeModule(chunk, module, chunkGraph = this.chunkGraph) {
|
||||
// Deprecated ModuleGraph association
|
||||
ModuleGraph.setModuleGraphForModule(module, this.moduleGraph);
|
||||
|
||||
|
|
@ -2741,10 +2821,10 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
this._modules.set(module.identifier(), module);
|
||||
|
||||
// connect to the chunk graph
|
||||
this.chunkGraph.connectChunkAndModule(chunk, module);
|
||||
this.chunkGraph.connectChunkAndRuntimeModule(chunk, module);
|
||||
chunkGraph.connectChunkAndModule(chunk, module);
|
||||
chunkGraph.connectChunkAndRuntimeModule(chunk, module);
|
||||
if (module.fullHash) {
|
||||
this.chunkGraph.addFullHashModuleToChunk(chunk, module);
|
||||
chunkGraph.addFullHashModuleToChunk(chunk, module);
|
||||
}
|
||||
|
||||
// attach runtime module
|
||||
|
|
@ -2762,14 +2842,14 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
|
|||
exportsInfo.setUsedForSideEffectsOnly(runtime);
|
||||
}
|
||||
}
|
||||
this.chunkGraph.addModuleRuntimeRequirements(
|
||||
chunkGraph.addModuleRuntimeRequirements(
|
||||
module,
|
||||
chunk.runtime,
|
||||
new Set([RuntimeGlobals.requireScope])
|
||||
);
|
||||
|
||||
// runtime modules don't need ids
|
||||
this.chunkGraph.setModuleId(module, "");
|
||||
chunkGraph.setModuleId(module, "");
|
||||
|
||||
// Call hook
|
||||
this.hooks.runtimeModule.call(module, chunk);
|
||||
|
|
@ -3889,6 +3969,301 @@ This prevents using hashes of each other and should be avoided.`);
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Module} module the module
|
||||
* @param {ExecuteModuleOptions} options options
|
||||
* @param {ExecuteModuleCallback} callback 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);
|
||||
this.buildQueue.waitFor(module, err => {
|
||||
if (err) return callback(err);
|
||||
this.processDependenciesQueue.waitFor(module, err => {
|
||||
if (err) return callback(err);
|
||||
for (const {
|
||||
module: m
|
||||
} of this.moduleGraph.getOutgoingConnections(module)) {
|
||||
const size = modules.size;
|
||||
modules.add(m);
|
||||
if (modules.size !== size) push(m);
|
||||
}
|
||||
callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
err => {
|
||||
if (err) return callback(err);
|
||||
|
||||
// Create new chunk graph, chunk and entrypoint for the build time execution
|
||||
const chunkGraph = new ChunkGraph(this.moduleGraph);
|
||||
const runtime = "build time";
|
||||
const {
|
||||
hashFunction,
|
||||
hashDigest,
|
||||
hashDigestLength
|
||||
} = this.outputOptions;
|
||||
const runtimeTemplate = this.runtimeTemplate;
|
||||
|
||||
const chunk = new Chunk("build time chunk");
|
||||
chunk.id = chunk.name;
|
||||
chunk.ids = [chunk.id];
|
||||
chunk.runtime = runtime;
|
||||
|
||||
const entrypoint = new Entrypoint({
|
||||
runtime,
|
||||
...options.entryOptions
|
||||
});
|
||||
chunkGraph.connectChunkAndEntryModule(chunk, module, entrypoint);
|
||||
connectChunkGroupAndChunk(entrypoint, chunk);
|
||||
entrypoint.setRuntimeChunk(chunk);
|
||||
entrypoint.setEntrypointChunk(chunk);
|
||||
|
||||
const chunks = new Set([chunk]);
|
||||
|
||||
/** @type {Map<string, Module>} */
|
||||
const modulesById = new Map();
|
||||
|
||||
// Assign ids to modules and modules to the chunk
|
||||
for (const module of modules) {
|
||||
const id = module.identifier();
|
||||
modulesById.set(id, module);
|
||||
chunkGraph.setModuleId(module, id);
|
||||
chunkGraph.connectChunkAndModule(chunk, module);
|
||||
}
|
||||
|
||||
// Hash modules
|
||||
for (const module of modules) {
|
||||
this._createModuleHash(
|
||||
module,
|
||||
chunkGraph,
|
||||
runtime,
|
||||
hashFunction,
|
||||
runtimeTemplate,
|
||||
hashDigest,
|
||||
hashDigestLength
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
runtime,
|
||||
[runtime],
|
||||
chunkGraph.getModuleHash(module, runtime),
|
||||
this.dependencyTemplates,
|
||||
chunkGraph,
|
||||
this.moduleGraph,
|
||||
runtimeTemplate,
|
||||
errors,
|
||||
codeGenerationResults,
|
||||
(err, codeGenerated) => {
|
||||
callback(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
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(err);
|
||||
reportErrors();
|
||||
|
||||
// for backward-compat temporary set the chunk graph
|
||||
// TODO webpack 6
|
||||
const old = this.chunkGraph;
|
||||
this.chunkGraph = chunkGraph;
|
||||
this.processRuntimeRequirements({
|
||||
chunkGraph,
|
||||
modules,
|
||||
chunks,
|
||||
codeGenerationResults,
|
||||
chunkGraphEntries: chunks
|
||||
});
|
||||
this.chunkGraph = old;
|
||||
|
||||
const runtimeModules = chunkGraph.getChunkRuntimeModulesIterable(
|
||||
chunk
|
||||
);
|
||||
|
||||
// Hash runtime modules
|
||||
for (const module of runtimeModules) {
|
||||
this._createModuleHash(
|
||||
module,
|
||||
chunkGraph,
|
||||
runtime,
|
||||
hashFunction,
|
||||
runtimeTemplate,
|
||||
hashDigest,
|
||||
hashDigestLength
|
||||
);
|
||||
}
|
||||
|
||||
// Generate code for all runtime modules
|
||||
asyncLib.eachLimit(runtimeModules, 10, codeGen, err => {
|
||||
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 {
|
||||
strictModuleErrorHandling,
|
||||
strictModuleExceptionHandling
|
||||
} = this.outputOptions;
|
||||
const moduleCache = new Map();
|
||||
const __webpack_require__ = id => {
|
||||
const module = modulesById.get(id);
|
||||
return __webpack_require_module__(module, id);
|
||||
};
|
||||
/**
|
||||
*
|
||||
* @param {Module} module the module
|
||||
* @param {string} id id
|
||||
* @returns {any} exports
|
||||
*/
|
||||
const __webpack_require_module__ = (module, id) => {
|
||||
const cached = moduleCache.get(module);
|
||||
if (cached !== undefined) {
|
||||
if (cached.error) throw cached.error;
|
||||
return cached.exports;
|
||||
}
|
||||
const moduleObject = {
|
||||
id,
|
||||
exports: {},
|
||||
loaded: false,
|
||||
error: undefined
|
||||
};
|
||||
this.buildTimeExecutedModules.add(module);
|
||||
module.addCacheDependencies(
|
||||
fileDependencies,
|
||||
contextDependencies,
|
||||
missingDependencies,
|
||||
buildDependencies
|
||||
);
|
||||
if (module.buildInfo && module.buildInfo.assets) {
|
||||
const { assets: moduleAssets, assetsInfo } = module.buildInfo;
|
||||
for (const assetName of Object.keys(moduleAssets)) {
|
||||
assets.set(assetName, {
|
||||
source: moduleAssets[assetName],
|
||||
info: assetsInfo ? assetsInfo.get(assetName) : undefined
|
||||
});
|
||||
}
|
||||
}
|
||||
try {
|
||||
moduleCache.set(module, moduleObject);
|
||||
const codeGenerationResult = codeGenerationResults.get(
|
||||
module,
|
||||
runtime
|
||||
);
|
||||
tryRunOrWebpackError(
|
||||
() =>
|
||||
this.hooks.executeModule.call(
|
||||
{
|
||||
codeGenerationResult,
|
||||
module,
|
||||
moduleObject
|
||||
},
|
||||
context
|
||||
),
|
||||
"Compilation.hooks.executeModule"
|
||||
);
|
||||
moduleObject.loaded = true;
|
||||
return moduleObject.exports;
|
||||
} catch (e) {
|
||||
if (strictModuleExceptionHandling) {
|
||||
moduleCache.delete(module);
|
||||
} else if (strictModuleErrorHandling) {
|
||||
moduleObject.error = e;
|
||||
}
|
||||
if (!e.module) e.module = module;
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
/** @type {ExecuteModuleContext} */
|
||||
const context = {
|
||||
assets,
|
||||
__webpack_require__,
|
||||
chunk,
|
||||
chunkGraph
|
||||
};
|
||||
|
||||
for (const runtimeModule of chunkGraph.getChunkRuntimeModulesInOrder(
|
||||
chunk
|
||||
)) {
|
||||
__webpack_require_module__(
|
||||
runtimeModule,
|
||||
runtimeModule.identifier()
|
||||
);
|
||||
}
|
||||
exports = __webpack_require__(module.identifier());
|
||||
} catch (e) {
|
||||
const err = new WebpackError(
|
||||
`Execution of module code from module graph (${module.readableIdentifier(
|
||||
this.requestShortener
|
||||
)}) failed: ${e.message}`
|
||||
);
|
||||
err.stack = e.stack;
|
||||
err.module = e.module;
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
callback(null, {
|
||||
exports,
|
||||
assets,
|
||||
fileDependencies,
|
||||
contextDependencies,
|
||||
missingDependencies,
|
||||
buildDependencies
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
checkConstraints() {
|
||||
const chunkGraph = this.chunkGraph;
|
||||
|
||||
|
|
|
|||
|
|
@ -496,7 +496,21 @@ class NormalModuleFactory extends ModuleFactory {
|
|||
for (const loader of loaders) allLoaders.push(loader);
|
||||
}
|
||||
for (const loader of preLoaders) allLoaders.push(loader);
|
||||
const type = settings.type;
|
||||
let type = settings.type;
|
||||
if (!type) {
|
||||
const resource =
|
||||
(matchResourceData && matchResourceData.resource) ||
|
||||
resourceData.resource;
|
||||
let match;
|
||||
if (
|
||||
typeof resource === "string" &&
|
||||
(match = /\.webpack\[([^\]]+)\]$/.exec(resource))
|
||||
) {
|
||||
type = match[1];
|
||||
} else {
|
||||
type = "javascript/auto";
|
||||
}
|
||||
}
|
||||
const resolveOptions = settings.resolve;
|
||||
const layer = settings.layer;
|
||||
if (layer !== undefined && !layers) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
const CaseSensitiveModulesWarning = require("./CaseSensitiveModulesWarning");
|
||||
|
||||
/** @typedef {import("./Compiler")} Compiler */
|
||||
/** @typedef {import("./Module")} Module */
|
||||
|
||||
class WarnCaseSensitiveModulesPlugin {
|
||||
/**
|
||||
|
|
@ -20,21 +21,26 @@ class WarnCaseSensitiveModulesPlugin {
|
|||
"WarnCaseSensitiveModulesPlugin",
|
||||
compilation => {
|
||||
compilation.hooks.seal.tap("WarnCaseSensitiveModulesPlugin", () => {
|
||||
/** @type {Map<string, Map<string, Module>>} */
|
||||
const moduleWithoutCase = new Map();
|
||||
for (const module of compilation.modules) {
|
||||
const identifier = module.identifier().toLowerCase();
|
||||
const array = moduleWithoutCase.get(identifier);
|
||||
if (array) {
|
||||
array.push(module);
|
||||
} else {
|
||||
moduleWithoutCase.set(identifier, [module]);
|
||||
const identifier = module.identifier();
|
||||
const lowerIdentifier = identifier.toLowerCase();
|
||||
let map = moduleWithoutCase.get(lowerIdentifier);
|
||||
if (map === undefined) {
|
||||
map = new Map();
|
||||
moduleWithoutCase.set(lowerIdentifier, map);
|
||||
}
|
||||
map.set(identifier, module);
|
||||
}
|
||||
for (const pair of moduleWithoutCase) {
|
||||
const array = pair[1];
|
||||
if (array.length > 1) {
|
||||
const map = pair[1];
|
||||
if (map.size > 1) {
|
||||
compilation.warnings.push(
|
||||
new CaseSensitiveModulesWarning(array, compilation.moduleGraph)
|
||||
new CaseSensitiveModulesWarning(
|
||||
map.values(),
|
||||
compilation.moduleGraph
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -176,6 +176,19 @@ class AssetModulesPlugin {
|
|||
|
||||
return result;
|
||||
});
|
||||
|
||||
compilation.hooks.executeModule.tap(
|
||||
"AssetModulesPlugin",
|
||||
(options, context) => {
|
||||
const { codeGenerationResult } = options;
|
||||
const source = codeGenerationResult.sources.get("asset");
|
||||
if (source === undefined) return;
|
||||
context.assets.set(codeGenerationResult.data.get("filename"), {
|
||||
source,
|
||||
info: codeGenerationResult.data.get("assetInfo")
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -431,9 +431,6 @@ const applyModuleDefaults = (
|
|||
};
|
||||
/** @type {RuleSetRules} */
|
||||
const rules = [
|
||||
{
|
||||
type: "javascript/auto"
|
||||
},
|
||||
{
|
||||
mimetype: "application/node",
|
||||
type: "javascript/auto"
|
||||
|
|
@ -1031,6 +1028,7 @@ const getResolveDefaults = ({ cache, context, targetProperties, mode }) => {
|
|||
byDependency: {
|
||||
wasm: esmDeps(),
|
||||
esm: esmDeps(),
|
||||
loaderImport: esmDeps(),
|
||||
url: {
|
||||
preferRelative: true
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const ModuleDependency = require("./ModuleDependency");
|
||||
|
||||
class LoaderImportDependency extends ModuleDependency {
|
||||
/**
|
||||
* @param {string} request request string
|
||||
*/
|
||||
constructor(request) {
|
||||
super(request);
|
||||
this.weak = true;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "loader import";
|
||||
}
|
||||
|
||||
get category() {
|
||||
return "loaderImport";
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LoaderImportDependency;
|
||||
|
|
@ -8,18 +8,44 @@
|
|||
const NormalModule = require("../NormalModule");
|
||||
const LazySet = require("../util/LazySet");
|
||||
const LoaderDependency = require("./LoaderDependency");
|
||||
const LoaderImportDependency = require("./LoaderImportDependency");
|
||||
|
||||
/** @typedef {import("../Compilation").DepConstructor} DepConstructor */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
/** @typedef {import("../Module")} Module */
|
||||
|
||||
/**
|
||||
* @callback LoadModuleCallback
|
||||
* @param {Error=} err error object
|
||||
* @param {string=} source source code
|
||||
* @param {string | Buffer=} source source code
|
||||
* @param {object=} map source map
|
||||
* @param {Module=} module loaded module if successful
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback ImportModuleCallback
|
||||
* @param {Error=} err error object
|
||||
* @param {any=} exports exports of the evaluated module
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ImportModuleOptions
|
||||
* @property {string=} layer the target layer
|
||||
*/
|
||||
|
||||
class LoaderPlugin {
|
||||
/**
|
||||
* @param {Object} options options
|
||||
* @param {boolean=} options.enableExecuteModule execute module enabled
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
this._enableExecuteModule = !!options.enableExecuteModule;
|
||||
}
|
||||
/**
|
||||
* Apply the plugin
|
||||
* @param {Compiler} compiler the compiler instance
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
compiler.hooks.compilation.tap(
|
||||
"LoaderPlugin",
|
||||
|
|
@ -28,6 +54,10 @@ class LoaderPlugin {
|
|||
LoaderDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
compilation.dependencyFactories.set(
|
||||
LoaderImportDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
|
@ -47,7 +77,7 @@ class LoaderPlugin {
|
|||
name: request
|
||||
};
|
||||
const factory = compilation.dependencyFactories.get(
|
||||
dep.constructor
|
||||
/** @type {DepConstructor} */ (dep.constructor)
|
||||
);
|
||||
if (factory === undefined) {
|
||||
return callback(
|
||||
|
|
@ -123,6 +153,101 @@ class LoaderPlugin {
|
|||
}
|
||||
);
|
||||
};
|
||||
|
||||
if (this._enableExecuteModule) {
|
||||
/**
|
||||
* @param {string} request the request string to load the module from
|
||||
* @param {ImportModuleOptions=} options options
|
||||
* @param {ImportModuleCallback=} callback callback returning the exports
|
||||
* @returns {void}
|
||||
*/
|
||||
const importModule = (request, options, callback) => {
|
||||
const dep = new LoaderImportDependency(request);
|
||||
dep.loc = {
|
||||
name: request
|
||||
};
|
||||
const factory = compilation.dependencyFactories.get(
|
||||
/** @type {DepConstructor} */ (dep.constructor)
|
||||
);
|
||||
if (factory === undefined) {
|
||||
return callback(
|
||||
new Error(
|
||||
`No module factory available for dependency type: ${dep.constructor.name}`
|
||||
)
|
||||
);
|
||||
}
|
||||
compilation.buildQueue.increaseParallelism();
|
||||
compilation.handleModuleCreation(
|
||||
{
|
||||
factory,
|
||||
dependencies: [dep],
|
||||
originModule: loaderContext._module,
|
||||
contextInfo: {
|
||||
issuerLayer: options.layer
|
||||
},
|
||||
context: loaderContext.context,
|
||||
connectOrigin: false
|
||||
},
|
||||
err => {
|
||||
compilation.buildQueue.decreaseParallelism();
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
const referencedModule = moduleGraph.getModule(dep);
|
||||
if (!referencedModule) {
|
||||
return callback(new Error("Cannot load the module"));
|
||||
}
|
||||
compilation.executeModule(
|
||||
referencedModule,
|
||||
{},
|
||||
(err, result) => {
|
||||
if (err) return callback(err);
|
||||
for (const d of result.fileDependencies) {
|
||||
loaderContext.addDependency(d);
|
||||
}
|
||||
for (const d of result.contextDependencies) {
|
||||
loaderContext.addContextDependency(d);
|
||||
}
|
||||
for (const d of result.missingDependencies) {
|
||||
loaderContext.addMissingDependency(d);
|
||||
}
|
||||
for (const d of result.buildDependencies) {
|
||||
loaderContext.addBuildDependency(d);
|
||||
}
|
||||
for (const [name, { source, info }] of result.assets) {
|
||||
const { buildInfo } = loaderContext._module;
|
||||
if (!buildInfo.assets) {
|
||||
buildInfo.assets = Object.create(null);
|
||||
buildInfo.assetsInfo = new Map();
|
||||
}
|
||||
buildInfo.assets[name] = source;
|
||||
buildInfo.assetsInfo.set(name, info);
|
||||
}
|
||||
callback(null, result.exports);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} request the request string to load the module from
|
||||
* @param {ImportModuleOptions} options options
|
||||
* @param {ImportModuleCallback=} callback callback returning the exports
|
||||
* @returns {Promise<any> | void} exports
|
||||
*/
|
||||
loaderContext.importModule = (request, options, callback) => {
|
||||
if (!callback) {
|
||||
return new Promise((resolve, reject) => {
|
||||
importModule(request, options || {}, (err, result) => {
|
||||
if (err) reject(err);
|
||||
else resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
return importModule(request, options || {}, callback);
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ class ArrayPushCallbackChunkFormatPlugin {
|
|||
compilation => {
|
||||
compilation.hooks.additionalChunkRuntimeRequirements.tap(
|
||||
"ArrayPushCallbackChunkFormatPlugin",
|
||||
(chunk, set) => {
|
||||
(chunk, set, { chunkGraph }) => {
|
||||
if (chunk.hasRuntime()) return;
|
||||
if (compilation.chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
||||
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
||||
set.add(RuntimeGlobals.onChunksLoaded);
|
||||
set.add(RuntimeGlobals.require);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ class CommonJsChunkFormatPlugin {
|
|||
compilation => {
|
||||
compilation.hooks.additionalChunkRuntimeRequirements.tap(
|
||||
"CommonJsChunkLoadingPlugin",
|
||||
(chunk, set) => {
|
||||
(chunk, set, { chunkGraph }) => {
|
||||
if (chunk.hasRuntime()) return;
|
||||
if (compilation.chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
||||
if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
|
||||
set.add(RuntimeGlobals.require);
|
||||
set.add(RuntimeGlobals.startupEntrypoint);
|
||||
set.add(RuntimeGlobals.externalInstallChunk);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
"use strict";
|
||||
|
||||
const { SyncWaterfallHook, SyncHook, SyncBailHook } = require("tapable");
|
||||
const vm = require("vm");
|
||||
const {
|
||||
ConcatSource,
|
||||
OriginalSource,
|
||||
|
|
@ -369,16 +370,58 @@ class JavascriptModulesPlugin {
|
|||
});
|
||||
compilation.hooks.additionalTreeRuntimeRequirements.tap(
|
||||
"JavascriptModulesPlugin",
|
||||
(chunk, set) => {
|
||||
(chunk, set, { chunkGraph }) => {
|
||||
if (
|
||||
!set.has(RuntimeGlobals.startupNoDefault) &&
|
||||
compilation.chunkGraph.hasChunkEntryDependentChunks(chunk)
|
||||
chunkGraph.hasChunkEntryDependentChunks(chunk)
|
||||
) {
|
||||
set.add(RuntimeGlobals.onChunksLoaded);
|
||||
set.add(RuntimeGlobals.require);
|
||||
}
|
||||
}
|
||||
);
|
||||
compilation.hooks.executeModule.tap(
|
||||
"JavascriptModulesPlugin",
|
||||
(options, context) => {
|
||||
const source = options.codeGenerationResult.sources.get(
|
||||
"javascript"
|
||||
);
|
||||
if (source === undefined) return;
|
||||
const { module, moduleObject } = options;
|
||||
const code = source.source();
|
||||
|
||||
const fn = vm.runInThisContext(
|
||||
`(function(${module.moduleArgument}, ${module.exportsArgument}, __webpack_require__) {\n${code}\n/**/})`,
|
||||
{
|
||||
filename: module.identifier(),
|
||||
lineOffset: -1
|
||||
}
|
||||
);
|
||||
fn.call(
|
||||
moduleObject.exports,
|
||||
moduleObject,
|
||||
moduleObject.exports,
|
||||
context.__webpack_require__
|
||||
);
|
||||
}
|
||||
);
|
||||
compilation.hooks.executeModule.tap(
|
||||
"JavascriptModulesPlugin",
|
||||
(options, context) => {
|
||||
const source = options.codeGenerationResult.sources.get("runtime");
|
||||
if (source === undefined) return;
|
||||
const code = source.source();
|
||||
|
||||
const fn = vm.runInThisContext(
|
||||
`(function(__webpack_require__) {\n${code}\n/**/})`,
|
||||
{
|
||||
filename: options.module.identifier(),
|
||||
lineOffset: -1
|
||||
}
|
||||
);
|
||||
fn.call(null, context.__webpack_require__);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ const JavascriptModulesPlugin = require("../javascript/JavascriptModulesPlugin")
|
|||
/** @typedef {import("../../declarations/WebpackOptions").LibraryOptions} LibraryOptions */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").LibraryType} LibraryType */
|
||||
/** @typedef {import("../Chunk")} Chunk */
|
||||
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
||||
/** @typedef {import("../Compilation")} Compilation */
|
||||
/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
|
|
@ -27,6 +28,7 @@ const COMMON_LIBRARY_NAME_MESSAGE =
|
|||
* @template T
|
||||
* @typedef {Object} LibraryContext
|
||||
* @property {Compilation} compilation
|
||||
* @property {ChunkGraph} chunkGraph
|
||||
* @property {T} options
|
||||
*/
|
||||
|
||||
|
|
@ -75,7 +77,8 @@ class AbstractLibraryPlugin {
|
|||
if (module) {
|
||||
this.finishEntryModule(module, name, {
|
||||
options,
|
||||
compilation
|
||||
compilation,
|
||||
chunkGraph: compilation.chunkGraph
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -101,10 +104,14 @@ class AbstractLibraryPlugin {
|
|||
) {
|
||||
compilation.hooks.additionalChunkRuntimeRequirements.tap(
|
||||
_pluginName,
|
||||
(chunk, set) => {
|
||||
(chunk, set, { chunkGraph }) => {
|
||||
const options = getOptionsForChunk(chunk);
|
||||
if (options !== false) {
|
||||
this.runtimeRequirements(chunk, set, { options, compilation });
|
||||
this.runtimeRequirements(chunk, set, {
|
||||
options,
|
||||
compilation,
|
||||
chunkGraph
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
@ -116,7 +123,11 @@ class AbstractLibraryPlugin {
|
|||
hooks.render.tap(_pluginName, (source, renderContext) => {
|
||||
const options = getOptionsForChunk(renderContext.chunk);
|
||||
if (options === false) return source;
|
||||
return this.render(source, renderContext, { options, compilation });
|
||||
return this.render(source, renderContext, {
|
||||
options,
|
||||
compilation,
|
||||
chunkGraph: compilation.chunkGraph
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -131,7 +142,8 @@ class AbstractLibraryPlugin {
|
|||
if (options === false) return;
|
||||
return this.embedInRuntimeBailout(module, renderContext, {
|
||||
options,
|
||||
compilation
|
||||
compilation,
|
||||
chunkGraph: compilation.chunkGraph
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
@ -146,7 +158,8 @@ class AbstractLibraryPlugin {
|
|||
if (options === false) return;
|
||||
return this.strictRuntimeBailout(renderContext, {
|
||||
options,
|
||||
compilation
|
||||
compilation,
|
||||
chunkGraph: compilation.chunkGraph
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -161,7 +174,8 @@ class AbstractLibraryPlugin {
|
|||
if (options === false) return source;
|
||||
return this.renderStartup(source, module, renderContext, {
|
||||
options,
|
||||
compilation
|
||||
compilation,
|
||||
chunkGraph: compilation.chunkGraph
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
@ -170,7 +184,11 @@ class AbstractLibraryPlugin {
|
|||
hooks.chunkHash.tap(_pluginName, (chunk, hash, context) => {
|
||||
const options = getOptionsForChunk(chunk);
|
||||
if (options === false) return;
|
||||
this.chunkHash(chunk, hash, context, { options, compilation });
|
||||
this.chunkHash(chunk, hash, context, {
|
||||
options,
|
||||
compilation,
|
||||
chunkGraph: compilation.chunkGraph
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,8 +24,7 @@ class ChunkPrefetchPreloadPlugin {
|
|||
compilation => {
|
||||
compilation.hooks.additionalChunkRuntimeRequirements.tap(
|
||||
"ChunkPrefetchPreloadPlugin",
|
||||
(chunk, set) => {
|
||||
const { chunkGraph } = compilation;
|
||||
(chunk, set, { chunkGraph }) => {
|
||||
if (chunkGraph.getNumberOfEntryModules(chunk) === 0) return;
|
||||
const startupChildChunks = chunk.getChildrenOfTypeInOrder(
|
||||
chunkGraph,
|
||||
|
|
@ -43,8 +42,7 @@ class ChunkPrefetchPreloadPlugin {
|
|||
);
|
||||
compilation.hooks.additionalTreeRuntimeRequirements.tap(
|
||||
"ChunkPrefetchPreloadPlugin",
|
||||
(chunk, set) => {
|
||||
const { chunkGraph } = compilation;
|
||||
(chunk, set, { chunkGraph }) => {
|
||||
const chunkMap = chunk.getChildIdsByOrdersMap(chunkGraph, false);
|
||||
|
||||
if (chunkMap.prefetch) {
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ class StartupChunkDependenciesPlugin {
|
|||
};
|
||||
compilation.hooks.additionalTreeRuntimeRequirements.tap(
|
||||
"StartupChunkDependenciesPlugin",
|
||||
(chunk, set) => {
|
||||
(chunk, set, { chunkGraph }) => {
|
||||
if (!isEnabledForChunk(chunk)) return;
|
||||
if (compilation.chunkGraph.hasChunkEntryDependentChunks(chunk)) {
|
||||
if (chunkGraph.hasChunkEntryDependentChunks(chunk)) {
|
||||
set.add(RuntimeGlobals.startup);
|
||||
set.add(RuntimeGlobals.ensureChunk);
|
||||
set.add(RuntimeGlobals.ensureChunkIncludeEntries);
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ const { makePathsRelative, parseResource } = require("../util/identifier");
|
|||
* @property {boolean=} cacheable
|
||||
* @property {boolean=} built
|
||||
* @property {boolean=} codeGenerated
|
||||
* @property {boolean=} buildTimeExecuted
|
||||
* @property {boolean=} cached
|
||||
* @property {boolean=} optional
|
||||
* @property {boolean=} orphan
|
||||
|
|
@ -1077,6 +1078,9 @@ const SIMPLE_EXTRACTORS = {
|
|||
const { compilation, type } = context;
|
||||
const built = compilation.builtModules.has(module);
|
||||
const codeGenerated = compilation.codeGeneratedModules.has(module);
|
||||
const buildTimeExecuted = compilation.buildTimeExecutedModules.has(
|
||||
module
|
||||
);
|
||||
/** @type {{[x: string]: number}} */
|
||||
const sizes = {};
|
||||
for (const sourceType of module.getSourceTypes()) {
|
||||
|
|
@ -1091,6 +1095,7 @@ const SIMPLE_EXTRACTORS = {
|
|||
sizes,
|
||||
built,
|
||||
codeGenerated,
|
||||
buildTimeExecuted,
|
||||
cached: !built && !codeGenerated
|
||||
};
|
||||
Object.assign(object, statsModule);
|
||||
|
|
|
|||
|
|
@ -306,6 +306,8 @@ const SIMPLE_PRINTERS = {
|
|||
built ? yellow(formatFlag("built")) : undefined,
|
||||
"module.codeGenerated": (codeGenerated, { formatFlag, yellow }) =>
|
||||
codeGenerated ? yellow(formatFlag("code generated")) : undefined,
|
||||
"module.buildTimeExecuted": (buildTimeExecuted, { formatFlag, green }) =>
|
||||
buildTimeExecuted ? green(formatFlag("build time executed")) : undefined,
|
||||
"module.cached": (cached, { formatFlag, green }) =>
|
||||
cached ? green(formatFlag("cached")) : undefined,
|
||||
"module.assets": (assets, { formatFlag, magenta }) =>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
"use strict";
|
||||
|
||||
const { SyncHook, AsyncSeriesHook } = require("tapable");
|
||||
const { makeWebpackError } = require("../HookWebpackError");
|
||||
const WebpackError = require("../WebpackError");
|
||||
const ArrayQueue = require("./ArrayQueue");
|
||||
|
||||
const QUEUED_STATE = 0;
|
||||
|
|
@ -17,7 +19,7 @@ let inHandleResult = 0;
|
|||
/**
|
||||
* @template T
|
||||
* @callback Callback
|
||||
* @param {Error=} err
|
||||
* @param {WebpackError=} err
|
||||
* @param {T=} result
|
||||
*/
|
||||
|
||||
|
|
@ -39,6 +41,7 @@ class AsyncQueueEntry {
|
|||
/** @type {Callback<R>[] | undefined} */
|
||||
this.callbacks = undefined;
|
||||
this.result = undefined;
|
||||
/** @type {WebpackError | undefined} */
|
||||
this.error = undefined;
|
||||
}
|
||||
}
|
||||
|
|
@ -99,15 +102,17 @@ class AsyncQueue {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {T} item a item
|
||||
* @param {T} item an item
|
||||
* @param {Callback<R>} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
add(item, callback) {
|
||||
if (this._stopped) return callback(new Error("Queue was stopped"));
|
||||
if (this._stopped) return callback(new WebpackError("Queue was stopped"));
|
||||
this.hooks.beforeAdd.callAsync(item, err => {
|
||||
if (err) {
|
||||
callback(err);
|
||||
callback(
|
||||
makeWebpackError(err, `AsyncQueue(${this._name}).hooks.beforeAdd`)
|
||||
);
|
||||
return;
|
||||
}
|
||||
const key = this._getKey(item);
|
||||
|
|
@ -127,7 +132,7 @@ class AsyncQueue {
|
|||
this.hooks.added.call(item);
|
||||
this._root._activeTasks++;
|
||||
process.nextTick(() =>
|
||||
this._handleResult(newEntry, new Error("Queue was stopped"))
|
||||
this._handleResult(newEntry, new WebpackError("Queue was stopped"))
|
||||
);
|
||||
} else {
|
||||
this._entries.set(key, newEntry);
|
||||
|
|
@ -144,7 +149,7 @@ class AsyncQueue {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {T} item a item
|
||||
* @param {T} item an item
|
||||
* @returns {void}
|
||||
*/
|
||||
invalidate(item) {
|
||||
|
|
@ -156,6 +161,31 @@ class AsyncQueue {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for an already started item
|
||||
* @param {T} item an item
|
||||
* @param {Callback<R>} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
waitFor(item, callback) {
|
||||
const key = this._getKey(item);
|
||||
const entry = this._entries.get(key);
|
||||
if (entry === undefined) {
|
||||
return callback(
|
||||
new WebpackError(
|
||||
"waitFor can only be called for an already started item"
|
||||
)
|
||||
);
|
||||
}
|
||||
if (entry.state === DONE_STATE) {
|
||||
process.nextTick(() => callback(entry.error, entry.result));
|
||||
} else if (entry.callbacks === undefined) {
|
||||
entry.callbacks = [callback];
|
||||
} else {
|
||||
entry.callbacks.push(callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {void}
|
||||
*/
|
||||
|
|
@ -167,7 +197,7 @@ class AsyncQueue {
|
|||
for (const entry of queue) {
|
||||
this._entries.delete(this._getKey(entry.item));
|
||||
root._activeTasks++;
|
||||
this._handleResult(entry, new Error("Queue was stopped"));
|
||||
this._handleResult(entry, new WebpackError("Queue was stopped"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -257,7 +287,10 @@ class AsyncQueue {
|
|||
_startProcessing(entry) {
|
||||
this.hooks.beforeStart.callAsync(entry.item, err => {
|
||||
if (err) {
|
||||
this._handleResult(entry, err);
|
||||
this._handleResult(
|
||||
entry,
|
||||
makeWebpackError(err, `AsyncQueue(${this._name}).hooks.beforeStart`)
|
||||
);
|
||||
return;
|
||||
}
|
||||
let inCallback = false;
|
||||
|
|
@ -276,13 +309,15 @@ class AsyncQueue {
|
|||
|
||||
/**
|
||||
* @param {AsyncQueueEntry<T, K, R>} entry the entry
|
||||
* @param {Error=} err error, if any
|
||||
* @param {WebpackError=} err error, if any
|
||||
* @param {R=} result result, if any
|
||||
* @returns {void}
|
||||
*/
|
||||
_handleResult(entry, err, result) {
|
||||
this.hooks.result.callAsync(entry.item, err, result, hookError => {
|
||||
const error = hookError || err;
|
||||
const error = hookError
|
||||
? makeWebpackError(hookError, `AsyncQueue(${this._name}).hooks.result`)
|
||||
: err;
|
||||
|
||||
const callback = entry.callback;
|
||||
const callbacks = entry.callbacks;
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@
|
|||
|
||||
/**
|
||||
* @template T
|
||||
* @template {Error} E
|
||||
* @param {Iterable<T>} items initial items
|
||||
* @param {number} concurrency number of items running in parallel
|
||||
* @param {function(T, function(T): void, function(Error=): void): void} processor worker which pushes more items
|
||||
* @param {function(Error=): void} callback all items processed
|
||||
* @param {function(T, function(T): void, function(E=): void): void} processor worker which pushes more items
|
||||
* @param {function(E=): void} callback all items processed
|
||||
* @returns {void}
|
||||
*/
|
||||
const processAsyncTree = (items, concurrency, processor, callback) => {
|
||||
|
|
|
|||
|
|
@ -675,6 +675,10 @@
|
|||
"description": "Support WebAssembly as asynchronous EcmaScript Module.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"executeModule": {
|
||||
"description": "Enable build-time execution of modules from the module graph for plugins and loaders.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"layers": {
|
||||
"description": "Enable module and chunk layers.",
|
||||
"type": "boolean"
|
||||
|
|
|
|||
|
|
@ -115,9 +115,6 @@ describe("Defaults", () => {
|
|||
"mode": "none",
|
||||
"module": Object {
|
||||
"defaultRules": Array [
|
||||
Object {
|
||||
"type": "javascript/auto",
|
||||
},
|
||||
Object {
|
||||
"mimetype": "application/node",
|
||||
"type": "javascript/auto",
|
||||
|
|
@ -424,6 +421,26 @@ describe("Defaults", () => {
|
|||
"...",
|
||||
],
|
||||
},
|
||||
"loaderImport": Object {
|
||||
"aliasFields": Array [
|
||||
"browser",
|
||||
],
|
||||
"conditionNames": Array [
|
||||
"import",
|
||||
"module",
|
||||
"...",
|
||||
],
|
||||
"extensions": Array [
|
||||
".js",
|
||||
".json",
|
||||
".wasm",
|
||||
],
|
||||
"mainFields": Array [
|
||||
"browser",
|
||||
"module",
|
||||
"...",
|
||||
],
|
||||
},
|
||||
"undefined": Object {
|
||||
"aliasFields": Array [
|
||||
"browser",
|
||||
|
|
@ -1092,6 +1109,13 @@ describe("Defaults", () => {
|
|||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
- "aliasFields": Array [
|
||||
- "browser",
|
||||
- ],
|
||||
+ "aliasFields": Array [],
|
||||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
- "browser",
|
||||
+ "node",
|
||||
@@ ... @@
|
||||
|
|
@ -1226,6 +1250,13 @@ describe("Defaults", () => {
|
|||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
- "aliasFields": Array [
|
||||
- "browser",
|
||||
- ],
|
||||
+ "aliasFields": Array [],
|
||||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
- "browser",
|
||||
+ "node",
|
||||
+ "electron",
|
||||
|
|
@ -1342,6 +1373,13 @@ describe("Defaults", () => {
|
|||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
- "aliasFields": Array [
|
||||
- "browser",
|
||||
- ],
|
||||
+ "aliasFields": Array [],
|
||||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
+ "node",
|
||||
@@ ... @@
|
||||
+ "electron",
|
||||
|
|
|
|||
|
|
@ -393,6 +393,19 @@ Object {
|
|||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"experiments-execute-module": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "Enable build-time execution of modules from the module graph for plugins and loaders.",
|
||||
"multiple": false,
|
||||
"path": "experiments.executeModule",
|
||||
"type": "boolean",
|
||||
},
|
||||
],
|
||||
"description": "Enable build-time execution of modules from the module graph for plugins and loaders.",
|
||||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"experiments-layers": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
export const red = "#f00";
|
||||
export const green = "#0f0";
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -0,0 +1,15 @@
|
|||
import stylesheet from "./stylesheet";
|
||||
import stylesheet1 from "./stylesheet?1";
|
||||
import otherStylesheet from "./other-stylesheet";
|
||||
|
||||
it("should be able to use build-time code", () => {
|
||||
expect(stylesheet).toBe(
|
||||
'body { background: url("/public/assets/file.png"); color: #f00; }'
|
||||
);
|
||||
expect(stylesheet1).toBe(
|
||||
'body { background: url("/public/assets/file.png?1"); color: #f00; }'
|
||||
);
|
||||
expect(otherStylesheet).toBe(
|
||||
'body { background: url("/public/assets/file.jpg"); color: #0f0; }'
|
||||
);
|
||||
});
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
exports.pitch = async function (remaining) {
|
||||
const result = await this.importModule(
|
||||
this.resourcePath + ".webpack[javascript/auto]" + "!=!" + remaining
|
||||
);
|
||||
return result.default || result;
|
||||
};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import { green } from "./colors.js";
|
||||
import file from "./file.jpg";
|
||||
export default `body { background: url("${file}"); color: ${green}; }`;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { red } from "./colors.js";
|
||||
export default `body { background: url("${
|
||||
new URL("./file.png" + __resourceQuery, import.meta.url).href
|
||||
}"); color: ${red}; }`;
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/** @type {import("../../../../").Configuration} */
|
||||
module.exports = {
|
||||
output: {
|
||||
publicPath: "/public/"
|
||||
},
|
||||
module: {
|
||||
parser: {
|
||||
javascript: {
|
||||
url: "relative"
|
||||
}
|
||||
},
|
||||
generator: {
|
||||
asset: {
|
||||
filename: "assets/[name][ext][query]"
|
||||
}
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
test: /stylesheet\.js$/,
|
||||
use: "./loader",
|
||||
type: "asset/source"
|
||||
},
|
||||
{
|
||||
test: /\.jpg$/,
|
||||
loader: "file-loader",
|
||||
options: {
|
||||
name: "assets/[name].[ext]"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
experiments: {
|
||||
executeModule: true
|
||||
},
|
||||
plugins: [
|
||||
compiler =>
|
||||
compiler.hooks.done.tap("test case", stats => {
|
||||
expect(stats.compilation.getAsset("assets/file.png")).toHaveProperty(
|
||||
"info",
|
||||
expect.objectContaining({ sourceFilename: "file.png" })
|
||||
);
|
||||
expect(stats.compilation.getAsset("assets/file.jpg")).toHaveProperty(
|
||||
"info",
|
||||
expect.objectContaining({ sourceFilename: "file.jpg" })
|
||||
);
|
||||
const { auxiliaryFiles } = stats.compilation.namedChunks.get("main");
|
||||
expect(auxiliaryFiles).toContain("assets/file.png");
|
||||
expect(auxiliaryFiles).toContain("assets/file.png?1");
|
||||
expect(auxiliaryFiles).toContain("assets/file.jpg");
|
||||
})
|
||||
]
|
||||
};
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
export const value = 42;
|
||||
export * from "./imported.js";
|
||||
export { default as nested } from "./b.generate-json.js";
|
||||
export const random = Math.random();
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
export const value = 42;
|
||||
export * from "./imported.js";
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
export const a = "a";
|
||||
export const b = "b";
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import a from "./a.generate-json.js";
|
||||
import { value as unrelated } from "./unrelated";
|
||||
|
||||
it("should have to correct values and validate on change", () => {
|
||||
const step = +WATCH_STEP;
|
||||
expect(a.value).toBe(42);
|
||||
expect(a.a).toBe("a");
|
||||
expect(a.nested.value).toBe(step < 3 ? 42 : 24);
|
||||
expect(a.nested.a).toBe(step < 3 ? "a" : undefined);
|
||||
expect(a.b).toBe(step < 1 ? "b" : undefined);
|
||||
expect(a.nested.b).toBe(step < 1 ? "b" : undefined);
|
||||
expect(a.c).toBe(step < 1 ? undefined : "c");
|
||||
expect(a.nested.c).toBe(step < 1 || step >= 3 ? undefined : "c");
|
||||
if (step !== 0) {
|
||||
expect(STATE.random === a.random).toBe(step === 2);
|
||||
}
|
||||
STATE.random = a.random;
|
||||
});
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
exports.pitch = async function (remaining) {
|
||||
const result = await this.importModule(
|
||||
`${this.resourcePath}.webpack[javascript/auto]!=!${remaining}`
|
||||
);
|
||||
return JSON.stringify(result, null, 2);
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export const value = 42;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
export const a = "a";
|
||||
export const c = "c";
|
||||
|
|
@ -0,0 +1 @@
|
|||
export const value = 24;
|
||||
|
|
@ -0,0 +1 @@
|
|||
export const value = 24;
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/** @type {import("../../../../").Configuration} */
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.generate-json\.js$/,
|
||||
use: "./loader",
|
||||
type: "json"
|
||||
}
|
||||
]
|
||||
},
|
||||
experiments: {
|
||||
executeModule: true
|
||||
}
|
||||
};
|
||||
|
|
@ -343,8 +343,13 @@ declare abstract class AsyncQueue<T, K, R> {
|
|||
started: SyncHook<[T]>;
|
||||
result: SyncHook<[T, Error, R]>;
|
||||
};
|
||||
add(item: T, callback: CallbackFunction<R>): void;
|
||||
add(item: T, callback: CallbackAsyncQueue<R>): void;
|
||||
invalidate(item: T): void;
|
||||
|
||||
/**
|
||||
* Waits for an already started item
|
||||
*/
|
||||
waitFor(item: T, callback: CallbackAsyncQueue<R>): void;
|
||||
stop(): void;
|
||||
increaseParallelism(): void;
|
||||
decreaseParallelism(): void;
|
||||
|
|
@ -657,6 +662,9 @@ declare interface CallExpressionInfo {
|
|||
name: string;
|
||||
getMembers: () => string[];
|
||||
}
|
||||
declare interface CallbackAsyncQueue<T> {
|
||||
(err?: WebpackError, result?: T): any;
|
||||
}
|
||||
declare interface CallbackCache<T> {
|
||||
(err?: WebpackError, result?: T): void;
|
||||
}
|
||||
|
|
@ -1242,6 +1250,7 @@ declare class Compilation {
|
|||
dependencyReferencedExports: SyncWaterfallHook<
|
||||
[(string[] | ReferencedExport)[], Dependency, RuntimeSpec]
|
||||
>;
|
||||
executeModule: SyncHook<[ExecuteModuleArgument, ExecuteModuleContext]>;
|
||||
finishModules: AsyncSeriesHook<[Iterable<Module>]>;
|
||||
finishRebuildingModule: AsyncSeriesHook<[Module]>;
|
||||
unseal: SyncHook<[]>;
|
||||
|
|
@ -1263,14 +1272,24 @@ declare class Compilation {
|
|||
>;
|
||||
afterOptimizeChunkModules: SyncHook<[Iterable<Chunk>, Iterable<Module>]>;
|
||||
shouldRecord: SyncBailHook<[], boolean>;
|
||||
additionalChunkRuntimeRequirements: SyncHook<[Chunk, Set<string>]>;
|
||||
runtimeRequirementInChunk: HookMap<SyncBailHook<[Chunk, Set<string>], any>>;
|
||||
additionalModuleRuntimeRequirements: SyncHook<[Module, Set<string>]>;
|
||||
runtimeRequirementInModule: HookMap<
|
||||
SyncBailHook<[Module, Set<string>], any>
|
||||
additionalChunkRuntimeRequirements: SyncHook<
|
||||
[Chunk, Set<string>, RuntimeRequirementsContext]
|
||||
>;
|
||||
runtimeRequirementInChunk: HookMap<
|
||||
SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext], any>
|
||||
>;
|
||||
additionalModuleRuntimeRequirements: SyncHook<
|
||||
[Module, Set<string>, RuntimeRequirementsContext]
|
||||
>;
|
||||
runtimeRequirementInModule: HookMap<
|
||||
SyncBailHook<[Module, Set<string>, RuntimeRequirementsContext], any>
|
||||
>;
|
||||
additionalTreeRuntimeRequirements: SyncHook<
|
||||
[Chunk, Set<string>, RuntimeRequirementsContext]
|
||||
>;
|
||||
runtimeRequirementInTree: HookMap<
|
||||
SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext], any>
|
||||
>;
|
||||
additionalTreeRuntimeRequirements: SyncHook<[Chunk, Set<string>]>;
|
||||
runtimeRequirementInTree: HookMap<SyncBailHook<[Chunk, Set<string>], any>>;
|
||||
runtimeModule: SyncHook<[RuntimeModule, Chunk]>;
|
||||
reviveModules: SyncHook<[Iterable<Module>, any]>;
|
||||
beforeModuleIds: SyncHook<[Iterable<Module>]>;
|
||||
|
|
@ -1376,7 +1395,7 @@ declare class Compilation {
|
|||
runtimeTemplate: RuntimeTemplate;
|
||||
moduleTemplates: { javascript: ModuleTemplate };
|
||||
moduleGraph: ModuleGraph;
|
||||
chunkGraph?: ChunkGraph;
|
||||
chunkGraph: ChunkGraph;
|
||||
codeGenerationResults: CodeGenerationResults;
|
||||
processDependenciesQueue: AsyncQueue<Module, Module, Module>;
|
||||
addModuleQueue: AsyncQueue<Module, string, Module>;
|
||||
|
|
@ -1415,6 +1434,7 @@ declare class Compilation {
|
|||
needAdditionalPass: boolean;
|
||||
builtModules: WeakSet<Module>;
|
||||
codeGeneratedModules: WeakSet<Module>;
|
||||
buildTimeExecutedModules: WeakSet<Module>;
|
||||
emittedAssets: Set<string>;
|
||||
comparedForEmitAssets: Set<string>;
|
||||
fileDependencies: LazySet<string>;
|
||||
|
|
@ -1512,8 +1532,33 @@ declare class Compilation {
|
|||
blocks: DependenciesBlock[]
|
||||
): void;
|
||||
codeGeneration(callback?: any): void;
|
||||
processRuntimeRequirements(): void;
|
||||
addRuntimeModule(chunk: Chunk, module: RuntimeModule): void;
|
||||
processRuntimeRequirements(__0?: {
|
||||
/**
|
||||
* the chunk graph
|
||||
*/
|
||||
chunkGraph?: ChunkGraph;
|
||||
/**
|
||||
* modules
|
||||
*/
|
||||
modules?: Iterable<Module>;
|
||||
/**
|
||||
* chunks
|
||||
*/
|
||||
chunks?: Iterable<Chunk>;
|
||||
/**
|
||||
* codeGenerationResults
|
||||
*/
|
||||
codeGenerationResults?: CodeGenerationResults;
|
||||
/**
|
||||
* chunkGraphEntries
|
||||
*/
|
||||
chunkGraphEntries?: Iterable<Chunk>;
|
||||
}): void;
|
||||
addRuntimeModule(
|
||||
chunk: Chunk,
|
||||
module: RuntimeModule,
|
||||
chunkGraph?: ChunkGraph
|
||||
): void;
|
||||
addChunkInGroup(
|
||||
groupOptions: string | ChunkGroupOptions,
|
||||
module: Module,
|
||||
|
|
@ -1601,6 +1646,11 @@ declare class Compilation {
|
|||
| WebpackPluginInstance
|
||||
)[]
|
||||
): Compiler;
|
||||
executeModule(
|
||||
module: Module,
|
||||
options: ExecuteModuleOptions,
|
||||
callback: (err?: WebpackError, result?: ExecuteModuleResult) => void
|
||||
): void;
|
||||
checkConstraints(): void;
|
||||
|
||||
/**
|
||||
|
|
@ -3085,6 +3135,28 @@ declare class EvalSourceMapDevToolPlugin {
|
|||
*/
|
||||
apply(compiler: Compiler): void;
|
||||
}
|
||||
declare interface ExecuteModuleArgument {
|
||||
module: Module;
|
||||
moduleObject: object;
|
||||
codeGenerationResult: CodeGenerationResult;
|
||||
}
|
||||
declare interface ExecuteModuleContext {
|
||||
assets: Map<string, { source: Source; info: AssetInfo }>;
|
||||
chunk: Chunk;
|
||||
chunkGraph: ChunkGraph;
|
||||
__webpack_require__: Function;
|
||||
}
|
||||
declare interface ExecuteModuleOptions {
|
||||
entryOptions?: EntryOptions;
|
||||
}
|
||||
declare interface ExecuteModuleResult {
|
||||
exports: any;
|
||||
assets: Map<string, { source: Source; info: AssetInfo }>;
|
||||
fileDependencies: LazySet<string>;
|
||||
contextDependencies: LazySet<string>;
|
||||
missingDependencies: LazySet<string>;
|
||||
buildDependencies: LazySet<string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables/Disables experiments (experimental features with relax SemVer compatibility).
|
||||
|
|
@ -3100,6 +3172,11 @@ declare interface Experiments {
|
|||
*/
|
||||
asyncWebAssembly?: boolean;
|
||||
|
||||
/**
|
||||
* Enable build-time execution of modules from the module graph for plugins and loaders.
|
||||
*/
|
||||
executeModule?: boolean;
|
||||
|
||||
/**
|
||||
* Enable module and chunk layers.
|
||||
*/
|
||||
|
|
@ -4048,6 +4125,11 @@ declare interface HandleModuleCreationOptions {
|
|||
* recurse into dependencies of the created module
|
||||
*/
|
||||
recursive?: boolean;
|
||||
|
||||
/**
|
||||
* connect the resolved module with the origin module
|
||||
*/
|
||||
connectOrigin?: boolean;
|
||||
}
|
||||
declare class Hash {
|
||||
constructor();
|
||||
|
|
@ -5348,6 +5430,7 @@ declare interface KnownStatsModule {
|
|||
cacheable?: boolean;
|
||||
built?: boolean;
|
||||
codeGenerated?: boolean;
|
||||
buildTimeExecuted?: boolean;
|
||||
cached?: boolean;
|
||||
optional?: boolean;
|
||||
orphan?: boolean;
|
||||
|
|
@ -5484,6 +5567,7 @@ declare class LibManifestPlugin {
|
|||
}
|
||||
declare interface LibraryContext<T> {
|
||||
compilation: Compilation;
|
||||
chunkGraph: ChunkGraph;
|
||||
options: T;
|
||||
}
|
||||
|
||||
|
|
@ -9294,6 +9378,17 @@ declare class RuntimeModule extends Module {
|
|||
*/
|
||||
static STAGE_TRIGGER: number;
|
||||
}
|
||||
declare interface RuntimeRequirementsContext {
|
||||
/**
|
||||
* the chunk graph
|
||||
*/
|
||||
chunkGraph: ChunkGraph;
|
||||
|
||||
/**
|
||||
* the code generation results
|
||||
*/
|
||||
codeGenerationResults: CodeGenerationResults;
|
||||
}
|
||||
type RuntimeSpec = undefined | string | SortableSet<string>;
|
||||
declare abstract class RuntimeSpecMap<T> {
|
||||
get(runtime: RuntimeSpec): T;
|
||||
|
|
|
|||
Loading…
Reference in New Issue