mirror of https://github.com/webpack/webpack.git
add experimental support for build time execution
allow to execute a part of the module graph at build time e. g. to generate code or other assets loaders have access to that via `this.importModule(request, options)`
This commit is contained in:
parent
57f04262b2
commit
065177df66
|
@ -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 ExportsCallback
|
||||
* @param {WebpackError=} err
|
||||
* @param {any=} exports
|
||||
* @returns {void}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback DepBlockVarDependenciesCallback
|
||||
* @param {Dependency} dependency
|
||||
|
@ -158,6 +169,31 @@ 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} RunModuleOptions
|
||||
* @property {EntryOptions=} entryOptions
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} RunModuleArgument
|
||||
* @property {Module} module
|
||||
* @property {object} moduleObject
|
||||
* @property {CodeGenerationResult} codeGenerationResult
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} RunModuleContext
|
||||
* @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 +561,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
"runtime"
|
||||
]),
|
||||
|
||||
/** @type {SyncHook<[RunModuleArgument, RunModuleContext]>} */
|
||||
runModule: new SyncHook(["options", "context"]),
|
||||
|
||||
/** @type {AsyncSeriesHook<[Iterable<Module>]>} */
|
||||
finishModules: new AsyncSeriesHook(["modules"]),
|
||||
/** @type {AsyncSeriesHook<[Module]>} */
|
||||
|
@ -568,32 +607,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]>} */
|
||||
|
@ -928,6 +970,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>} */
|
||||
|
@ -2644,59 +2688,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 +2699,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 +2775,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 +2807,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 +2828,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 +3955,236 @@ This prevents using hashes of each other and should be avoided.`);
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Module} module the module
|
||||
* @param {RunModuleOptions} options options
|
||||
* @param {ExportsCallback} callback callback
|
||||
*/
|
||||
runModule(module, options, callback) {
|
||||
// Aggregate all referenced modules and ensure they are ready
|
||||
const modules = new Set([module]);
|
||||
processAsyncTree(
|
||||
modules,
|
||||
10,
|
||||
(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(makeWebpackError(err, "runModule"));
|
||||
|
||||
// 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]);
|
||||
|
||||
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 = [];
|
||||
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);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Generate code for all aggregated modules
|
||||
asyncLib.eachLimit(modules, 10, codeGen, err => {
|
||||
if (err) return callback(makeWebpackError(err, "runModule"));
|
||||
|
||||
// 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(makeWebpackError(err, "runModule"));
|
||||
|
||||
let result;
|
||||
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);
|
||||
};
|
||||
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);
|
||||
try {
|
||||
moduleCache.set(module, moduleObject);
|
||||
const codeGenerationResult = codeGenerationResults.get(
|
||||
module,
|
||||
runtime
|
||||
);
|
||||
tryRunOrWebpackError(
|
||||
() =>
|
||||
this.hooks.runModule.call(
|
||||
{
|
||||
codeGenerationResult,
|
||||
module,
|
||||
moduleObject
|
||||
},
|
||||
context
|
||||
),
|
||||
"Compilation.hooks.runModule"
|
||||
);
|
||||
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 {RunModuleContext} */
|
||||
const context = {
|
||||
__webpack_require__,
|
||||
chunk,
|
||||
chunkGraph
|
||||
};
|
||||
|
||||
for (const runtimeModule of chunkGraph.getChunkRuntimeModulesInOrder(
|
||||
chunk
|
||||
)) {
|
||||
__webpack_require_module__(
|
||||
runtimeModule,
|
||||
runtimeModule.identifier()
|
||||
);
|
||||
}
|
||||
result = __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, result);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
checkConstraints() {
|
||||
const chunkGraph = this.chunkGraph;
|
||||
|
||||
|
|
|
@ -176,6 +176,20 @@ class AssetModulesPlugin {
|
|||
|
||||
return result;
|
||||
});
|
||||
|
||||
compilation.hooks.runModule.tap(
|
||||
"AssetModulesPlugin",
|
||||
(options, context) => {
|
||||
const { codeGenerationResult } = options;
|
||||
const source = codeGenerationResult.sources.get("asset");
|
||||
if (source === undefined) return;
|
||||
compilation.emitAsset(
|
||||
codeGenerationResult.data.get("filename"),
|
||||
source,
|
||||
codeGenerationResult.data.get("assetInfo")
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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,37 @@
|
|||
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 {
|
||||
/**
|
||||
* Apply the plugin
|
||||
* @param {Compiler} compiler the compiler instance
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
compiler.hooks.compilation.tap(
|
||||
"LoaderPlugin",
|
||||
|
@ -28,6 +47,10 @@ class LoaderPlugin {
|
|||
LoaderDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
compilation.dependencyFactories.set(
|
||||
LoaderImportDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -47,7 +70,7 @@ class LoaderPlugin {
|
|||
name: request
|
||||
};
|
||||
const factory = compilation.dependencyFactories.get(
|
||||
dep.constructor
|
||||
/** @type {DepConstructor} */ (dep.constructor)
|
||||
);
|
||||
if (factory === undefined) {
|
||||
return callback(
|
||||
|
@ -123,6 +146,71 @@ class LoaderPlugin {
|
|||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @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,
|
||||
recursive: true
|
||||
},
|
||||
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.runModule(referencedModule, {}, callback);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @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.runModule.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.runModule.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 }) =>
|
||||
|
|
|
@ -99,7 +99,7 @@ class AsyncQueue {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {T} item a item
|
||||
* @param {T} item an item
|
||||
* @param {Callback<R>} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
|
@ -144,7 +144,7 @@ class AsyncQueue {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param {T} item a item
|
||||
* @param {T} item an item
|
||||
* @returns {void}
|
||||
*/
|
||||
invalidate(item) {
|
||||
|
@ -156,6 +156,29 @@ 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 Error("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}
|
||||
*/
|
||||
|
|
|
@ -421,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",
|
||||
|
@ -1089,6 +1109,13 @@ describe("Defaults", () => {
|
|||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
- "aliasFields": Array [
|
||||
- "browser",
|
||||
- ],
|
||||
+ "aliasFields": Array [],
|
||||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
- "browser",
|
||||
+ "node",
|
||||
@@ ... @@
|
||||
|
@ -1223,6 +1250,13 @@ describe("Defaults", () => {
|
|||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
- "aliasFields": Array [
|
||||
- "browser",
|
||||
- ],
|
||||
+ "aliasFields": Array [],
|
||||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
- "browser",
|
||||
+ "node",
|
||||
+ "electron",
|
||||
|
@ -1339,6 +1373,13 @@ describe("Defaults", () => {
|
|||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
- "aliasFields": Array [
|
||||
- "browser",
|
||||
- ],
|
||||
+ "aliasFields": Array [],
|
||||
@@ ... @@
|
||||
- "browser",
|
||||
@@ ... @@
|
||||
+ "node",
|
||||
@@ ... @@
|
||||
+ "electron",
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
export const red = "#f00";
|
||||
export const green = "#0f0";
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,13 @@
|
|||
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-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,2 @@
|
|||
import { green } from "./colors.js";
|
||||
export default `body { background-color: ${green}; }`;
|
|
@ -0,0 +1,4 @@
|
|||
import { red } from "./colors.js";
|
||||
export default `body { background: url("${
|
||||
new URL("./file.png", import.meta.url).href + __resourceQuery
|
||||
}"); color: ${red}; }`;
|
|
@ -0,0 +1,34 @@
|
|||
/** @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"
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
compiler =>
|
||||
compiler.hooks.done.tap("test case", stats =>
|
||||
expect(stats.compilation.getAsset("assets/file.png")).toHaveProperty(
|
||||
"info",
|
||||
expect.objectContaining({ sourceFilename: "file.png" })
|
||||
)
|
||||
)
|
||||
]
|
||||
};
|
|
@ -345,6 +345,11 @@ declare abstract class AsyncQueue<T, K, R> {
|
|||
};
|
||||
add(item: T, callback: CallbackFunction<R>): void;
|
||||
invalidate(item: T): void;
|
||||
|
||||
/**
|
||||
* Waits for an already started item
|
||||
*/
|
||||
waitFor(item: T, callback: CallbackFunction<R>): void;
|
||||
stop(): void;
|
||||
increaseParallelism(): void;
|
||||
decreaseParallelism(): void;
|
||||
|
@ -1242,6 +1247,7 @@ declare class Compilation {
|
|||
dependencyReferencedExports: SyncWaterfallHook<
|
||||
[(string[] | ReferencedExport)[], Dependency, RuntimeSpec]
|
||||
>;
|
||||
runModule: SyncHook<[RunModuleArgument, RunModuleContext]>;
|
||||
finishModules: AsyncSeriesHook<[Iterable<Module>]>;
|
||||
finishRebuildingModule: AsyncSeriesHook<[Module]>;
|
||||
unseal: SyncHook<[]>;
|
||||
|
@ -1263,14 +1269,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 +1392,7 @@ declare class Compilation {
|
|||
runtimeTemplate: RuntimeTemplate;
|
||||
moduleTemplates: { javascript: ModuleTemplate };
|
||||
moduleGraph: ModuleGraph;
|
||||
chunkGraph?: ChunkGraph;
|
||||
chunkGraph: any;
|
||||
codeGenerationResults: CodeGenerationResults;
|
||||
processDependenciesQueue: AsyncQueue<Module, Module, Module>;
|
||||
addModuleQueue: AsyncQueue<Module, string, Module>;
|
||||
|
@ -1415,6 +1431,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 +1529,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 +1643,11 @@ declare class Compilation {
|
|||
| WebpackPluginInstance
|
||||
)[]
|
||||
): Compiler;
|
||||
runModule(
|
||||
module: Module,
|
||||
options: RunModuleOptions,
|
||||
callback: (err?: WebpackError, exports?: any) => void
|
||||
): void;
|
||||
checkConstraints(): void;
|
||||
|
||||
/**
|
||||
|
@ -5348,6 +5395,7 @@ declare interface KnownStatsModule {
|
|||
cacheable?: boolean;
|
||||
built?: boolean;
|
||||
codeGenerated?: boolean;
|
||||
buildTimeExecuted?: boolean;
|
||||
cached?: boolean;
|
||||
optional?: boolean;
|
||||
orphan?: boolean;
|
||||
|
@ -5484,6 +5532,7 @@ declare class LibManifestPlugin {
|
|||
}
|
||||
declare interface LibraryContext<T> {
|
||||
compilation: Compilation;
|
||||
chunkGraph: ChunkGraph;
|
||||
options: T;
|
||||
}
|
||||
|
||||
|
@ -9253,6 +9302,19 @@ type RuleSetUseItem =
|
|||
options?: string | { [index: string]: any };
|
||||
}
|
||||
| __TypeWebpackOptions;
|
||||
declare interface RunModuleArgument {
|
||||
module: Module;
|
||||
moduleObject: object;
|
||||
codeGenerationResult: CodeGenerationResult;
|
||||
}
|
||||
declare interface RunModuleContext {
|
||||
chunk: Chunk;
|
||||
chunkGraph: ChunkGraph;
|
||||
__webpack_require__: Function;
|
||||
}
|
||||
declare interface RunModuleOptions {
|
||||
entryOptions?: EntryOptions;
|
||||
}
|
||||
declare class RuntimeChunkPlugin {
|
||||
constructor(options?: any);
|
||||
options: any;
|
||||
|
@ -9294,6 +9356,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