fix: a lot of types

This commit is contained in:
Alexander Akait 2024-08-06 18:38:15 +03:00 committed by GitHub
commit 13560eac2e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
59 changed files with 2733 additions and 1134 deletions

View File

@ -292,7 +292,8 @@
"xxhashjs",
"Yann",
"readonly",
"commithash"
"commithash",
"formaters"
],
"ignoreRegExpList": [
"/Author.+/",

View File

@ -1,4 +1,5 @@
import type { SourceMap } from "../lib/NormalModule";
import type Module from "../lib/Module";
import type { validate } from "schema-utils";
import type { AssetInfo } from "../lib/Compilation";
import type { ResolveOptionsWithDependencyType } from "../lib/ResolverFactory";
@ -70,15 +71,15 @@ export interface LoaderPluginLoaderContext {
request: string,
callback: (
err: Error | null,
source: string,
sourceMap: any,
module: NormalModule
source?: string | Buffer,
sourceMap?: object | null,
module?: Module
) => void
): void;
importModule(
request: string,
options: ImportModuleOptions,
options: ImportModuleOptions | undefined,
callback: ImportModuleCallback
): void;
importModule(request: string, options?: ImportModuleOptions): Promise<any>;

View File

@ -22,6 +22,7 @@ const { mergeRuntime } = require("./util/runtime");
/** @typedef {import("./ChunkGraph").ChunkFilterPredicate} ChunkFilterPredicate */
/** @typedef {import("./ChunkGraph").ChunkSizeOptions} ChunkSizeOptions */
/** @typedef {import("./ChunkGraph").ModuleFilterPredicate} ModuleFilterPredicate */
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("./ChunkGroup")} ChunkGroup */
/** @typedef {import("./ChunkGroup").ChunkGroupOptions} ChunkGroupOptions */
/** @typedef {import("./Compilation")} Compilation */
@ -367,7 +368,9 @@ class Chunk {
array = [];
chunkModuleIdMap[/** @type {ChunkId} */ (asyncChunk.id)] = array;
}
const moduleId = chunkGraph.getModuleId(module);
const moduleId =
/** @type {ModuleId} */
(chunkGraph.getModuleId(module));
array.push(moduleId);
chunkModuleHashMap[moduleId] = chunkGraph.getRenderedModuleHash(
module,

View File

@ -30,6 +30,7 @@ const {
/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./Chunk").ChunkId} ChunkId */
/** @typedef {import("./ChunkGroup")} ChunkGroup */
/** @typedef {import("./Module")} Module */
/** @typedef {import("./ModuleGraph")} ModuleGraph */
@ -197,7 +198,7 @@ class ChunkGraphModule {
this.runtimeInChunks = undefined;
/** @type {RuntimeSpecMap<ModuleHashInfo> | undefined} */
this.hashes = undefined;
/** @type {string | number} */
/** @type {ModuleId | null} */
this.id = null;
/** @type {RuntimeSpecMap<Set<string>> | undefined} */
this.runtimeRequirements = undefined;
@ -747,9 +748,9 @@ class ChunkGraph {
if (filterFn(module)) {
if (array === undefined) {
array = [];
chunkModuleIdMap[asyncChunk.id] = array;
chunkModuleIdMap[/** @type {ChunkId} */ (asyncChunk.id)] = array;
}
const moduleId = this.getModuleId(module);
const moduleId = /** @type {ModuleId} */ (this.getModuleId(module));
array.push(moduleId);
}
}
@ -771,13 +772,15 @@ class ChunkGraph {
hashLength = 0,
includeAllChunks = false
) {
/** @type {Record<string|number, Record<string|number, string>>} */
/** @type {Record<ChunkId, Record<string|number, string>>} */
const chunkModuleHashMap = Object.create(null);
/** @typedef {Record<string|number, string>} IdToHashMap */
for (const asyncChunk of includeAllChunks
? chunk.getAllReferencedChunks()
: chunk.getAllAsyncChunks()) {
/** @type {Record<string|number, string> | undefined} */
/** @type {IdToHashMap | undefined} */
let idToHashMap;
for (const module of this.getOrderedChunkModulesIterable(
asyncChunk,
@ -786,11 +789,15 @@ class ChunkGraph {
if (filterFn(module)) {
if (idToHashMap === undefined) {
idToHashMap = Object.create(null);
chunkModuleHashMap[asyncChunk.id] = idToHashMap;
chunkModuleHashMap[/** @type {ChunkId} */ (asyncChunk.id)] =
/** @type {IdToHashMap} */ (idToHashMap);
}
const moduleId = this.getModuleId(module);
const hash = this.getRenderedModuleHash(module, asyncChunk.runtime);
idToHashMap[moduleId] = hashLength ? hash.slice(0, hashLength) : hash;
/** @type {IdToHashMap} */
(idToHashMap)[/** @type {ModuleId} */ (moduleId)] = hashLength
? hash.slice(0, hashLength)
: hash;
}
}
}
@ -806,7 +813,7 @@ class ChunkGraph {
getChunkConditionMap(chunk, filterFn) {
const map = Object.create(null);
for (const c of chunk.getAllReferencedChunks()) {
map[c.id] = filterFn(c, this);
map[/** @type {ChunkId} */ (c.id)] = filterFn(c, this);
}
return map;
}
@ -1109,8 +1116,9 @@ class ChunkGraph {
disconnectChunkAndEntryModule(chunk, module) {
const cgm = this._getChunkGraphModule(module);
const cgc = this._getChunkGraphChunk(chunk);
cgm.entryInChunks.delete(chunk);
if (cgm.entryInChunks.size === 0) {
/** @type {EntryInChunks} */
(cgm.entryInChunks).delete(chunk);
if (/** @type {EntryInChunks} */ (cgm.entryInChunks).size === 0) {
cgm.entryInChunks = undefined;
}
cgc.entryModules.delete(module);
@ -1124,8 +1132,9 @@ class ChunkGraph {
disconnectChunkAndRuntimeModule(chunk, module) {
const cgm = this._getChunkGraphModule(module);
const cgc = this._getChunkGraphChunk(chunk);
cgm.runtimeInChunks.delete(chunk);
if (cgm.runtimeInChunks.size === 0) {
/** @type {RuntimeInChunks} */
(cgm.runtimeInChunks).delete(chunk);
if (/** @type {RuntimeInChunks} */ (cgm.runtimeInChunks).size === 0) {
cgm.runtimeInChunks = undefined;
}
cgc.runtimeModules.delete(module);
@ -1152,8 +1161,9 @@ class ChunkGraph {
const cgc = this._getChunkGraphChunk(chunk);
for (const module of cgc.entryModules.keys()) {
const cgm = this._getChunkGraphModule(module);
cgm.entryInChunks.delete(chunk);
if (cgm.entryInChunks.size === 0) {
/** @type {EntryInChunks} */
(cgm.entryInChunks).delete(chunk);
if (/** @type {EntryInChunks} */ (cgm.entryInChunks).size === 0) {
cgm.entryInChunks = undefined;
}
}
@ -1320,7 +1330,7 @@ class ChunkGraph {
/**
* @param {Module} module the module
* @returns {ModuleId} the id of the module
* @returns {ModuleId | null} the id of the module
*/
getModuleId(module) {
const cgm = this._getChunkGraphModule(module);
@ -1342,7 +1352,7 @@ class ChunkGraph {
* @returns {string | number} the id of the runtime
*/
getRuntimeId(runtime) {
return this._runtimeIds.get(runtime);
return /** @type {string | number} */ (this._runtimeIds.get(runtime));
}
/**
@ -1591,6 +1601,7 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
if (cgm.graphHashesWithConnections === undefined) {
cgm.graphHashesWithConnections = new RuntimeSpecMap();
}
/**
* @param {ConnectionState} state state
* @returns {"F" | "T" | "O"} result
@ -1613,6 +1624,10 @@ Caller might not support runtime-dependent code generation (opt-out via optimiza
const activeNamespaceModules = new Set();
/** @type {Map<string, Module | Set<Module>>} */
const connectedModules = new Map();
/**
* @param {ModuleGraphConnection} connection connection
* @param {string} stateInfo state info
*/
const processConnection = (connection, stateInfo) => {
const module = connection.module;
stateInfo += module.getExportsType(this.moduleGraph, strict);

View File

@ -350,7 +350,7 @@ const { isSourceEqual } = require("./util/source");
* @property {boolean=} forToString
*/
/** @typedef {KnownCreateStatsOptionsContext & Record<string, any>} CreateStatsOptionsContext */
/** @typedef {Record<string, any> & KnownCreateStatsOptionsContext} CreateStatsOptionsContext */
/** @typedef {{module: Module, hash: string, runtime: RuntimeSpec, runtimes: RuntimeSpec[]}[]} CodeGenerationJobs */
@ -571,6 +571,10 @@ class Compilation {
*/
const createProcessAssetsHook = (name, stage, getArgs, code) => {
if (!this._backCompat && code) return;
/**
* @param {string} reason reason
* @returns {string} error message
*/
const errorMessage =
reason => `Can't automatically convert plugin using Compilation.hooks.${name} to Compilation.hooks.processAssets because ${reason}.
BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a single Compilation.hooks.processAssets hook.`;
@ -661,14 +665,14 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
*/
afterChunks: new SyncHook(["chunks"]),
/** @type {SyncBailHook<[Iterable<Module>]>} */
/** @type {SyncBailHook<[Iterable<Module>], boolean | void>} */
optimizeDependencies: new SyncBailHook(["modules"]),
/** @type {SyncHook<[Iterable<Module>]>} */
afterOptimizeDependencies: new SyncHook(["modules"]),
/** @type {SyncHook<[]>} */
optimize: new SyncHook([]),
/** @type {SyncBailHook<[Iterable<Module>]>} */
/** @type {SyncBailHook<[Iterable<Module>], boolean | void>} */
optimizeModules: new SyncBailHook(["modules"]),
/** @type {SyncHook<[Iterable<Module>]>} */
afterOptimizeModules: new SyncHook(["modules"]),
@ -706,7 +710,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
"runtimeRequirements",
"context"
]),
/** @type {HookMap<SyncBailHook<[Module, Set<string>, RuntimeRequirementsContext]>>} */
/** @type {HookMap<SyncBailHook<[Module, Set<string>, RuntimeRequirementsContext], void>>} */
runtimeRequirementInModule: new HookMap(
() => new SyncBailHook(["module", "runtimeRequirements", "context"])
),
@ -716,7 +720,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
"runtimeRequirements",
"context"
]),
/** @type {HookMap<SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext]>>} */
/** @type {HookMap<SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext], void>>} */
runtimeRequirementInTree: new HookMap(
() => new SyncBailHook(["chunk", "runtimeRequirements", "context"])
),
@ -1109,14 +1113,15 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
/**
* @param {string | boolean | StatsOptions | undefined} optionsOrPreset stats option value
* @param {CreateStatsOptionsContext} context context
* @param {CreateStatsOptionsContext=} context context
* @returns {NormalizedStatsOptions} normalized options
*/
createStatsOptions(optionsOrPreset, context = {}) {
if (
typeof optionsOrPreset === "boolean" ||
typeof optionsOrPreset === "string"
) {
if (typeof optionsOrPreset === "boolean") {
optionsOrPreset = {
preset: optionsOrPreset === false ? "none" : "normal"
};
} else if (typeof optionsOrPreset === "string") {
optionsOrPreset = { preset: optionsOrPreset };
}
if (typeof optionsOrPreset === "object" && optionsOrPreset !== null) {
@ -1126,7 +1131,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
const options = {};
// eslint-disable-next-line guard-for-in
for (const key in optionsOrPreset) {
options[key] = optionsOrPreset[key];
options[key] = optionsOrPreset[/** @type {keyof StatsOptions} */ (key)];
}
if (options.preset !== undefined) {
this.hooks.statsPreset.for(options.preset).call(options, context);
@ -2680,6 +2685,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
const logger = this.getLogger("webpack.Compilation.ModuleProfile");
// Avoid coverage problems due indirect changes
/**
* @param {number} value value
* @param {string} msg message
*/
/* istanbul ignore next */
const logByValue = (value, msg) => {
if (value > 1000) {
@ -2891,6 +2900,10 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
* @returns {void}
*/
seal(callback) {
/**
* @param {WebpackError=} err err
* @returns {void}
*/
const finalCallback = err => {
this.factorizeQueue.clear();
this.buildQueue.clear();
@ -3808,6 +3821,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
const moduleGraph = this.moduleGraph;
const queue = new Set([module]);
/** @type {number} */
let depth;
moduleGraph.setDepth(module, 0);
@ -3823,7 +3837,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
for (module of queue) {
queue.delete(module);
depth = moduleGraph.getDepth(module) + 1;
depth = /** @type {number} */ (moduleGraph.getDepth(module)) + 1;
for (const connection of moduleGraph.getOutgoingConnections(module)) {
const refModule = connection.module;

View File

@ -47,13 +47,18 @@ const { isSourceEqual } = require("./util/source");
/** @typedef {import("./Module").BuildInfo} BuildInfo */
/** @typedef {import("./config/target").PlatformTargetProperties} PlatformTargetProperties */
/** @typedef {import("./logging/createConsoleLogger").LoggingFunction} LoggingFunction */
/** @typedef {import("./util/WeakTupleMap")} WeakTupleMap */
/** @typedef {import("./util/fs").IStats} IStats */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/** @typedef {import("./util/fs").IntermediateFileSystem} IntermediateFileSystem */
/** @typedef {import("./util/fs").OutputFileSystem} OutputFileSystem */
/** @typedef {import("./util/fs").WatchFileSystem} WatchFileSystem */
/**
* @template {any[]} T
* @template V
* @typedef {import("./util/WeakTupleMap")<T, V>} WeakTupleMap
*/
/**
* @typedef {object} CompilationParams
* @property {NormalModuleFactory} normalModuleFactory
@ -283,7 +288,7 @@ class Compiler {
this.cache = new Cache();
/** @type {Map<Module, { buildInfo: BuildInfo, references: References | undefined, memCache: WeakTupleMap }> | undefined} */
/** @type {Map<Module, { buildInfo: BuildInfo, references: References | undefined, memCache: WeakTupleMap<any, any> }> | undefined} */
this.moduleMemCaches = undefined;
this.compilerPath = "";

View File

@ -36,6 +36,10 @@ const makeSerializable = require("./util/makeSerializable");
/** @typedef {import("./util/Hash")} Hash */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
/** @typedef {string} SourceRequest */
/** @typedef {"require" | "object"} Type */
/** @typedef {TODO} Data */
const TYPES = new Set(["javascript"]);
const RUNTIME_REQUIREMENTS = new Set([
RuntimeGlobals.module,
@ -44,9 +48,9 @@ const RUNTIME_REQUIREMENTS = new Set([
class DelegatedModule extends Module {
/**
* @param {string} sourceRequest source request
* @param {TODO} data data
* @param {"require" | "object"} type type
* @param {SourceRequest} sourceRequest source request
* @param {Data} data data
* @param {Type} type type
* @param {string} userRequest user request
* @param {string | Module} originalRequest original request
*/

View File

@ -7,15 +7,28 @@
const DelegatedModule = require("./DelegatedModule");
/** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptions} DllReferencePluginOptions */
/** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptionsContent} DllReferencePluginOptionsContent */
/** @typedef {import("./DelegatedModule").Data} Data */
/** @typedef {import("./DelegatedModule").SourceRequest} SourceRequest */
/** @typedef {import("./DelegatedModule").Type} Type */
/** @typedef {import("./NormalModuleFactory")} NormalModuleFactory */
// options.source
// options.type
// options.context
// options.scope
// options.content
// options.associatedObjectForCache
/**
* @typedef {object} Options
* @property {SourceRequest} source source
* @property {NonNullable<DllReferencePluginOptions["context"]>} context absolute context path to which lib ident is relative to
* @property {DllReferencePluginOptionsContent} content content
* @property {DllReferencePluginOptions["type"]} type type
* @property {DllReferencePluginOptions["extensions"]} extensions extensions
* @property {DllReferencePluginOptions["scope"]} scope scope
* @property {object=} associatedObjectForCache object for caching
*/
class DelegatedModuleFactoryPlugin {
/**
* @param {Options} options options
*/
constructor(options) {
this.options = options;
options.type = options.type || "require";
@ -44,14 +57,17 @@ class DelegatedModuleFactoryPlugin {
new DelegatedModule(
this.options.source,
resolved,
this.options.type,
/** @type {Type} */ (this.options.type),
innerRequest,
request
)
);
}
for (let i = 0; i < this.options.extensions.length; i++) {
const extension = this.options.extensions[i];
const extensions =
/** @type {string[]} */
(this.options.extensions);
for (let i = 0; i < extensions.length; i++) {
const extension = extensions[i];
const requestPlusExt = innerRequest + extension;
if (requestPlusExt in this.options.content) {
resolved = this.options.content[requestPlusExt];
@ -60,7 +76,7 @@ class DelegatedModuleFactoryPlugin {
new DelegatedModule(
this.options.source,
resolved,
this.options.type,
/** @type {Type} */ (this.options.type),
requestPlusExt,
request + extension
)
@ -81,7 +97,7 @@ class DelegatedModuleFactoryPlugin {
return new DelegatedModule(
this.options.source,
resolved,
this.options.type,
/** @type {Type} */ (this.options.type),
request,
module
);

View File

@ -9,8 +9,12 @@ const DelegatedModuleFactoryPlugin = require("./DelegatedModuleFactoryPlugin");
const DelegatedSourceDependency = require("./dependencies/DelegatedSourceDependency");
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./DelegatedModuleFactoryPlugin").Options} Options */
class DelegatedPlugin {
/**
* @param {Options} options options
*/
constructor(options) {
this.options = options;
}

View File

@ -328,6 +328,8 @@ Dependency.NO_EXPORTS_REFERENCED = [];
/** @type {string[][]} */
Dependency.EXPORTS_OBJECT_REFERENCED = [[]];
// eslint-disable-next-line no-warning-comments
// @ts-ignore https://github.com/microsoft/TypeScript/issues/42919
Object.defineProperty(Dependency.prototype, "module", {
/**
* @deprecated
@ -350,6 +352,8 @@ Object.defineProperty(Dependency.prototype, "module", {
}
});
// eslint-disable-next-line no-warning-comments
// @ts-ignore https://github.com/microsoft/TypeScript/issues/42919
Object.defineProperty(Dependency.prototype, "disconnect", {
get() {
throw new Error(

View File

@ -10,12 +10,14 @@ const DllEntryDependency = require("./dependencies/DllEntryDependency");
const EntryDependency = require("./dependencies/EntryDependency");
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {string[]} Entries */
/** @typedef {{ name: string, filename: TODO }} Options */
class DllEntryPlugin {
/**
* @param {string} context context
* @param {string[]} entries entry names
* @param {TODO} options options
* @param {Entries} entries entry names
* @param {Options} options options
*/
constructor(context, entries, options) {
this.context = context;

View File

@ -12,6 +12,8 @@ const createSchemaValidation = require("./util/create-schema-validation");
/** @typedef {import("../declarations/plugins/DllPlugin").DllPluginOptions} DllPluginOptions */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./DllEntryPlugin").Entries} Entries */
/** @typedef {import("./DllEntryPlugin").Options} Options */
const validate = createSchemaValidation(
require("../schemas/plugins/DllPlugin.check.js"),
@ -43,13 +45,13 @@ class DllPlugin {
compiler.hooks.entryOption.tap("DllPlugin", (context, entry) => {
if (typeof entry !== "function") {
for (const name of Object.keys(entry)) {
const options = {
name,
filename: entry.filename
};
new DllEntryPlugin(context, entry[name].import, options).apply(
compiler
);
/** @type {Options} */
const options = { name, filename: entry.filename };
new DllEntryPlugin(
context,
/** @type {Entries} */ (entry[name].import),
options
).apply(compiler);
}
} else {
throw new Error(

View File

@ -15,6 +15,7 @@ const makePathsRelative = require("./util/identifier").makePathsRelative;
/** @typedef {import("../declarations/WebpackOptions").Externals} Externals */
/** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptions} DllReferencePluginOptions */
/** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptionsContent} DllReferencePluginOptionsContent */
/** @typedef {import("../declarations/plugins/DllReferencePlugin").DllReferencePluginOptionsManifest} DllReferencePluginOptionsManifest */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
@ -28,6 +29,8 @@ const validate = createSchemaValidation(
}
);
/** @typedef {{ path: string, data: DllReferencePluginOptionsManifest | undefined, error: Error | undefined }} CompilationDataItem */
class DllReferencePlugin {
/**
* @param {DllReferencePluginOptions} options options object
@ -35,7 +38,7 @@ class DllReferencePlugin {
constructor(options) {
validate(options);
this.options = options;
/** @type {WeakMap<object, {path: string, data: DllReferencePluginOptionsManifest?, error: Error?}>} */
/** @type {WeakMap<object, CompilationDataItem>} */
this._compilationData = new WeakMap();
}
@ -64,6 +67,7 @@ class DllReferencePlugin {
/** @type {InputFileSystem} */
(compiler.inputFileSystem).readFile(manifest, (err, result) => {
if (err) return callback(err);
/** @type {CompilationDataItem} */
const data = {
path: manifest,
data: undefined,
@ -79,13 +83,13 @@ class DllReferencePlugin {
// Store the error in the params so that it can
// be added as a compilation error later on.
const manifestPath = makePathsRelative(
compiler.options.context,
/** @type {string} */ (compiler.options.context),
manifest,
compiler.root
);
data.error = new DllManifestError(
manifestPath,
parseErr.message
/** @type {Error} */ (parseErr).message
);
}
this._compilationData.set(params, data);
@ -101,13 +105,15 @@ class DllReferencePlugin {
compiler.hooks.compile.tap("DllReferencePlugin", params => {
let name = this.options.name;
let sourceType = this.options.sourceType;
let content =
let resolvedContent =
"content" in this.options ? this.options.content : undefined;
if ("manifest" in this.options) {
const manifestParameter = this.options.manifest;
let manifest;
if (typeof manifestParameter === "string") {
const data = this._compilationData.get(params);
const data =
/** @type {CompilationDataItem} */
(this._compilationData.get(params));
// If there was an error parsing the manifest
// file, exit now because the error will be added
// as a compilation error in the "compilation" hook.
@ -121,13 +127,13 @@ class DllReferencePlugin {
if (manifest) {
if (!name) name = manifest.name;
if (!sourceType) sourceType = manifest.type;
if (!content) content = manifest.content;
if (!resolvedContent) resolvedContent = manifest.content;
}
}
/** @type {Externals} */
const externals = {};
const source = `dll-reference ${name}`;
externals[source] = name;
externals[source] = /** @type {string} */ (name);
const normalModuleFactory = params.normalModuleFactory;
new ExternalModuleFactoryPlugin(sourceType || "var", externals).apply(
normalModuleFactory
@ -136,8 +142,12 @@ class DllReferencePlugin {
source,
type: this.options.type,
scope: this.options.scope,
context: this.options.context || compiler.options.context,
content,
context:
/** @type {string} */
(this.options.context || compiler.options.context),
content:
/** @type {DllReferencePluginOptionsContent} */
(resolvedContent),
extensions: this.options.extensions,
associatedObjectForCache: compiler.root
}).apply(normalModuleFactory);
@ -149,7 +159,9 @@ class DllReferencePlugin {
if ("manifest" in this.options) {
const manifest = this.options.manifest;
if (typeof manifest === "string") {
const data = this._compilationData.get(params);
const data = /** @type {CompilationDataItem} */ (
this._compilationData.get(params)
);
// If there was an error parsing the manifest file, add the
// error as a compilation error to make the compilation fail.
if (data.error) {

View File

@ -12,15 +12,18 @@ const WebpackError = require("./WebpackError");
/** @typedef {import("./DefinePlugin").CodeValue} CodeValue */
class EnvironmentPlugin {
/**
* @param {(string | string[] | Record<string, string>)[]} keys keys
*/
constructor(...keys) {
if (keys.length === 1 && Array.isArray(keys[0])) {
this.keys = keys[0];
this.defaultValues = {};
} else if (keys.length === 1 && keys[0] && typeof keys[0] === "object") {
this.keys = Object.keys(keys[0]);
this.defaultValues = keys[0];
this.defaultValues = /** @type {Record<string, string>} */ (keys[0]);
} else {
this.keys = keys;
this.keys = /** @type {string[]} */ (keys);
this.defaultValues = {};
}
}

View File

@ -39,7 +39,7 @@ class EvalDevToolModulePlugin {
/**
* @param {EvalDevToolModulePluginOptions=} options options
*/
constructor(options) {
constructor(options = {}) {
this.namespace = options.namespace || "";
this.sourceUrlComment = options.sourceUrlComment || "\n//# sourceURL=[url]";
this.moduleFilenameTemplate =

View File

@ -17,6 +17,7 @@ const { makePathsAbsolute } = require("./util/identifier");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../declarations/WebpackOptions").DevTool} DevToolOptions */
/** @typedef {import("../declarations/plugins/SourceMapDevToolPlugin").SourceMapDevToolPluginOptions} SourceMapDevToolPluginOptions */
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./NormalModule").SourceMap} SourceMap */
@ -163,7 +164,9 @@ class EvalSourceMapDevToolPlugin {
sourceMap.sourcesContent = undefined;
}
sourceMap.sourceRoot = options.sourceRoot || "";
const moduleId = chunkGraph.getModuleId(m);
const moduleId =
/** @type {ModuleId} */
(chunkGraph.getModuleId(m));
sourceMap.file =
typeof moduleId === "number" ? `${moduleId}.js` : moduleId;

View File

@ -71,9 +71,11 @@ makeSerializable(
"RestoreProvidedData"
);
/** @typedef {Map<string, ExportInfo>} Exports */
class ExportsInfo {
constructor() {
/** @type {Map<string, ExportInfo>} */
/** @type {Exports} */
this._exports = new Map();
this._otherExportsInfo = new ExportInfo(null);
this._sideEffectsOnlyInfo = new ExportInfo("*side effects only*");
@ -144,6 +146,10 @@ class ExportsInfo {
return this._otherExportsInfo;
}
/**
* @param {Exports} exports exports
* @private
*/
_sortExportsMap(exports) {
if (exports.size > 1) {
const namesInOrder = [];
@ -520,7 +526,7 @@ class ExportsInfo {
return false;
}
}
return new SortableSet(array);
return /** @type {SortableSet<string>} */ (new SortableSet(array));
}
/**
@ -796,6 +802,8 @@ class ExportsInfo {
}
}
/** @typedef {Map<any, { connection: ModuleGraphConnection | null, export: string[], priority: number }>} Target */
class ExportInfo {
/**
* @param {string} name the original name of the export
@ -811,7 +819,7 @@ class ExportInfo {
this._usedName = initFrom ? initFrom._usedName : null;
/**
* @private
* @type {UsageStateType}
* @type {UsageStateType | undefined}
*/
this._globalUsed = initFrom ? initFrom._globalUsed : undefined;
/**
@ -858,9 +866,9 @@ class ExportInfo {
this.canMangleUse = initFrom ? initFrom.canMangleUse : undefined;
/** @type {boolean} */
this.exportsInfoOwned = false;
/** @type {ExportsInfo=} */
/** @type {ExportsInfo | undefined} */
this.exportsInfo = undefined;
/** @type {Map<any, { connection: ModuleGraphConnection | null, export: string[], priority: number }>=} */
/** @type {Target | undefined} */
this._target = undefined;
if (initFrom && initFrom._target) {
this._target = new Map();
@ -872,7 +880,7 @@ class ExportInfo {
});
}
}
/** @type {Map<any, { connection: ModuleGraphConnection | null, export: string[], priority: number }>=} */
/** @type {Target | undefined} */
this._maxTarget = undefined;
}
@ -1004,8 +1012,9 @@ class ExportInfo {
} else {
let changed = false;
forEachRuntime(runtime, runtime => {
/** @type {UsageStateType} */
let oldValue = this._usedInRuntime.get(runtime);
let oldValue =
/** @type {UsageStateType} */
(this._usedInRuntime.get(runtime));
if (oldValue === undefined) oldValue = UsageState.Unused;
if (newValue !== oldValue && condition(oldValue)) {
if (newValue === UsageState.Unused) {
@ -1046,8 +1055,9 @@ class ExportInfo {
} else {
let changed = false;
forEachRuntime(runtime, runtime => {
/** @type {UsageStateType} */
let oldValue = this._usedInRuntime.get(runtime);
let oldValue =
/** @type {UsageStateType} */
(this._usedInRuntime.get(runtime));
if (oldValue === undefined) oldValue = UsageState.Unused;
if (newValue !== oldValue) {
if (newValue === UsageState.Unused) {
@ -1108,7 +1118,7 @@ class ExportInfo {
: oldTarget.export)
) {
oldTarget.connection = connection;
oldTarget.export = exportName;
oldTarget.export = /** @type {string[]} */ (exportName);
oldTarget.priority = priority;
this._maxTarget = undefined;
return true;
@ -1181,7 +1191,7 @@ class ExportInfo {
}
}
if (this._usedName !== null) return this._usedName;
return this.name || fallbackName;
return /** @type {string | false} */ (this.name || fallbackName);
}
/**
@ -1220,10 +1230,11 @@ class ExportInfo {
_getMaxTarget() {
if (this._maxTarget !== undefined) return this._maxTarget;
if (this._target.size <= 1) return (this._maxTarget = this._target);
if (/** @type {Target} */ (this._target).size <= 1)
return (this._maxTarget = this._target);
let maxPriority = -Infinity;
let minPriority = Infinity;
for (const { priority } of this._target.values()) {
for (const { priority } of /** @type {Target} */ (this._target).values()) {
if (maxPriority < priority) maxPriority = priority;
if (minPriority > priority) minPriority = priority;
}
@ -1232,7 +1243,7 @@ class ExportInfo {
// This is an edge case
const map = new Map();
for (const [key, value] of this._target) {
for (const [key, value] of /** @type {Target} */ (this._target)) {
if (maxPriority === value.priority) {
map.set(key, value);
}
@ -1244,7 +1255,7 @@ class ExportInfo {
/**
* @param {ModuleGraph} moduleGraph the module graph
* @param {function(Module): boolean} validTargetModuleFilter a valid target module
* @returns {{ module: Module, export: string[] | undefined } | undefined | false} the target, undefined when there is no target, false when no target is valid
* @returns {{ module: Module, export: string[] | undefined } | null | undefined | false} the target, undefined when there is no target, false when no target is valid
*/
findTarget(moduleGraph, validTargetModuleFilter) {
return this._findTarget(moduleGraph, validTargetModuleFilter, new Set());
@ -1254,11 +1265,13 @@ class ExportInfo {
* @param {ModuleGraph} moduleGraph the module graph
* @param {function(Module): boolean} validTargetModuleFilter a valid target module
* @param {Set<ExportInfo>} alreadyVisited set of already visited export info to avoid circular references
* @returns {{ module: Module, export: string[] | undefined } | undefined | false} the target, undefined when there is no target, false when no target is valid
* @returns {{ module: Module, export: string[] | undefined } | null | undefined | false} the target, undefined when there is no target, false when no target is valid
*/
_findTarget(moduleGraph, validTargetModuleFilter, alreadyVisited) {
if (!this._target || this._target.size === 0) return;
const rawTarget = this._getMaxTarget().values().next().value;
const rawTarget =
/** @type {Target} */
(this._getMaxTarget()).values().next().value;
if (!rawTarget) return;
/** @type {{ module: Module, export: string[] | undefined }} */
let target = {
@ -1366,7 +1379,7 @@ class ExportInfo {
if (alreadyVisited && alreadyVisited.has(this)) return CIRCULAR;
const newAlreadyVisited = new Set(alreadyVisited);
newAlreadyVisited.add(this);
const values = this._getMaxTarget().values();
const values = /** @type {Target} */ (this._getMaxTarget()).values();
const target = resolveTarget(values.next().value, newAlreadyVisited);
if (target === CIRCULAR) return CIRCULAR;
if (target === null) return;
@ -1398,15 +1411,19 @@ class ExportInfo {
const target = this._getTarget(moduleGraph, resolveTargetFilter, undefined);
if (target === CIRCULAR) return;
if (!target) return;
const originalTarget = this._getMaxTarget().values().next().value;
const originalTarget =
/** @type {Target} */
(this._getMaxTarget()).values().next().value;
if (
originalTarget.connection === target.connection &&
originalTarget.export === target.export
) {
return;
}
this._target.clear();
this._target.set(undefined, {
/** @type {Target} */
(this._target).clear();
/** @type {Target} */
(this._target).set(undefined, {
connection: updateOriginalConnection
? updateOriginalConnection(target)
: target.connection,
@ -1432,6 +1449,11 @@ class ExportInfo {
return this.exportsInfo;
}
/**
* @param {ExportInfo} baseInfo base info
* @param {RuntimeSpec} runtime runtime
* @returns {boolean} true when has info, otherwise false
*/
hasInfo(baseInfo, runtime) {
return (
(this._usedName && this._usedName !== this.name) ||
@ -1441,10 +1463,20 @@ class ExportInfo {
);
}
/**
* @param {Hash} hash the hash
* @param {RuntimeSpec} runtime the runtime
* @returns {void}
*/
updateHash(hash, runtime) {
this._updateHash(hash, runtime, new Set());
}
/**
* @param {Hash} hash the hash
* @param {RuntimeSpec} runtime the runtime
* @param {Set<ExportsInfo>} alreadyVisitedExportsInfo for circular references
*/
_updateHash(hash, runtime, alreadyVisitedExportsInfo) {
hash.update(
`${this._usedName || this.name}${this.getUsed(runtime)}${this.provided}${

View File

@ -719,7 +719,8 @@ class ExternalModule extends Module {
request,
/** @type {string} */
(runtimeTemplate.outputOptions.importMetaName),
runtimeTemplate.supportNodePrefixForCoreModules()
/** @type {boolean} */
(runtimeTemplate.supportNodePrefixForCoreModules())
)
: getSourceForCommonJsExternal(request);
case "amd":

File diff suppressed because it is too large Load Diff

View File

@ -44,8 +44,10 @@ const {
/** @typedef {import("estree").CallExpression} CallExpression */
/** @typedef {import("estree").Expression} Expression */
/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputNormalized */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./Chunk").ChunkId} ChunkId */
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
@ -62,7 +64,8 @@ const {
* @property {SyncBailHook<[TODO, string[]], void>} hotAcceptWithoutCallback
*/
/** @typedef {Map<string, { updatedChunkIds: Set<ChunkId>, removedChunkIds: Set<ChunkId>, removedModules: Set<Module>, filename: string, assetInfo: AssetInfo }>} HotUpdateMainContentByRuntime */
/** @typedef {{ updatedChunkIds: Set<ChunkId>, removedChunkIds: Set<ChunkId>, removedModules: Set<Module>, filename: string, assetInfo: AssetInfo }} HotUpdateMainContentByRuntimeItem */
/** @typedef {Map<string, HotUpdateMainContentByRuntimeItem>} HotUpdateMainContentByRuntime */
/** @type {WeakMap<JavascriptParser, HMRJavascriptParserHooks>} */
const parserHooksMap = new WeakMap();
@ -512,7 +515,8 @@ class HotModuleReplacementPlugin {
forEachRuntime(allOldRuntime, runtime => {
const { path: filename, info: assetInfo } =
compilation.getPathWithInfo(
compilation.outputOptions.hotUpdateMainFilename,
/** @type {NonNullable<OutputNormalized["hotUpdateMainFilename"]>} */
(compilation.outputOptions.hotUpdateMainFilename),
{
hash: records.hash,
runtime
@ -535,7 +539,9 @@ class HotModuleReplacementPlugin {
/** @type {Map<number|string, Module>} */
const allModules = new Map();
for (const module of compilation.modules) {
const id = chunkGraph.getModuleId(module);
const id =
/** @type {ModuleId} */
(chunkGraph.getModuleId(module));
allModules.set(id, module);
}
@ -606,9 +612,13 @@ class HotModuleReplacementPlugin {
if (removedFromRuntime) {
// chunk was removed from some runtimes
forEachRuntime(removedFromRuntime, runtime => {
const item = hotUpdateMainContentByRuntime.get(
/** @type {string} */ (runtime)
);
const item =
/** @type {HotUpdateMainContentByRuntimeItem} */
(
hotUpdateMainContentByRuntime.get(
/** @type {string} */ (runtime)
)
);
item.removedChunkIds.add(/** @type {ChunkId} */ (chunkId));
});
// dispose modules from the chunk in these runtimes
@ -655,9 +665,12 @@ class HotModuleReplacementPlugin {
)
return;
}
const item = hotUpdateMainContentByRuntime.get(
/** @type {string} */ (runtime)
);
const item =
/** @type {HotUpdateMainContentByRuntimeItem} */ (
hotUpdateMainContentByRuntime.get(
/** @type {string} */ (runtime)
)
);
item.removedModules.add(module);
});
}
@ -732,9 +745,12 @@ class HotModuleReplacementPlugin {
}
}
forEachRuntime(newRuntime, runtime => {
const item = hotUpdateMainContentByRuntime.get(
/** @type {string} */ (runtime)
);
const item =
/** @type {HotUpdateMainContentByRuntimeItem} */ (
hotUpdateMainContentByRuntime.get(
/** @type {string} */ (runtime)
)
);
item.updatedChunkIds.add(/** @type {ChunkId} */ (chunkId));
});
}
@ -789,8 +805,10 @@ To fix this, make sure to include [runtime] in the output.hotUpdateMainFilename
removedModules.size === 0
? completelyRemovedModulesArray
: completelyRemovedModulesArray.concat(
Array.from(removedModules, m =>
chunkGraph.getModuleId(m)
Array.from(
removedModules,
m =>
/** @type {ModuleId} */ (chunkGraph.getModuleId(m))
)
)
};

View File

@ -11,6 +11,7 @@ const { someInIterable } = require("./util/IterableHelpers");
const { compareModulesById } = require("./util/comparators");
const { dirname, mkdirp } = require("./util/fs");
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./Compiler").IntermediateFileSystem} IntermediateFileSystem */
/** @typedef {import("./Module").BuildMeta} BuildMeta */
@ -102,7 +103,7 @@ class LibManifestPlugin {
const providedExports = exportsInfo.getProvidedExports();
/** @type {ManifestModuleData} */
const data = {
id: chunkGraph.getModuleId(module),
id: /** @type {ModuleId} */ (chunkGraph.getModuleId(module)),
buildMeta: /** @type {BuildMeta} */ (module.buildMeta),
exports: Array.isArray(providedExports)
? providedExports

View File

@ -81,7 +81,7 @@ const makeSerializable = require("./util/makeSerializable");
* @typedef {object} CodeGenerationResult
* @property {Map<string, Source>} sources the resulting sources for all source types
* @property {Map<string, any>=} data the resulting data for all source types
* @property {ReadOnlyRuntimeRequirements} runtimeRequirements the runtime requirements
* @property {ReadOnlyRuntimeRequirements | null} runtimeRequirements the runtime requirements
* @property {string=} hash a hash of the code generation result (will be automatically calculated from sources and runtimeRequirements if not provided)
*/
@ -897,7 +897,11 @@ class Module extends DependenciesBlock {
};
const sources = this.codeGeneration(codeGenContext).sources;
return type ? sources.get(type) : sources.get(first(this.getSourceTypes()));
return /** @type {Source} */ (
type
? sources.get(type)
: sources.get(/** @type {string} */ (first(this.getSourceTypes())))
);
}
/* istanbul ignore next */
@ -1103,6 +1107,8 @@ class Module extends DependenciesBlock {
makeSerializable(Module, "webpack/lib/Module");
// TODO remove in webpack 6
// eslint-disable-next-line no-warning-comments
// @ts-ignore https://github.com/microsoft/TypeScript/issues/42919
Object.defineProperty(Module.prototype, "hasEqualsChunks", {
get() {
throw new Error(
@ -1112,6 +1118,8 @@ Object.defineProperty(Module.prototype, "hasEqualsChunks", {
});
// TODO remove in webpack 6
// eslint-disable-next-line no-warning-comments
// @ts-ignore https://github.com/microsoft/TypeScript/issues/42919
Object.defineProperty(Module.prototype, "isUsed", {
get() {
throw new Error(
@ -1157,6 +1165,8 @@ Object.defineProperty(Module.prototype, "warnings", {
});
// TODO remove in webpack 6
// eslint-disable-next-line no-warning-comments
// @ts-ignore https://github.com/microsoft/TypeScript/issues/42919
Object.defineProperty(Module.prototype, "used", {
get() {
throw new Error(

View File

@ -30,7 +30,7 @@ class ModuleDependencyError extends WebpackError {
/** error is not (de)serialized, so it might be undefined after deserialization */
this.error = err;
if (err && /** @type {any} */ (err).hideStack) {
if (err && /** @type {any} */ (err).hideStack && err.stack) {
this.stack = /** @type {string} */ `${err.stack
.split("\n")
.slice(1)

View File

@ -30,7 +30,7 @@ class ModuleDependencyWarning extends WebpackError {
/** error is not (de)serialized, so it might be undefined after deserialization */
this.error = err;
if (err && /** @type {any} */ (err).hideStack) {
if (err && /** @type {any} */ (err).hideStack && err.stack) {
this.stack = /** @type {string} */ `${err.stack
.split("\n")
.slice(1)

View File

@ -8,15 +8,25 @@
const identifierUtils = require("./util/identifier");
/** @typedef {import("../declarations/WebpackOptions").StatsOptions} StatsOptions */
/** @typedef {import("./Compilation").CreateStatsOptionsContext} CreateStatsOptionsContext */
/** @typedef {import("./Compilation").NormalizedStatsOptions} NormalizedStatsOptions */
/** @typedef {import("./Stats")} Stats */
/** @typedef {import("./stats/DefaultStatsFactoryPlugin").KnownStatsCompilation} KnownStatsCompilation */
/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
/** @typedef {import("./stats/DefaultStatsFactoryPlugin").StatsError} StatsError */
/**
* @param {string} str string
* @param {string} prefix pref
* @returns {string} indent
*/
const indent = (str, prefix) => {
const rem = str.replace(/\n([^\n])/g, `\n${prefix}$1`);
return prefix + rem;
};
/** @typedef {{ version: boolean, hash: boolean, errorsCount: boolean, warningsCount: boolean, errors: boolean, warnings: boolean, children: NormalizedStatsOptions[] }} ChildOptions */
class MultiStats {
/**
* @param {Stats[]} stats the child stats
@ -43,13 +53,30 @@ class MultiStats {
return this.stats.some(stat => stat.hasWarnings());
}
/**
* @param {string | boolean | StatsOptions | undefined} options stats options
* @param {CreateStatsOptionsContext} context context
* @returns {ChildOptions} context context
*/
_createChildOptions(options, context) {
if (!options) {
options = {};
}
const { children: childrenOptions = undefined, ...baseOptions } =
typeof options === "string" ? { preset: options } : options;
const getCreateStatsOptions = () => {
if (!options) {
options = {};
}
const { children: childrenOptions = undefined, ...baseOptions } =
typeof options === "string"
? { preset: options }
: /** @type {StatsOptions} */ (options);
return { childrenOptions, baseOptions };
};
const children = this.stats.map((stat, idx) => {
if (typeof options === "boolean") {
return stat.compilation.createStatsOptions(options, context);
}
const { childrenOptions, baseOptions } = getCreateStatsOptions();
const childOptions = Array.isArray(childrenOptions)
? childrenOptions[idx]
: childrenOptions;
@ -77,77 +104,96 @@ class MultiStats {
}
/**
* @param {any} options stats options
* @param {(string | boolean | StatsOptions)=} options stats options
* @returns {StatsCompilation} json output
*/
toJson(options) {
options = this._createChildOptions(options, { forToString: false });
const childOptions = this._createChildOptions(options, {
forToString: false
});
/** @type {KnownStatsCompilation} */
const obj = {};
obj.children = this.stats.map((stat, idx) => {
const obj = stat.toJson(options.children[idx]);
const obj = stat.toJson(childOptions.children[idx]);
const compilationName = stat.compilation.name;
const name =
compilationName &&
identifierUtils.makePathsRelative(
options.context,
stat.compilation.compiler.context,
compilationName,
stat.compilation.compiler.root
);
obj.name = name;
return obj;
});
if (options.version) {
if (childOptions.version) {
obj.version = obj.children[0].version;
}
if (options.hash) {
if (childOptions.hash) {
obj.hash = obj.children.map(j => j.hash).join("");
}
/**
* @param {StatsCompilation} j stats error
* @param {StatsError} obj Stats error
* @returns {TODO} result
*/
const mapError = (j, obj) => ({
...obj,
compilerPath: obj.compilerPath ? `${j.name}.${obj.compilerPath}` : j.name
});
if (options.errors) {
if (childOptions.errors) {
obj.errors = [];
for (const j of obj.children) {
for (const i of j.errors) {
const errors =
/** @type {NonNullable<KnownStatsCompilation["errors"]>} */
(j.errors);
for (const i of errors) {
obj.errors.push(mapError(j, i));
}
}
}
if (options.warnings) {
if (childOptions.warnings) {
obj.warnings = [];
for (const j of obj.children) {
for (const i of j.warnings) {
const warnings =
/** @type {NonNullable<KnownStatsCompilation["warnings"]>} */
(j.warnings);
for (const i of warnings) {
obj.warnings.push(mapError(j, i));
}
}
}
if (options.errorsCount) {
if (childOptions.errorsCount) {
obj.errorsCount = 0;
for (const j of obj.children) {
obj.errorsCount += j.errorsCount;
obj.errorsCount += /** @type {number} */ (j.errorsCount);
}
}
if (options.warningsCount) {
if (childOptions.warningsCount) {
obj.warningsCount = 0;
for (const j of obj.children) {
obj.warningsCount += j.warningsCount;
obj.warningsCount += /** @type {number} */ (j.warningsCount);
}
}
return obj;
}
/**
* @param {(string | boolean | StatsOptions)=} options stats options
* @returns {string} string output
*/
toString(options) {
options = this._createChildOptions(options, { forToString: true });
const childOptions = this._createChildOptions(options, {
forToString: true
});
const results = this.stats.map((stat, idx) => {
const str = stat.toString(options.children[idx]);
const str = stat.toString(childOptions.children[idx]);
const compilationName = stat.compilation.name;
const name =
compilationName &&
identifierUtils
.makePathsRelative(
options.context,
stat.compilation.compiler.context,
compilationName,
stat.compilation.compiler.root
)

View File

@ -88,6 +88,16 @@ const memoize = require("./util/memoize");
/** @typedef {UnsafeCacheData & { parser: undefined | Parser, parserOptions: undefined | ParserOptions, generator: undefined | Generator, generatorOptions: undefined | GeneratorOptions }} NormalModuleUnsafeCacheData */
/**
* @template T
* @typedef {import("../declarations/LoaderContext").LoaderContext<T>} LoaderContext
*/
/**
* @template T
* @typedef {import("../declarations/LoaderContext").NormalModuleLoaderContext<T>} NormalModuleLoaderContext
*/
/**
* @typedef {object} SourceMap
* @property {number} version
@ -184,6 +194,9 @@ const asBuffer = input => {
};
class NonErrorEmittedError extends WebpackError {
/**
* @param {any} error value which is not an instance of Error
*/
constructor(error) {
super();
@ -200,12 +213,12 @@ makeSerializable(
/**
* @typedef {object} NormalModuleCompilationHooks
* @property {SyncHook<[object, NormalModule]>} loader
* @property {SyncHook<[LoaderItem[], NormalModule, object]>} beforeLoaders
* @property {SyncHook<[LoaderContext<any>, NormalModule]>} loader
* @property {SyncHook<[LoaderItem[], NormalModule, LoaderContext<any>]>} beforeLoaders
* @property {SyncHook<[NormalModule]>} beforeParse
* @property {SyncHook<[NormalModule]>} beforeSnapshot
* @property {HookMap<AsyncSeriesBailHook<[string, NormalModule], string | Buffer>>} readResourceForScheme
* @property {HookMap<AsyncSeriesBailHook<[object], string | Buffer>>} readResource
* @property {HookMap<AsyncSeriesBailHook<[string, NormalModule], string | Buffer | null>>} readResourceForScheme
* @property {HookMap<AsyncSeriesBailHook<[LoaderContext<any>], string | Buffer>>} readResource
* @property {AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>} needBuild
*/
@ -251,20 +264,32 @@ class NormalModule extends Module {
beforeSnapshot: new SyncHook(["module"]),
// TODO webpack 6 deprecate
readResourceForScheme: new HookMap(scheme => {
const hook = hooks.readResource.for(scheme);
const hook =
/** @type {NormalModuleCompilationHooks} */
(hooks).readResource.for(scheme);
return createFakeHook(
/** @type {AsyncSeriesBailHook<[string, NormalModule], string | Buffer>} */ ({
tap: (options, fn) =>
hook.tap(options, loaderContext =>
fn(loaderContext.resource, loaderContext._module)
fn(
loaderContext.resource,
/** @type {NormalModule} */ (loaderContext._module)
)
),
tapAsync: (options, fn) =>
hook.tapAsync(options, (loaderContext, callback) =>
fn(loaderContext.resource, loaderContext._module, callback)
fn(
loaderContext.resource,
/** @type {NormalModule} */ (loaderContext._module),
callback
)
),
tapPromise: (options, fn) =>
hook.tapPromise(options, loaderContext =>
fn(loaderContext.resource, loaderContext._module)
fn(
loaderContext.resource,
/** @type {NormalModule} */ (loaderContext._module)
)
)
})
);
@ -741,7 +766,7 @@ class NormalModule extends Module {
Object.assign(loaderContext, options.loader);
hooks.loader.call(loaderContext, this);
hooks.loader.call(/** @type {LoaderContext<any>} */ (loaderContext), this);
return loaderContext;
}
@ -889,7 +914,11 @@ class NormalModule extends Module {
buildInfo.cacheable = true;
try {
hooks.beforeLoaders.call(this.loaders, this, loaderContext);
hooks.beforeLoaders.call(
this.loaders,
this,
/** @type {LoaderContext<any>} */ (loaderContext)
);
} catch (err) {
processResult(err);
return;
@ -1509,7 +1538,8 @@ class NormalModule extends Module {
*/
updateHash(hash, context) {
hash.update(/** @type {BuildInfo} */ (this.buildInfo).hash);
this.generator.updateHash(hash, {
/** @type {Generator} */
(this.generator).updateHash(hash, {
module: this,
...context
});

View File

@ -1165,7 +1165,9 @@ If changing the source code is not an option there is also a resolve options cal
}
if (err) return callback(err);
const parsedResult = this._parseResourceWithoutFragment(result);
const parsedResult = this._parseResourceWithoutFragment(
/** @type {string} */ (result)
);
const type = /\.mjs$/i.test(parsedResult.path)
? "module"

View File

@ -108,7 +108,7 @@ const getTaskForFile = (
source = asset.source();
}
if (!sourceMap || typeof source !== "string") return;
const context = compilation.options.context;
const context = /** @type {string} */ (compilation.options.context);
const root = compilation.compiler.root;
const cachedAbsolutify = makePathsAbsolute.bindContextCache(context, root);
const modules = sourceMap.sources.map(source => {
@ -137,8 +137,7 @@ class SourceMapDevToolPlugin {
constructor(options = {}) {
validate(options);
/** @type {string | false} */
this.sourceMapFilename = options.filename;
this.sourceMapFilename = /** @type {string | false} */ (options.filename);
/** @type {string | false | (function(PathData, AssetInfo=): string)}} */
this.sourceMappingURLComment =
options.append === false

View File

@ -55,13 +55,11 @@ class Stats {
* @returns {StatsCompilation} json output
*/
toJson(options) {
options = this.compilation.createStatsOptions(options, {
const normalizedOptions = this.compilation.createStatsOptions(options, {
forToString: false
});
const statsFactory = this.compilation.createStatsFactory(
/** @type {NormalizedStatsOptions} */ (options)
);
const statsFactory = this.compilation.createStatsFactory(normalizedOptions);
return statsFactory.create("compilation", this.compilation, {
compilation: this.compilation
@ -73,16 +71,12 @@ class Stats {
* @returns {string} string output
*/
toString(options) {
options = this.compilation.createStatsOptions(options, {
const normalizedOptions = this.compilation.createStatsOptions(options, {
forToString: true
});
const statsFactory = this.compilation.createStatsFactory(
/** @type {NormalizedStatsOptions} */ (options)
);
const statsPrinter = this.compilation.createStatsPrinter(
/** @type {NormalizedStatsOptions} */ (options)
);
const statsFactory = this.compilation.createStatsFactory(normalizedOptions);
const statsPrinter = this.compilation.createStatsPrinter(normalizedOptions);
const data = statsFactory.create("compilation", this.compilation, {
compilation: this.compilation

View File

@ -13,6 +13,7 @@ const RuntimeGlobals = require("./RuntimeGlobals");
/** @typedef {import("../declarations/WebpackOptions").Output} OutputOptions */
/** @typedef {import("./Chunk")} Chunk */
/** @typedef {import("./ChunkGraph")} ChunkGraph */
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("./CodeGenerationResults")} CodeGenerationResults */
/** @typedef {import("./Compilation").AssetInfo} AssetInfo */
/** @typedef {import("./Compilation").PathData} PathData */
@ -294,7 +295,7 @@ class Template {
}
/** @type {{id: string|number, source: Source|string}[]} */
const allModules = modules.map(module => ({
id: chunkGraph.getModuleId(module),
id: /** @type {ModuleId} */ (chunkGraph.getModuleId(module)),
source: renderModule(module) || "false"
}));
const bounds = Template.getModulesArrayBounds(allModules);

View File

@ -52,6 +52,8 @@ const webpackSchema = require("../schemas/WebpackOptions.json");
* @property {ArgumentConfig[]} configs
*/
/** @typedef {string | number | boolean | RegExp | (string | number | boolean | RegExp)} Value */
/**
* @param {any=} schema a json schema to create arguments for (by default webpack schema is used)
* @returns {Record<string, Argument>} object of arguments
@ -60,6 +62,10 @@ const getArguments = (schema = webpackSchema) => {
/** @type {Record<string, Argument>} */
const flags = {};
/**
* @param {string} input input
* @returns {string} result
*/
const pathToArgumentName = input =>
input
.replace(/\./g, "-")
@ -71,6 +77,10 @@ const getArguments = (schema = webpackSchema) => {
.replace(/-?[^\p{Uppercase_Letter}\p{Lowercase_Letter}\d]+/gu, "-")
.toLowerCase();
/**
* @param {string} path path
* @returns {any} schema part
*/
const getSchemaPart = path => {
const newPath = path.split("/");
@ -131,7 +141,7 @@ const getArguments = (schema = webpackSchema) => {
/**
* @param {any} schemaPart schema
* @returns {Pick<ArgumentConfig, "type"|"values">} partial argument config
* @returns {Pick<ArgumentConfig, "type"|"values"> | undefined} partial argument config
*/
const schemaToArgumentConfig = schemaPart => {
if (schemaPart.enum) {
@ -342,36 +352,49 @@ const getArguments = (schema = webpackSchema) => {
traverse(schema);
/** @typedef {"string" | "number" | "boolean"} Type */
// Summarize flags
for (const name of Object.keys(flags)) {
const argument = flags[name];
argument.description = argument.configs.reduce((desc, { description }) => {
if (!desc) return description;
if (!description) return desc;
if (desc.includes(description)) return desc;
return `${desc} ${description}`;
}, /** @type {string | undefined} */ (undefined));
argument.simpleType = argument.configs.reduce((t, argConfig) => {
/** @type {"string" | "number" | "boolean"} */
let type = "string";
switch (argConfig.type) {
case "number":
type = "number";
break;
case "reset":
case "boolean":
type = "boolean";
break;
case "enum":
if (argConfig.values.every(v => typeof v === "boolean"))
type = "boolean";
if (argConfig.values.every(v => typeof v === "number"))
type = "number";
break;
}
if (t === undefined) return type;
return t === type ? t : "string";
}, /** @type {"string" | "number" | "boolean" | undefined} */ (undefined));
argument.description =
/** @type {string} */
(
argument.configs.reduce((desc, { description }) => {
if (!desc) return description;
if (!description) return desc;
if (desc.includes(description)) return desc;
return `${desc} ${description}`;
}, /** @type {string | undefined} */ (undefined))
);
argument.simpleType =
/** @type {Type} */
(
argument.configs.reduce((t, argConfig) => {
/** @type {Type} */
let type = "string";
switch (argConfig.type) {
case "number":
type = "number";
break;
case "reset":
case "boolean":
type = "boolean";
break;
case "enum": {
const values =
/** @type {NonNullable<ArgumentConfig["values"]>} */
(argConfig.values);
if (values.every(v => typeof v === "boolean")) type = "boolean";
if (values.every(v => typeof v === "number")) type = "number";
break;
}
}
if (t === undefined) return type;
return t === type ? t : "string";
}, /** @type {Type | undefined} */ (undefined))
);
argument.multiple = argument.configs.some(c => c.multiple);
}
@ -380,16 +403,18 @@ const getArguments = (schema = webpackSchema) => {
const cliAddedItems = new WeakMap();
/** @typedef {string | number} Property */
/**
* @param {any} config configuration
* @param {string} schemaPath path in the config
* @param {number | undefined} index index of value when multiple values are provided, otherwise undefined
* @returns {{ problem?: LocalProblem, object?: any, property?: string | number, value?: any }} problem or object with property and value
* @returns {{ problem?: LocalProblem, object?: any, property?: Property, value?: any }} problem or object with property and value
*/
const getObjectAndProperty = (config, schemaPath, index = 0) => {
if (!schemaPath) return { value: config };
const parts = schemaPath.split(".");
const property = parts.pop();
const property = /** @type {string} */ (parts.pop());
let current = config;
let i = 0;
for (const part of parts) {
@ -494,7 +519,7 @@ const setValue = (config, schemaPath, value, index) => {
index
);
if (problem) return problem;
object[property] = value;
object[/** @type {Property} */ (property)] = value;
return null;
};
@ -536,7 +561,11 @@ const getExpectedValue = argConfig => {
case "RegExp":
return "regular expression (example: /ab?c*/)";
case "enum":
return argConfig.values.map(v => `${v}`).join(" | ");
return /** @type {NonNullable<ArgumentConfig["values"]>} */ (
argConfig.values
)
.map(v => `${v}`)
.join(" | ");
case "reset":
return "true (will reset the previous value to an empty array)";
default:
@ -582,12 +611,16 @@ const parseValueForArgumentConfig = (argConfig, value) => {
return new RegExp(match[1], match[2]);
}
break;
case "enum":
if (argConfig.values.includes(value)) return value;
for (const item of argConfig.values) {
case "enum": {
const values =
/** @type {NonNullable<ArgumentConfig["values"]>} */
(argConfig.values);
if (values.includes(value)) return value;
for (const item of values) {
if (`${item}` === value) return item;
}
break;
}
case "reset":
if (value === true) return [];
break;
@ -597,7 +630,7 @@ const parseValueForArgumentConfig = (argConfig, value) => {
/**
* @param {Record<string, Argument>} args object of arguments
* @param {any} config configuration
* @param {Record<string, string | number | boolean | RegExp | (string | number | boolean | RegExp)[]>} values object with values
* @param {Record<string, Value[]>} values object with values
* @returns {Problem[] | null} problems or null for success
*/
const processArguments = (args, config, values) => {
@ -613,6 +646,10 @@ const processArguments = (args, config, values) => {
});
continue;
}
/**
* @param {Value} value value
* @param {number} i index
*/
const processValue = (value, i) => {
const currentProblems = [];
for (const argConfig of arg.configs) {

View File

@ -14,10 +14,15 @@ const NullDependency = require("./NullDependency");
/** @typedef {import("../Dependency").UpdateHashContext} UpdateHashContext */
/** @typedef {import("../ModuleGraph")} ModuleGraph */
/** @typedef {import("../json/JsonData")} JsonData */
/** @typedef {import("../json/JsonData").RawJsonData} RawJsonData */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
/** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
/** @typedef {import("../util/Hash")} Hash */
/**
* @param {RawJsonData} data data
* @returns {TODO} value
*/
const getExportsFromData = data => {
if (data && typeof data === "object") {
if (Array.isArray(data)) {
@ -62,7 +67,9 @@ class JsonExportsDependency extends NullDependency {
*/
getExports(moduleGraph) {
return {
exports: getExportsFromData(this.data && this.data.get()),
exports: getExportsFromData(
this.data && /** @type {RawJsonData} */ (this.data.get())
),
dependencies: undefined
};
}

View File

@ -10,17 +10,12 @@ const LazySet = require("../util/LazySet");
const LoaderDependency = require("./LoaderDependency");
const LoaderImportDependency = require("./LoaderImportDependency");
/** @typedef {import("../../declarations/LoaderContext").LoaderPluginLoaderContext} LoaderPluginLoaderContext */
/** @typedef {import("../Compilation").DepConstructor} DepConstructor */
/** @typedef {import("../Compilation").ExecuteModuleResult} ExecuteModuleResult */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module")} Module */
/**
* @callback LoadModuleCallback
* @param {(Error | null)=} err error object
* @param {string | Buffer=} source source code
* @param {object=} map source map
* @param {Module=} module loaded module if successful
*/
/** @typedef {import("../Module").BuildInfo} BuildInfo */
/**
* @callback ImportModuleCallback
@ -66,11 +61,6 @@ class LoaderPlugin {
NormalModule.getCompilationHooks(compilation).loader.tap(
"LoaderPlugin",
loaderContext => {
/**
* @param {string} request the request string to load the module from
* @param {LoadModuleCallback} callback callback returning the loaded module or error
* @returns {void}
*/
loaderContext.loadModule = (request, callback) => {
const dep = new LoaderDependency(request);
dep.loc = {
@ -91,7 +81,9 @@ class LoaderPlugin {
{
factory,
dependencies: [dep],
originModule: loaderContext._module,
originModule:
/** @type {NormalModule} */
(loaderContext._module),
context: loaderContext.context,
recursive: false
},
@ -150,15 +142,20 @@ class LoaderPlugin {
for (const d of buildDependencies) {
loaderContext.addBuildDependency(d);
}
return callback(null, source, map, referencedModule);
return callback(
null,
source,
/** @type {object | null} */ (map),
referencedModule
);
}
);
};
/**
* @param {string} request the request string to load the module from
* @param {ImportModuleOptions=} options options
* @param {ImportModuleCallback=} callback callback returning the exports
* @param {ImportModuleOptions} options options
* @param {ImportModuleCallback} callback callback returning the exports
* @returns {void}
*/
const importModule = (request, options, callback) => {
@ -181,7 +178,9 @@ class LoaderPlugin {
{
factory,
dependencies: [dep],
originModule: loaderContext._module,
originModule:
/** @type {NormalModule} */
(loaderContext._module),
contextInfo: {
issuerLayer: options.layer
},
@ -208,42 +207,53 @@ class LoaderPlugin {
},
(err, result) => {
if (err) return callback(err);
for (const d of result.fileDependencies) {
const {
fileDependencies,
contextDependencies,
missingDependencies,
buildDependencies,
cacheable,
assets,
exports
} = /** @type {ExecuteModuleResult} */ (result);
for (const d of fileDependencies) {
loaderContext.addDependency(d);
}
for (const d of result.contextDependencies) {
for (const d of contextDependencies) {
loaderContext.addContextDependency(d);
}
for (const d of result.missingDependencies) {
for (const d of missingDependencies) {
loaderContext.addMissingDependency(d);
}
for (const d of result.buildDependencies) {
for (const d of buildDependencies) {
loaderContext.addBuildDependency(d);
}
if (result.cacheable === false)
loaderContext.cacheable(false);
for (const [name, { source, info }] of result.assets) {
const { buildInfo } = loaderContext._module;
if (cacheable === false) loaderContext.cacheable(false);
for (const [name, { source, info }] of assets) {
const buildInfo =
/** @type {BuildInfo} */
(
/** @type {NormalModule} */ (loaderContext._module)
.buildInfo
);
if (!buildInfo.assets) {
buildInfo.assets = Object.create(null);
buildInfo.assetsInfo = new Map();
}
buildInfo.assets[name] = source;
buildInfo.assetsInfo.set(name, info);
/** @type {NonNullable<BuildInfo["assets"]>} */
(buildInfo.assets)[name] = source;
/** @type {NonNullable<BuildInfo["assetsInfo"]>} */
(buildInfo.assetsInfo).set(name, info);
}
callback(null, result.exports);
callback(null, 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
*/
// eslint-disable-next-line no-warning-comments
// @ts-ignore Overloading doesn't work
loaderContext.importModule = (request, options, callback) => {
if (!callback) {
return new Promise((resolve, reject) => {

View File

@ -17,6 +17,7 @@ const { getInitialChunkIds } = require("../javascript/StartupHelpers");
const compileBooleanMatcher = require("../util/compileBooleanMatcher");
const { getUndoPath } = require("../util/identifier");
/** @typedef {import("../../declarations/WebpackOptions").Environment} Environment */
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
@ -87,9 +88,12 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
const compilation = /** @type {Compilation} */ (this.compilation);
const chunkGraph = /** @type {ChunkGraph} */ (this.chunkGraph);
const chunk = /** @type {Chunk} */ (this.chunk);
const environment =
/** @type {Environment} */
(compilation.outputOptions.environment);
const {
runtimeTemplate,
outputOptions: { environment, importFunctionName, crossOriginLoading }
outputOptions: { importFunctionName, crossOriginLoading }
} = compilation;
const fn = RuntimeGlobals.ensureChunkHandlers;
const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI);

View File

@ -64,7 +64,11 @@ class HashedModuleIdsPlugin {
);
for (const module of modulesInNaturalOrder) {
const ident = getFullModuleName(module, context, compiler.root);
const hash = createHash(options.hashFunction);
const hash = createHash(
/** @type {NonNullable<HashedModuleIdsPluginOptions["hashFunction"]>} */ (
options.hashFunction
)
);
hash.update(ident || "");
const hashId = /** @type {string} */ (
hash.digest(options.hashDigest)

View File

@ -10,6 +10,7 @@ const { getUsedModuleIdsAndModules } = require("./IdHelpers");
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
const plugin = "SyncModuleIdsPlugin";
@ -42,7 +43,9 @@ class SyncModuleIdsPlugin {
let dataChanged = false;
if (this._read) {
compiler.hooks.readRecords.tapAsync(plugin, callback => {
const fs = compiler.intermediateFileSystem;
const fs =
/** @type {IntermediateFileSystem} */
(compiler.intermediateFileSystem);
fs.readFile(this._path, (err, buffer) => {
if (err) {
if (err.code !== "ENOENT") {
@ -69,7 +72,9 @@ class SyncModuleIdsPlugin {
for (const [key, value] of sorted) {
json[key] = value;
}
const fs = compiler.intermediateFileSystem;
const fs =
/** @type {IntermediateFileSystem} */
(compiler.intermediateFileSystem);
fs.writeFile(this._path, JSON.stringify(json), callback);
});
}

View File

@ -16,6 +16,7 @@ const AbstractLibraryPlugin = require("./AbstractLibraryPlugin");
/** @typedef {import("../Compilation").ChunkHashContext} ChunkHashContext */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../Module").BuildMeta} BuildMeta */
/** @typedef {import("../javascript/JavascriptModulesPlugin").StartupRenderContext} StartupRenderContext */
/** @typedef {import("../util/Hash")} Hash */
/** @template T @typedef {import("./AbstractLibraryPlugin").LibraryContext<T>} LibraryContext<T> */
@ -92,7 +93,9 @@ class ModernModuleLibraryPlugin extends AbstractLibraryPlugin {
) {
const result = new ConcatSource(source);
const exportsInfo = moduleGraph.getExportsInfo(module);
const definitions = module.buildMeta.exportsFinalName;
const definitions =
/** @type {BuildMeta} */
(module.buildMeta).exportsFinalName;
const exports = [];
for (const exportInfo of exportsInfo.orderedExports) {
@ -105,7 +108,7 @@ class ModernModuleLibraryPlugin extends AbstractLibraryPlugin {
for (const reexportInfo of exp.orderedExports) {
if (
!reexportInfo.provided &&
reexportInfo.name === reexport.export[0]
reexportInfo.name === /** @type {string[]} */ (reexport.export)[0]
) {
shouldContinue = true;
}

View File

@ -155,11 +155,11 @@ if (!ReferencerClass.prototype.PropertyDefinition) {
* @property {number} index
* @property {string} name
* @property {boolean} interopNamespaceObjectUsed
* @property {string} interopNamespaceObjectName
* @property {string | undefined} interopNamespaceObjectName
* @property {boolean} interopNamespaceObject2Used
* @property {string} interopNamespaceObject2Name
* @property {string | undefined} interopNamespaceObject2Name
* @property {boolean} interopDefaultAccessUsed
* @property {string} interopDefaultAccessName
* @property {string | undefined} interopDefaultAccessName
*/
/**
@ -631,7 +631,7 @@ const TYPES = new Set(["javascript"]);
/**
* @typedef {object} ConcatenateModuleHooks
* @property {SyncBailHook<[Record<string, string>]>} exportsDefinitions
* @property {SyncBailHook<[Record<string, string>], boolean>} exportsDefinitions
*/
/** @type {WeakMap<Compilation, ConcatenateModuleHooks>} */
@ -1511,7 +1511,7 @@ class ConcatenatedModule extends Module {
// define exports
if (exportsMap.size > 0) {
const { exportsDefinitions } = ConcatenatedModule.getCompilationHooks(
this.compilation
/** @type {Compilation} */ (this.compilation)
);
const definitions = [];
@ -1546,7 +1546,8 @@ class ConcatenatedModule extends Module {
}, {${definitions.join(",")}\n});\n`
);
} else {
this.buildMeta.exportsFinalName = exportsFinalName;
/** @type {BuildMeta} */
(this.buildMeta).exportsFinalName = exportsFinalName;
}
}
@ -1867,7 +1868,7 @@ ${defineGetters}`
/** @type {ModuleInfo} */ (item).module,
/** @type {ModuleInfo} */ (item)
);
return item;
return /** @type {ModuleInfo} */ (item);
}
/** @type {ReferenceToModuleInfo} */
const ref = {

View File

@ -5,6 +5,7 @@
"use strict";
/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
/** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */
class BasicEffectRulePlugin {
@ -28,7 +29,8 @@ class BasicEffectRulePlugin {
if (unhandledProperties.has(this.ruleProperty)) {
unhandledProperties.delete(this.ruleProperty);
const value = rule[this.ruleProperty];
const value =
rule[/** @type {keyof RuleSetRule} */ (this.ruleProperty)];
result.effects.push({
type: this.effectType,

View File

@ -5,6 +5,7 @@
"use strict";
/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
/** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */
/** @typedef {import("./RuleSetCompiler").RuleCondition} RuleCondition */
@ -30,7 +31,8 @@ class BasicMatcherRulePlugin {
(path, rule, unhandledProperties, result) => {
if (unhandledProperties.has(this.ruleProperty)) {
unhandledProperties.delete(this.ruleProperty);
const value = rule[this.ruleProperty];
const value =
rule[/** @type {keyof RuleSetRule} */ (this.ruleProperty)];
const condition = ruleSetCompiler.compileCondition(
`${path}.${this.ruleProperty}`,
value

View File

@ -5,6 +5,7 @@
"use strict";
/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
/** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */
/** @typedef {import("./RuleSetCompiler").RuleCondition} RuleCondition */
/** @typedef {import("./RuleSetCompiler").RuleConditionFunction} RuleConditionFunction */
@ -32,7 +33,9 @@ class ObjectMatcherRulePlugin {
(path, rule, unhandledProperties, result) => {
if (unhandledProperties.has(ruleProperty)) {
unhandledProperties.delete(ruleProperty);
const value = rule[ruleProperty];
const value =
/** @type {Record<string, any>} */
(rule[/** @type {keyof RuleSetRule} */ (ruleProperty)]);
for (const property of Object.keys(value)) {
const nestedDataProperties = property.split(".");
const condition = ruleSetCompiler.compileCondition(

View File

@ -7,6 +7,9 @@
const { SyncHook } = require("tapable");
/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
/** @typedef {import("../../declarations/WebpackOptions").RuleSetRules} RuleSetRules */
/** @typedef {function(string): boolean} RuleConditionFunction */
/**
@ -22,10 +25,14 @@ const { SyncHook } = require("tapable");
* @property {RuleConditionFunction} fn
*/
/**
* @typedef {Record<string, TODO>} EffectData
*/
/**
* @typedef {object} CompiledRule
* @property {RuleCondition[]} conditions
* @property {(Effect|function(object): Effect[])[]} effects
* @property {(Effect|function(EffectData): Effect[])[]} effects
* @property {CompiledRule[]=} rules
* @property {CompiledRule[]=} oneOf
*/
@ -39,13 +46,18 @@ const { SyncHook } = require("tapable");
/**
* @typedef {object} RuleSet
* @property {Map<string, any>} references map of references in the rule set (may grow over time)
* @property {function(object): Effect[]} exec execute the rule set
* @property {function(EffectData): Effect[]} exec execute the rule set
*/
/** @typedef {{ apply: (function(RuleSetCompiler): void) }} RuleSetPlugin */
class RuleSetCompiler {
/**
* @param {RuleSetPlugin[]} plugins plugins
*/
constructor(plugins) {
this.hooks = Object.freeze({
/** @type {SyncHook<[string, object, Set<string>, CompiledRule, Map<string, any>]>} */
/** @type {SyncHook<[string, RuleSetRule, Set<string>, CompiledRule, Map<string | undefined, any>]>} */
rule: new SyncHook([
"path",
"rule",
@ -62,7 +74,7 @@ class RuleSetCompiler {
}
/**
* @param {object[]} ruleSet raw user provided rules
* @param {TODO[]} ruleSet raw user provided rules
* @returns {RuleSet} compiled RuleSet
*/
compile(ruleSet) {
@ -70,7 +82,7 @@ class RuleSetCompiler {
const rules = this.compileRules("ruleSet", ruleSet, refs);
/**
* @param {object} data data passed in
* @param {EffectData} data data passed in
* @param {CompiledRule} rule the compiled rule
* @param {Effect[]} effects an array where effects are pushed to
* @returns {boolean} true, if the rule has matched
@ -79,6 +91,7 @@ class RuleSetCompiler {
for (const condition of rule.conditions) {
const p = condition.property;
if (Array.isArray(p)) {
/** @type {EffectData | string | undefined} */
let current = data;
for (const subProperty of p) {
if (
@ -93,7 +106,7 @@ class RuleSetCompiler {
}
}
if (current !== undefined) {
if (!condition.fn(current)) return false;
if (!condition.fn(/** @type {string} */ (current))) return false;
continue;
}
} else if (p in data) {
@ -147,25 +160,33 @@ class RuleSetCompiler {
/**
* @param {string} path current path
* @param {object[]} rules the raw rules provided by user
* @param {RuleSetRules} rules the raw rules provided by user
* @param {Map<string, any>} refs references
* @returns {CompiledRule[]} rules
*/
compileRules(path, rules, refs) {
return rules
.filter(Boolean)
.map((rule, i) => this.compileRule(`${path}[${i}]`, rule, refs));
.map((rule, i) =>
this.compileRule(
`${path}[${i}]`,
/** @type {RuleSetRule} */ (rule),
refs
)
);
}
/**
* @param {string} path current path
* @param {object} rule the raw rule provided by user
* @param {RuleSetRule} rule the raw rule provided by user
* @param {Map<string, any>} refs references
* @returns {CompiledRule} normalized and compiled rule for processing
*/
compileRule(path, rule, refs) {
const unhandledProperties = new Set(
Object.keys(rule).filter(key => rule[key] !== undefined)
Object.keys(rule).filter(
key => rule[/** @type {keyof RuleSetRule} */ (key)] !== undefined
)
);
/** @type {CompiledRule} */
@ -303,7 +324,7 @@ class RuleSetCompiler {
const fn = matcher.fn;
conditions.push({
matchWhenEmpty: !matcher.matchWhenEmpty,
fn: v => !fn(v)
fn: /** @type {RuleConditionFunction} */ (v => !fn(v))
});
}
break;

View File

@ -7,6 +7,9 @@
const util = require("util");
/** @typedef {import("../../declarations/WebpackOptions").RuleSetLoader} RuleSetLoader */
/** @typedef {import("../../declarations/WebpackOptions").RuleSetLoaderOptions} RuleSetLoaderOptions */
/** @typedef {import("../../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
/** @typedef {import("./RuleSetCompiler")} RuleSetCompiler */
/** @typedef {import("./RuleSetCompiler").Effect} Effect */
@ -19,6 +22,10 @@ class UseEffectRulePlugin {
ruleSetCompiler.hooks.rule.tap(
"UseEffectRulePlugin",
(path, rule, unhandledProperties, result, references) => {
/**
* @param {keyof RuleSetRule} property property
* @param {string} correctProperty correct property
*/
const conflictWith = (property, correctProperty) => {
if (unhandledProperties.has(property)) {
throw ruleSetCompiler.error(
@ -57,7 +64,7 @@ class UseEffectRulePlugin {
/**
* @param {string} path options path
* @param {string} defaultIdent default ident when none is provided
* @param {object} item user provided use value
* @param {{ ident?: string, loader?: RuleSetLoader, options?: RuleSetLoaderOptions }} item user provided use value
* @returns {Effect} effect
*/
const useToEffectRaw = (path, defaultIdent, item) => {
@ -128,7 +135,10 @@ class UseEffectRulePlugin {
if (typeof use === "function") {
result.effects.push(data =>
useToEffectsWithoutIdent(`${path}.use`, use(data))
useToEffectsWithoutIdent(
`${path}.use`,
use(/** @type {TODO} */ (data))
)
);
} else {
for (const effect of useToEffects(`${path}.use`, use)) {
@ -142,7 +152,7 @@ class UseEffectRulePlugin {
unhandledProperties.delete("options");
unhandledProperties.delete("enforce");
const loader = rule.loader;
const loader = /** @type {RuleSetLoader} */ (rule.loader);
const options = rule.options;
const enforce = rule.enforce;
@ -185,8 +195,6 @@ class UseEffectRulePlugin {
}
);
}
useItemToEffects(path, item) {}
}
module.exports = UseEffectRulePlugin;

View File

@ -15,17 +15,37 @@ const createHash = require("../util/createHash");
const { mkdirp, dirname, join } = require("../util/fs");
const memoize = require("../util/memoize");
/** @typedef {import("http").IncomingMessage} IncomingMessage */
/** @typedef {import("http").RequestOptions} RequestOptions */
/** @typedef {import("net").Socket} Socket */
/** @typedef {import("stream").Readable} Readable */
/** @typedef {import("../../declarations/plugins/schemes/HttpUriPlugin").HttpUriPluginOptions} HttpUriPluginOptions */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../FileSystemInfo").Snapshot} Snapshot */
/** @typedef {import("../Module").BuildInfo} BuildInfo */
/** @typedef {import("../NormalModuleFactory").ResourceDataWithData} ResourceDataWithData */
/** @typedef {import("../util/fs").IntermediateFileSystem} IntermediateFileSystem */
const getHttp = memoize(() => require("http"));
const getHttps = memoize(() => require("https"));
/**
* @param {typeof import("http") | typeof import("https")} request request
* @param {string | { toString: () => string } | undefined} proxy proxy
* @returns {function(URL, RequestOptions, function(IncomingMessage): void): EventEmitter} fn
*/
const proxyFetch = (request, proxy) => (url, options, callback) => {
const eventEmitter = new EventEmitter();
const doRequest = socket =>
/**
* @param {Socket=} socket socket
* @returns {void}
*/
const doRequest = socket => {
request
.get(url, { ...options, ...(socket && { socket }) }, callback)
.on("error", eventEmitter.emit.bind(eventEmitter, "error"));
};
if (proxy) {
const { hostname: host, port } = new URL(proxy);
@ -59,7 +79,8 @@ const proxyFetch = (request, proxy) => (url, options, callback) => {
return eventEmitter;
};
/** @type {(() => void)[] | undefined} */
/** @typedef {() => void} InProgressWriteItem */
/** @type {InProgressWriteItem[] | undefined} */
let inProgressWrite;
const validate = createSchemaValidation(
@ -157,6 +178,11 @@ const parseCacheControl = (cacheControl, requestTime) => {
* @property {string} contentType
*/
/**
* @param {LockfileEntry} a first lockfile entry
* @param {LockfileEntry} b second lockfile entry
* @returns {boolean} true when equal, otherwise false
*/
const areLockfileEntriesEqual = (a, b) =>
a.resolved === b.resolved &&
a.integrity === b.integrity &&
@ -229,8 +255,8 @@ class Lockfile {
/**
* @template R
* @param {function(function(Error=, R=): void): void} fn function
* @returns {function(function((Error | null)=, R=): void): void} cached function
* @param {function(function(Error | null, R=): void): void} fn function
* @returns {function(function(Error | null, R=): void): void} cached function
*/
const cachedWithoutKey = fn => {
let inFlight = false;
@ -238,7 +264,7 @@ const cachedWithoutKey = fn => {
let cachedError;
/** @type {R | undefined} */
let cachedResult;
/** @type {(function(Error=, R=): void)[] | undefined} */
/** @type {(function(Error| null, R=): void)[] | undefined} */
let cachedCallbacks;
return callback => {
if (inFlight) {
@ -263,17 +289,22 @@ const cachedWithoutKey = fn => {
/**
* @template T
* @template R
* @param {function(T, function(Error=, R=): void): void} fn function
* @param {function(T, function(Error=, R=): void): void=} forceFn function for the second try
* @returns {(function(T, function((Error | null)=, R=): void): void) & { force: function(T, function((Error | null)=, R=): void): void }} cached function
* @param {function(T, function(Error | null, R=): void): void} fn function
* @param {function(T, function(Error | null, R=): void): void=} forceFn function for the second try
* @returns {(function(T, function(Error | null, R=): void): void) & { force: function(T, function(Error | null, R=): void): void }} cached function
*/
const cachedWithKey = (fn, forceFn = fn) => {
/**
* @template R
* @typedef {{ result?: R, error?: Error, callbacks?: (function((Error | null)=, R=): void)[], force?: true }} CacheEntry
* @typedef {{ result?: R, error?: Error, callbacks?: (function(Error | null, R=): void)[], force?: true }} CacheEntry
*/
/** @type {Map<T, CacheEntry<R>>} */
const cache = new Map();
/**
* @param {T} arg arg
* @param {function(Error | null, R=): void} callback callback
* @returns {void}
*/
const resultFn = (arg, callback) => {
const cacheEntry = cache.get(arg);
if (cacheEntry !== undefined) {
@ -300,6 +331,11 @@ const cachedWithKey = (fn, forceFn = fn) => {
if (callbacks !== undefined) for (const cb of callbacks) cb(err, result);
});
};
/**
* @param {T} arg arg
* @param {function(Error | null, R=): void} callback callback
* @returns {void}
*/
resultFn.force = (arg, callback) => {
const cacheEntry = cache.get(arg);
if (cacheEntry !== undefined && cacheEntry.force) {
@ -330,6 +366,24 @@ const cachedWithKey = (fn, forceFn = fn) => {
return resultFn;
};
/**
* @typedef {object} LockfileCache
* @property {Lockfile} lockfile lockfile
* @property {Snapshot} snapshot snapshot
*/
/**
* @typedef {object} ResolveContentResult
* @property {LockfileEntry} entry lockfile entry
* @property {Buffer} content content
* @property {boolean} storeLock need store lockfile
*/
/** @typedef {{ storeCache: boolean, storeLock: boolean, validUntil: number, etag: string | undefined, fresh: boolean }} FetchResultMeta */
/** @typedef {FetchResultMeta & { location: string }} RedirectFetchResult */
/** @typedef {FetchResultMeta & { entry: LockfileEntry, content: Buffer }} ContentFetchResult */
/** @typedef {RedirectFetchResult | ContentFetchResult} FetchResult */
class HttpUriPlugin {
/**
* @param {HttpUriPluginOptions} options options
@ -362,11 +416,14 @@ class HttpUriPlugin {
fetch: proxyFetch(getHttps(), proxy)
}
];
/** @type {LockfileCache} */
let lockfileCache;
compiler.hooks.compilation.tap(
"HttpUriPlugin",
(compilation, { normalModuleFactory }) => {
const intermediateFs = compiler.intermediateFileSystem;
const intermediateFs =
/** @type {IntermediateFileSystem} */
(compiler.intermediateFileSystem);
const fs = compilation.inputFileSystem;
const cache = compilation.getCache("webpack.HttpUriPlugin");
const logger = compilation.getLogger("webpack.HttpUriPlugin");
@ -430,7 +487,7 @@ class HttpUriPlugin {
const getLockfile = cachedWithoutKey(
/**
* @param {function((Error | null)=, Lockfile=): void} callback callback
* @param {function(Error | null, Lockfile=): void} callback callback
* @returns {void}
*/
callback => {
@ -447,14 +504,14 @@ class HttpUriPlugin {
[],
buffer ? [] : [lockfileLocation],
{ timestamp: true },
(err, snapshot) => {
(err, s) => {
if (err) return callback(err);
const lockfile = buffer
? Lockfile.parse(buffer.toString("utf-8"))
: new Lockfile();
lockfileCache = {
lockfile,
snapshot
snapshot: /** @type {Snapshot} */ (s)
};
callback(null, lockfile);
}
@ -476,7 +533,9 @@ class HttpUriPlugin {
}
);
/** @type {Map<string, LockfileEntry | "ignore" | "no-cache"> | undefined} */
/** @typedef {Map<string, LockfileEntry | "ignore" | "no-cache">} LockfileUpdates */
/** @type {LockfileUpdates | undefined} */
let lockfileUpdates;
/**
@ -518,6 +577,13 @@ class HttpUriPlugin {
}
};
/**
* @param {Lockfile} lockfile lockfile
* @param {string} url url
* @param {ResolveContentResult} result result
* @param {function(Error | null, ResolveContentResult=): void} callback callback
* @returns {void}
*/
const storeResult = (lockfile, url, result, callback) => {
if (result.storeLock) {
storeLockEntry(lockfile, url, result.entry);
@ -541,10 +607,15 @@ class HttpUriPlugin {
for (const { scheme, fetch } of schemes) {
/**
* @param {string} url URL
* @param {string} integrity integrity
* @param {function((Error | null)=, { entry: LockfileEntry, content: Buffer, storeLock: boolean }=): void} callback callback
* @param {string | null} integrity integrity
* @param {function(Error | null, ResolveContentResult=): void} callback callback
*/
const resolveContent = (url, integrity, callback) => {
/**
* @param {Error | null} err error
* @param {TODO} result result result
* @returns {void}
*/
const handleResult = (err, result) => {
if (err) return callback(err);
if ("location" in result) {
@ -553,10 +624,12 @@ class HttpUriPlugin {
integrity,
(err, innerResult) => {
if (err) return callback(err);
const { entry, content, storeLock } =
/** @type {ResolveContentResult} */ (innerResult);
callback(null, {
entry: innerResult.entry,
content: innerResult.content,
storeLock: innerResult.storeLock && result.storeLock
entry,
content,
storeLock: storeLock && result.storeLock
});
}
);
@ -578,15 +651,10 @@ class HttpUriPlugin {
fetchContent(url, handleResult);
};
/** @typedef {{ storeCache: boolean, storeLock: boolean, validUntil: number, etag: string | undefined, fresh: boolean }} FetchResultMeta */
/** @typedef {FetchResultMeta & { location: string }} RedirectFetchResult */
/** @typedef {FetchResultMeta & { entry: LockfileEntry, content: Buffer }} ContentFetchResult */
/** @typedef {RedirectFetchResult | ContentFetchResult} FetchResult */
/**
* @param {string} url URL
* @param {FetchResult | RedirectFetchResult} cachedResult result from cache
* @param {function((Error | null)=, FetchResult=): void} callback callback
* @param {FetchResult | RedirectFetchResult | undefined} cachedResult result from cache
* @param {function(Error | null, FetchResult=): void} callback callback
* @returns {void}
*/
const fetchContentRaw = (url, cachedResult, callback) => {
@ -659,22 +727,21 @@ class HttpUriPlugin {
);
};
if (res.statusCode === 304) {
const result = /** @type {FetchResult} */ (cachedResult);
if (
cachedResult.validUntil < validUntil ||
cachedResult.storeLock !== storeLock ||
cachedResult.storeCache !== storeCache ||
cachedResult.etag !== etag
result.validUntil < validUntil ||
result.storeLock !== storeLock ||
result.storeCache !== storeCache ||
result.etag !== etag
) {
return finishWith(cachedResult);
return finishWith(result);
}
logger.debug(`GET ${url} [${res.statusCode}] (unchanged)`);
return callback(null, {
...cachedResult,
fresh: true
});
return callback(null, { ...result, fresh: true });
}
if (
location &&
res.statusCode &&
res.statusCode >= 301 &&
res.statusCode <= 308
) {
@ -703,9 +770,11 @@ class HttpUriPlugin {
});
}
const contentType = res.headers["content-type"] || "";
/** @type {Buffer[]} */
const bufferArr = [];
const contentEncoding = res.headers["content-encoding"];
/** @type {Readable} */
let stream = res;
if (contentEncoding === "gzip") {
stream = stream.pipe(createGunzip());
@ -757,9 +826,10 @@ class HttpUriPlugin {
const fetchContent = cachedWithKey(
/**
* @param {string} url URL
* @param {function((Error | null)=, { validUntil: number, etag?: string, entry: LockfileEntry, content: Buffer, fresh: boolean } | { validUntil: number, etag?: string, location: string, fresh: boolean }=): void} callback callback
* @param {function(Error | null, { validUntil: number, etag?: string, entry: LockfileEntry, content: Buffer, fresh: boolean } | { validUntil: number, etag?: string, location: string, fresh: boolean }=): void} callback callback
* @returns {void}
*/ (url, callback) => {
*/
(url, callback) => {
cache.get(url, null, (err, cachedResult) => {
if (err) return callback(err);
if (cachedResult) {
@ -772,6 +842,10 @@ class HttpUriPlugin {
(url, callback) => fetchContentRaw(url, undefined, callback)
);
/**
* @param {string} uri uri
* @returns {boolean} true when allowed, otherwise false
*/
const isAllowed = uri => {
for (const allowed of allowedUris) {
if (typeof allowed === "string") {
@ -785,10 +859,12 @@ class HttpUriPlugin {
return false;
};
/** @typedef {{ entry: LockfileEntry, content: Buffer }} Info */
const getInfo = cachedWithKey(
/**
* @param {string} url the url
* @param {function((Error | null)=, { entry: LockfileEntry, content: Buffer }=): void} callback callback
* @param {function(Error | null, Info=): void} callback callback
* @returns {void}
*/
// eslint-disable-next-line no-loop-func
@ -802,8 +878,9 @@ class HttpUriPlugin {
)
);
}
getLockfile((err, lockfile) => {
getLockfile((err, _lockfile) => {
if (err) return callback(err);
const lockfile = /** @type {Lockfile} */ (_lockfile);
const entryOrString = lockfile.entries.get(url);
if (!entryOrString) {
if (frozen) {
@ -815,14 +892,24 @@ class HttpUriPlugin {
}
resolveContent(url, null, (err, result) => {
if (err) return callback(err);
storeResult(lockfile, url, result, callback);
storeResult(
/** @type {Lockfile} */
(lockfile),
url,
/** @type {ResolveContentResult} */
(result),
callback
);
});
return;
}
if (typeof entryOrString === "string") {
const entryTag = entryOrString;
resolveContent(url, null, (err, result) => {
resolveContent(url, null, (err, _result) => {
if (err) return callback(err);
const result =
/** @type {ResolveContentResult} */
(_result);
if (!result.storeLock || entryTag === "ignore")
return callback(null, result);
if (frozen) {
@ -846,8 +933,11 @@ Remove this line from the lockfile to force upgrading.`
return;
}
let entry = entryOrString;
/**
* @param {Buffer=} lockedContent locked content
*/
const doFetch = lockedContent => {
resolveContent(url, entry.integrity, (err, result) => {
resolveContent(url, entry.integrity, (err, _result) => {
if (err) {
if (lockedContent) {
logger.warn(
@ -861,6 +951,9 @@ Remove this line from the lockfile to force upgrading.`
}
return callback(err);
}
const result =
/** @type {ResolveContentResult} */
(_result);
if (!result.storeLock) {
// When the lockfile entry should be no-cache
// we need to update the lockfile
@ -915,12 +1008,16 @@ Remove this line from the lockfile to force upgrading.`
const key = getCacheKey(entry.resolved);
const filePath = join(intermediateFs, cacheLocation, key);
fs.readFile(filePath, (err, result) => {
const content = /** @type {Buffer} */ (result);
if (err) {
if (err.code === "ENOENT") return doFetch();
return callback(err);
}
const continueWithCachedContent = result => {
const content = /** @type {Buffer} */ (result);
/**
* @param {Buffer | undefined} _result result
* @returns {void}
*/
const continueWithCachedContent = _result => {
if (!upgrade) {
// When not in upgrade mode, we accept the result from the lockfile cache
return callback(null, { entry, content });
@ -928,6 +1025,7 @@ Remove this line from the lockfile to force upgrading.`
return doFetch(content);
};
if (!verifyIntegrity(content, entry.integrity)) {
/** @type {Buffer | undefined} */
let contentWithChangedEol;
let isEolChanged = false;
try {
@ -965,10 +1063,14 @@ This will avoid that the end of line sequence is changed by git on Windows.`;
);
intermediateFs.writeFile(
filePath,
contentWithChangedEol,
/** @type {Buffer} */
(contentWithChangedEol),
err => {
if (err) return callback(err);
continueWithCachedContent(contentWithChangedEol);
continueWithCachedContent(
/** @type {Buffer} */
(contentWithChangedEol)
);
}
);
return;
@ -1008,9 +1110,15 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
}
);
/**
* @param {URL} url url
* @param {ResourceDataWithData} resourceData resource data
* @param {function(Error | null, true | void): void} callback callback
*/
const respondWithUrlModule = (url, resourceData, callback) => {
getInfo(url.href, (err, result) => {
getInfo(url.href, (err, _result) => {
if (err) return callback(err);
const result = /** @type {Info} */ (_result);
resourceData.resource = url.href;
resourceData.path = url.origin + url.pathname;
resourceData.query = url.search;
@ -1055,9 +1163,11 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
hooks.readResourceForScheme
.for(scheme)
.tapAsync("HttpUriPlugin", (resource, module, callback) =>
getInfo(resource, (err, result) => {
getInfo(resource, (err, _result) => {
if (err) return callback(err);
module.buildInfo.resourceIntegrity = result.entry.integrity;
const result = /** @type {Info} */ (_result);
/** @type {BuildInfo} */
(module.buildInfo).resourceIntegrity = result.entry.integrity;
callback(null, result.content);
})
);
@ -1068,11 +1178,13 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
module.resource &&
module.resource.startsWith(`${scheme}://`)
) {
getInfo(module.resource, (err, result) => {
getInfo(module.resource, (err, _result) => {
if (err) return callback(err);
const result = /** @type {Info} */ (_result);
if (
result.entry.integrity !==
module.buildInfo.resourceIntegrity
/** @type {BuildInfo} */
(module.buildInfo).resourceIntegrity
) {
return callback(null, true);
}
@ -1098,7 +1210,9 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
);
const writeDone = () => {
const nextOperation = inProgressWrite.shift();
const nextOperation =
/** @type {InProgressWriteItem[]} */
(inProgressWrite).shift();
if (nextOperation) {
nextOperation();
} else {
@ -1114,19 +1228,25 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
const lockfile = buffer
? Lockfile.parse(buffer.toString("utf-8"))
: new Lockfile();
for (const [key, value] of lockfileUpdates) {
for (const [key, value] of /** @type {LockfileUpdates} */ (
lockfileUpdates
)) {
lockfile.entries.set(key, value);
}
intermediateFs.writeFile(tempFile, lockfile.toString(), err => {
if (err) {
writeDone();
return intermediateFs.unlink(tempFile, () => callback(err));
return (
/** @type {NonNullable<IntermediateFileSystem["unlink"]>} */
(intermediateFs.unlink)(tempFile, () => callback(err))
);
}
intermediateFs.rename(tempFile, lockfileLocation, err => {
if (err) {
writeDone();
return intermediateFs.unlink(tempFile, () =>
callback(err)
return (
/** @type {NonNullable<IntermediateFileSystem["unlink"]>} */
(intermediateFs.unlink)(tempFile, () => callback(err))
);
}
writeDone();

File diff suppressed because it is too large Load Diff

View File

@ -11,15 +11,24 @@ const RequestShortener = require("../RequestShortener");
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../Compilation").CreateStatsOptionsContext} CreateStatsOptionsContext */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsError} StatsError */
/**
* @param {StatsOptions} options options
* @param {StatsOptions} defaults default options
*/
const applyDefaults = (options, defaults) => {
for (const key of Object.keys(defaults)) {
for (const _k of Object.keys(defaults)) {
const key = /** @type {keyof StatsOptions} */ (_k);
if (typeof options[key] === "undefined") {
options[key] = defaults[key];
/** @type {TODO} */
(options)[key] = defaults[key];
}
}
};
/** @typedef {Record<string, StatsOptions>} NamedPresets */
/** @type {NamedPresets} */
const NAMED_PRESETS = {
verbose: {
hash: true,
@ -126,12 +135,35 @@ const NAMED_PRESETS = {
}
};
/**
* @param {StatsOptions} all stats option
* @returns {boolean} true when enabled, otherwise false
*/
const NORMAL_ON = ({ all }) => all !== false;
/**
* @param {StatsOptions} all stats option
* @returns {boolean} true when enabled, otherwise false
*/
const NORMAL_OFF = ({ all }) => all === true;
/**
* @param {StatsOptions} all stats option
* @param {CreateStatsOptionsContext} forToString stats options context
* @returns {boolean} true when enabled, otherwise false
*/
const ON_FOR_TO_STRING = ({ all }, { forToString }) =>
forToString ? all !== false : all === true;
/**
* @param {StatsOptions} all stats option
* @param {CreateStatsOptionsContext} forToString stats options context
* @returns {boolean} true when enabled, otherwise false
*/
const OFF_FOR_TO_STRING = ({ all }, { forToString }) =>
forToString ? all === true : all !== false;
/**
* @param {StatsOptions} all stats option
* @param {CreateStatsOptionsContext} forToString stats options context
* @returns {boolean | "auto"} true when enabled, otherwise false
*/
const AUTO_FOR_TO_STRING = ({ all }, { forToString }) => {
if (all === false) return false;
if (all === true) return true;
@ -139,13 +171,19 @@ const AUTO_FOR_TO_STRING = ({ all }, { forToString }) => {
return true;
};
/** @type {Record<string, (options: StatsOptions, context: CreateStatsOptionsContext, compilation: Compilation) => any>} */
/** @typedef {Record<string, (options: StatsOptions, context: CreateStatsOptionsContext, compilation: Compilation) => StatsOptions[keyof StatsOptions] | RequestShortener>} Defaults */
/** @type {Defaults} */
const DEFAULTS = {
context: (options, context, compilation) => compilation.compiler.context,
requestShortener: (options, context, compilation) =>
compilation.compiler.context === options.context
? compilation.requestShortener
: new RequestShortener(options.context, compilation.compiler.root),
: new RequestShortener(
/** @type {string} */
(options.context),
compilation.compiler.root
),
performance: NORMAL_ON,
hash: OFF_FOR_TO_STRING,
env: NORMAL_OFF,
@ -235,6 +273,10 @@ const DEFAULTS = {
colors: () => false
};
/**
* @param {string | ({ test: function(string): boolean }) | (function(string): boolean) | boolean} item item to normalize
* @returns {(function(string): boolean) | undefined} normalize fn
*/
const normalizeFilter = item => {
if (typeof item === "string") {
const regExp = new RegExp(
@ -253,6 +295,7 @@ const normalizeFilter = item => {
}
};
/** @type {Record<string, function(any): any[]>} */
const NORMALIZER = {
excludeModules: value => {
if (!Array.isArray(value)) {
@ -270,20 +313,32 @@ const NORMALIZER = {
if (!Array.isArray(value)) {
value = value ? [value] : [];
}
return value.map(filter => {
if (typeof filter === "string") {
return (warning, warningString) => warningString.includes(filter);
/**
* @callback WarningFilterFn
* @param {StatsError} warning warning
* @param {string} warningString warning string
* @returns {boolean} result
*/
return value.map(
/**
* @param {StatsOptions["warningsFilter"]} filter a warning filter
* @returns {WarningFilterFn} result
*/
filter => {
if (typeof filter === "string") {
return (warning, warningString) => warningString.includes(filter);
}
if (filter instanceof RegExp) {
return (warning, warningString) => filter.test(warningString);
}
if (typeof filter === "function") {
return filter;
}
throw new Error(
`Can only filter warnings with Strings or RegExps. (Given: ${filter})`
);
}
if (filter instanceof RegExp) {
return (warning, warningString) => filter.test(warningString);
}
if (typeof filter === "function") {
return filter;
}
throw new Error(
`Can only filter warnings with Strings or RegExps. (Given: ${filter})`
);
});
);
},
logging: value => {
if (value === true) value = "log";
@ -306,7 +361,7 @@ class DefaultStatsPresetPlugin {
apply(compiler) {
compiler.hooks.compilation.tap("DefaultStatsPresetPlugin", compilation => {
for (const key of Object.keys(NAMED_PRESETS)) {
const defaults = NAMED_PRESETS[key];
const defaults = NAMED_PRESETS[/** @type {keyof NamedPresets} */ (key)];
compilation.hooks.statsPreset
.for(key)
.tap("DefaultStatsPresetPlugin", (options, context) => {

View File

@ -6,7 +6,10 @@
"use strict";
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("./DefaultStatsFactoryPlugin").KnownStatsChunkGroup} KnownStatsChunkGroup */
/** @typedef {import("./StatsPrinter")} StatsPrinter */
/** @typedef {import("./StatsPrinter").KnownStatsPrinterColorFn} KnownStatsPrinterColorFn */
/** @typedef {import("./StatsPrinter").KnownStatsPrinterFormaters} KnownStatsPrinterFormaters */
/** @typedef {import("./StatsPrinter").StatsPrinterContext} StatsPrinterContext */
const DATA_URI_CONTENT_LENGTH = 16;
@ -22,9 +25,8 @@ const plural = (n, singular, plural) => (n === 1 ? singular : plural);
/**
* @param {Record<string, number>} sizes sizes by source type
* @param {object} options options
* @param {(number) => string=} options.formatSize size formatter
* @returns {string} text
* @param {StatsPrinterContext} options options
* @returns {string | undefined} text
*/
const printSizes = (sizes, { formatSize = n => `${n}` }) => {
const keys = Object.keys(sizes);
@ -56,7 +58,9 @@ const getResourceName = resource => {
* @returns {[string,string]} prefix and module name
*/
const getModuleName = name => {
const [, prefix, resource] = /^(.*!)?([^!]*)$/.exec(name);
const [, prefix, resource] =
/** @type {[any, string, string]} */
(/** @type {unknown} */ (/^(.*!)?([^!]*)$/.exec(name)));
if (resource.length > MAX_MODULE_IDENTIFIER_LENGTH) {
const truncatedResource = `${resource.slice(
@ -86,19 +90,29 @@ const mapLines = (str, fn) => str.split("\n").map(fn).join("\n");
*/
const twoDigit = n => (n >= 10 ? `${n}` : `0${n}`);
/**
* @param {string | number} id an id
* @returns {boolean | string} is i
*/
const isValidId = id => typeof id === "number" || id;
/**
* @template T
* @param {Array<T>} list of items
* @param {Array<T> | undefined} list of items
* @param {number} count number of items to show
* @returns {string} string representation of list
*/
const moreCount = (list, count) =>
list && list.length > 0 ? `+ ${count}` : `${count}`;
/** @type {Record<string, (thing: any, context: StatsPrinterContext, printer: StatsPrinter) => string | void>} */
const SIMPLE_PRINTERS = {
/**
* @template T
* @template {keyof T} K
* @typedef {{ [P in K]-?: T[P] }} WithRequired
*/
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation">, printer: StatsPrinter) => string | undefined>} */
const COMPILATION_SIMPLE_PRINTERS = {
"compilation.summary!": (
_,
{
@ -122,14 +136,16 @@ const SIMPLE_PRINTERS = {
) => {
const root = type === "compilation.summary!";
const warningsMessage =
warningsCount > 0
/** @type {number} */ (warningsCount) > 0
? yellow(
`${warningsCount} ${plural(warningsCount, "warning", "warnings")}`
`${warningsCount} ${plural(/** @type {number} */ (warningsCount), "warning", "warnings")}`
)
: "";
const errorsMessage =
errorsCount > 0
? red(`${errorsCount} ${plural(errorsCount, "error", "errors")}`)
/** @type {number} */ (errorsCount) > 0
? red(
`${errorsCount} ${plural(/** @type {number} */ (errorsCount), "error", "errors")}`
)
: "";
const timeMessage = root && time ? ` in ${formatTime(time)}` : "";
const hashMessage = hash ? ` (${hash})` : "";
@ -255,11 +271,12 @@ const SIMPLE_PRINTERS = {
"compilation.warningsInChildren!": (_, { yellow, compilation }) => {
if (
!compilation.children &&
compilation.warningsCount > 0 &&
/** @type {number} */ (compilation.warningsCount) > 0 &&
compilation.warnings
) {
const childWarnings =
compilation.warningsCount - compilation.warnings.length;
/** @type {number} */ (compilation.warningsCount) -
compilation.warnings.length;
if (childWarnings > 0) {
return yellow(
`${childWarnings} ${plural(
@ -278,10 +295,12 @@ const SIMPLE_PRINTERS = {
"compilation.errorsInChildren!": (_, { red, compilation }) => {
if (
!compilation.children &&
compilation.errorsCount > 0 &&
/** @type {number} */ (compilation.errorsCount) > 0 &&
compilation.errors
) {
const childErrors = compilation.errorsCount - compilation.errors.length;
const childErrors =
/** @type {number} */ (compilation.errorsCount) -
compilation.errors.length;
if (childErrors > 0) {
return red(
`${childErrors} ${plural(
@ -296,15 +315,16 @@ const SIMPLE_PRINTERS = {
);
}
}
},
}
};
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "asset">, printer: StatsPrinter) => string | undefined>} */
const ASSET_SIMPLE_PRINTERS = {
"asset.type": type => type,
"asset.name": (name, { formatFilename, asset: { isOverSizeLimit } }) =>
formatFilename(name, isOverSizeLimit),
"asset.size": (
size,
{ asset: { isOverSizeLimit }, yellow, green, formatSize }
) => (isOverSizeLimit ? yellow(formatSize(size)) : formatSize(size)),
"asset.size": (size, { asset: { isOverSizeLimit }, yellow, formatSize }) =>
isOverSizeLimit ? yellow(formatSize(size)) : formatSize(size),
"asset.emitted": (emitted, { green, formatFlag }) =>
emitted ? green(formatFlag("emitted")) : undefined,
"asset.comparedForEmit": (comparedForEmit, { yellow, formatFlag }) =>
@ -353,8 +373,11 @@ const SIMPLE_PRINTERS = {
assetChunk: (id, { formatChunkId }) => formatChunkId(id),
assetChunkName: name => name,
assetChunkIdHint: name => name,
assetChunkIdHint: name => name
};
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "module">, printer: StatsPrinter) => string | undefined>} */
const MODULE_SIMPLE_PRINTERS = {
"module.type": type => (type !== "module" ? type : undefined),
"module.id": (id, { formatModuleId }) =>
isValidId(id) ? formatModuleId(id) : undefined,
@ -467,11 +490,17 @@ const SIMPLE_PRINTERS = {
"modules"
)}`
: undefined,
"module.separator!": () => "\n",
"module.separator!": () => "\n"
};
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "moduleIssuer">, printer: StatsPrinter) => string | undefined>} */
const MODULE_ISSUER_PRINTERS = {
"moduleIssuer.id": (id, { formatModuleId }) => formatModuleId(id),
"moduleIssuer.profile.total": (value, { formatTime }) => formatTime(value),
"moduleIssuer.profile.total": (value, { formatTime }) => formatTime(value)
};
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "moduleReason">, printer: StatsPrinter) => string | undefined>} */
const MODULE_REASON_PRINTERS = {
"moduleReason.type": type => type,
"moduleReason.userRequest": (userRequest, { cyan }) =>
cyan(getResourceName(userRequest)),
@ -493,8 +522,11 @@ const SIMPLE_PRINTERS = {
"reason",
"reasons"
)}`
: undefined,
: undefined
};
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "profile">, printer: StatsPrinter) => string | undefined>} */
const MODULE_PROFILE_PRINTERS = {
"module.profile.total": (value, { formatTime }) => formatTime(value),
"module.profile.resolving": (value, { formatTime }) =>
`resolving: ${formatTime(value)}`,
@ -509,8 +541,11 @@ const SIMPLE_PRINTERS = {
"module.profile.additionalResolving": (value, { formatTime }) =>
value ? `additional resolving: ${formatTime(value)}` : undefined,
"module.profile.additionalIntegration": (value, { formatTime }) =>
value ? `additional integration: ${formatTime(value)}` : undefined,
value ? `additional integration: ${formatTime(value)}` : undefined
};
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "chunkGroupKind" | "chunkGroup">, printer: StatsPrinter) => string | undefined>} */
const CHUNK_GROUP_PRINTERS = {
"chunkGroup.kind!": (_, { chunkGroupKind }) => chunkGroupKind,
"chunkGroup.separator!": () => "\n",
"chunkGroup.name": (name, { bold }) => bold(name),
@ -538,10 +573,11 @@ const SIMPLE_PRINTERS = {
"chunkGroup.is!": () => "=",
"chunkGroupAsset.name": (asset, { green }) => green(asset),
"chunkGroupAsset.size": (size, { formatSize, chunkGroup }) =>
chunkGroup.assets.length > 1 ||
chunkGroup.assets &&
(chunkGroup.assets.length > 1 ||
(chunkGroup.auxiliaryAssets && chunkGroup.auxiliaryAssets.length > 0)
? formatSize(size)
: undefined,
: undefined),
"chunkGroup.children": (children, context, printer) =>
Array.isArray(children)
? undefined
@ -557,8 +593,11 @@ const SIMPLE_PRINTERS = {
"chunkGroupChild.assets[]": (file, { formatFilename }) =>
formatFilename(file),
"chunkGroupChild.chunks[]": (id, { formatChunkId }) => formatChunkId(id),
"chunkGroupChild.name": name => (name ? `(name: ${name})` : undefined),
"chunkGroupChild.name": name => (name ? `(name: ${name})` : undefined)
};
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "chunk">, printer: StatsPrinter) => string | undefined>} */
const CHUNK_PRINTERS = {
"chunk.id": (id, { formatChunkId }) => formatChunkId(id),
"chunk.files[]": (file, { formatFilename }) => formatFilename(file),
"chunk.names[]": name => name,
@ -608,8 +647,11 @@ const SIMPLE_PRINTERS = {
"chunkOrigin.moduleId": (moduleId, { formatModuleId }) =>
isValidId(moduleId) ? formatModuleId(moduleId) : undefined,
"chunkOrigin.moduleName": (moduleName, { bold }) => bold(moduleName),
"chunkOrigin.loc": loc => loc,
"chunkOrigin.loc": loc => loc
};
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "error">, printer: StatsPrinter) => string | undefined>} */
const ERROR_PRINTERS = {
"error.compilerPath": (compilerPath, { bold }) =>
compilerPath ? bold(`(${compilerPath})`) : undefined,
"error.chunkId": (chunkId, { formatChunkId }) =>
@ -631,8 +673,11 @@ const SIMPLE_PRINTERS = {
filteredDetails ? `+ ${filteredDetails} hidden lines` : undefined,
"error.stack": stack => stack,
"error.moduleTrace": moduleTrace => undefined,
"error.separator!": () => "\n",
"error.separator!": () => "\n"
};
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "logging">, printer: StatsPrinter) => string | undefined>} */
const LOG_ENTRY_PRINTERS = {
"loggingEntry(error).loggingEntry.message": (message, { red }) =>
mapLines(message, x => `<e> ${red(x)}`),
"loggingEntry(warn).loggingEntry.message": (message, { yellow }) =>
@ -662,20 +707,26 @@ const SIMPLE_PRINTERS = {
"loggingEntry.trace[]": trace =>
trace ? mapLines(trace, x => `| ${x}`) : undefined,
"moduleTraceItem.originName": originName => originName,
loggingGroup: loggingGroup =>
loggingGroup.entries.length === 0 ? "" : undefined,
"loggingGroup.debug": (flag, { red }) => (flag ? red("DEBUG") : undefined),
"loggingGroup.name": (name, { bold }) => bold(`LOG from ${name}`),
"loggingGroup.separator!": () => "\n",
"loggingGroup.filteredEntries": filteredEntries =>
filteredEntries > 0 ? `+ ${filteredEntries} hidden lines` : undefined,
filteredEntries > 0 ? `+ ${filteredEntries} hidden lines` : undefined
};
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "moduleTraceItem">, printer: StatsPrinter) => string | undefined>} */
const MODULE_TRACE_ITEM_PRINTERS = {
"moduleTraceItem.originName": originName => originName
};
/** @type {Record<string, (thing: any, context: Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "moduleTraceDependency">, printer: StatsPrinter) => string | undefined>} */
const MODULE_TRACE_DEPENDENCY_PRINTERS = {
"moduleTraceDependency.loc": loc => loc
};
/** @type {Record<string, string | Function>} */
/** @type {Record<string, string | function(any): string>} */
const ITEM_NAMES = {
"compilation.assets[]": "asset",
"compilation.modules[]": "module",
@ -904,19 +955,27 @@ const PREFERRED_ORDERS = {
loggingEntry: ["message", "trace", "children"]
};
/** @typedef {(items: string[]) => string | undefined} SimpleItemsJoiner */
/** @type {SimpleItemsJoiner} */
const itemsJoinOneLine = items => items.filter(Boolean).join(" ");
/** @type {SimpleItemsJoiner} */
const itemsJoinOneLineBrackets = items =>
items.length > 0 ? `(${items.filter(Boolean).join(" ")})` : undefined;
/** @type {SimpleItemsJoiner} */
const itemsJoinMoreSpacing = items => items.filter(Boolean).join("\n\n");
/** @type {SimpleItemsJoiner} */
const itemsJoinComma = items => items.filter(Boolean).join(", ");
/** @type {SimpleItemsJoiner} */
const itemsJoinCommaBrackets = items =>
items.length > 0 ? `(${items.filter(Boolean).join(", ")})` : undefined;
/** @type {function(string): SimpleItemsJoiner} */
const itemsJoinCommaBracketsWithName = name => items =>
items.length > 0
? `(${name}: ${items.filter(Boolean).join(", ")})`
: undefined;
/** @type {Record<string, (items: string[]) => string>} */
/** @type {Record<string, SimpleItemsJoiner>} */
const SIMPLE_ITEMS_JOINER = {
"chunk.parents": itemsJoinOneLine,
"chunk.siblings": itemsJoinOneLine,
@ -948,18 +1007,27 @@ const SIMPLE_ITEMS_JOINER = {
"compilation.errors": itemsJoinMoreSpacing,
"compilation.warnings": itemsJoinMoreSpacing,
"compilation.logging": itemsJoinMoreSpacing,
"compilation.children": items => indent(itemsJoinMoreSpacing(items), " "),
"compilation.children": items =>
indent(/** @type {string} */ (itemsJoinMoreSpacing(items)), " "),
"moduleTraceItem.dependencies": itemsJoinOneLine,
"loggingEntry.children": items =>
indent(items.filter(Boolean).join("\n"), " ", false)
};
/**
* @param {Item[]} items items
* @returns {string} result
*/
const joinOneLine = items =>
items
.map(item => item.content)
.filter(Boolean)
.join(" ");
/**
* @param {Item[]} items items
* @returns {string} result
*/
const joinInBrackets = items => {
const res = [];
let mode = 0;
@ -1002,6 +1070,12 @@ const joinInBrackets = items => {
return res.join("");
};
/**
* @param {string} str a string
* @param {string} prefix prefix
* @param {boolean=} noPrefixInFirstLine need prefix in the first line?
* @returns {string} result
*/
const indent = (str, prefix, noPrefixInFirstLine) => {
const rem = str.replace(/\n([^\n])/g, `\n${prefix}$1`);
if (noPrefixInFirstLine) return rem;
@ -1009,6 +1083,11 @@ const indent = (str, prefix, noPrefixInFirstLine) => {
return ind + rem;
};
/**
* @param {(false | Item)[]} items items
* @param {string} indenter indenter
* @returns {string} result
*/
const joinExplicitNewLine = (items, indenter) => {
let firstInLine = true;
let first = true;
@ -1030,15 +1109,27 @@ const joinExplicitNewLine = (items, indenter) => {
.trim();
};
/**
* @param {boolean} error is an error
* @returns {SimpleElementJoiner} joiner
*/
const joinError =
error =>
/**
* @param {Item[]} items items
* @param {Required<StatsPrinterContext>} ctx context
* @returns {string} result
*/
(items, { red, yellow }) =>
`${error ? red("ERROR") : yellow("WARNING")} in ${joinExplicitNewLine(
items,
""
)}`;
/** @type {Record<string, (items: ({ element: string, content: string })[], context: StatsPrinterContext) => string>} */
/** @typedef {{ element: string, content: string }} Item */
/** @typedef {(items: Item[], context: Required<StatsPrinterContext>) => string} SimpleElementJoiner */
/** @type {Record<string, SimpleElementJoiner>} */
const SIMPLE_ELEMENT_JOINERS = {
compilation: items => {
const result = [];
@ -1197,6 +1288,9 @@ const SIMPLE_ELEMENT_JOINERS = {
moduleTraceDependency: joinOneLine
};
/** @typedef {"bold" | "yellow" | "red" | "green" | "cyan" | "magenta"} ColorNames */
/** @type {Record<ColorNames, string>} */
const AVAILABLE_COLORS = {
bold: "\u001B[1m",
yellow: "\u001B[1m\u001B[33m",
@ -1206,6 +1300,7 @@ const AVAILABLE_COLORS = {
magenta: "\u001B[1m\u001B[35m"
};
/** @type {Record<string, function(any, Required<KnownStatsPrinterColorFn> & StatsPrinterContext, ...any): string>} */
const AVAILABLE_FORMATS = {
formatChunkId: (id, { yellow }, direction) => {
switch (direction) {
@ -1282,21 +1377,36 @@ const AVAILABLE_FORMATS = {
}
];
for (const { regExp, format } of highlights) {
message = message.replace(regExp, (match, content) =>
match.replace(content, format(content))
message = message.replace(
regExp,
/**
* @param {string} match match
* @param {string} content content
* @returns {string} result
*/
(match, content) => match.replace(content, format(content))
);
}
return message;
}
};
/** @typedef {function(string): string} ResultModifierFn */
/** @type {Record<string, ResultModifierFn>} */
const RESULT_MODIFIER = {
"module.modules": result => indent(result, "| ")
};
/**
* @param {string[]} array array
* @param {string[]} preferredOrder preferred order
* @returns {string[]} result
*/
const createOrder = (array, preferredOrder) => {
const originalArray = array.slice();
/** @type {Set<string>} */
const set = new Set(array);
/** @type {Set<string>} */
const usedSet = new Set();
array.length = 0;
for (const element of preferredOrder) {
@ -1323,24 +1433,30 @@ class DefaultStatsPrinterPlugin {
compiler.hooks.compilation.tap("DefaultStatsPrinterPlugin", compilation => {
compilation.hooks.statsPrinter.tap(
"DefaultStatsPrinterPlugin",
(stats, options, context) => {
(stats, options) => {
// Put colors into context
stats.hooks.print
.for("compilation")
.tap("DefaultStatsPrinterPlugin", (compilation, context) => {
for (const color of Object.keys(AVAILABLE_COLORS)) {
const name = /** @type {ColorNames} */ (color);
/** @type {string | undefined} */
let start;
if (options.colors) {
if (
typeof options.colors === "object" &&
typeof options.colors[color] === "string"
typeof options.colors[name] === "string"
) {
start = options.colors[color];
start = options.colors[name];
} else {
start = AVAILABLE_COLORS[color];
start = AVAILABLE_COLORS[name];
}
}
if (start) {
/**
* @param {string} str string
* @returns {string} string with color
*/
context[color] = str =>
`${start}${
typeof str === "string"
@ -1351,21 +1467,184 @@ class DefaultStatsPrinterPlugin {
: str
}\u001B[39m\u001B[22m`;
} else {
/**
* @param {string} str string
* @returns {string} str string
*/
context[color] = str => str;
}
}
for (const format of Object.keys(AVAILABLE_FORMATS)) {
context[format] = (content, ...args) =>
AVAILABLE_FORMATS[format](content, context, ...args);
context[format] =
/**
* @param {string | number} content content
* @param {...TODO} args args
* @returns {string} result
*/
(content, ...args) =>
AVAILABLE_FORMATS[format](
content,
/** @type {Required<KnownStatsPrinterColorFn> & StatsPrinterContext} */
(context),
...args
);
}
context.timeReference = compilation.time;
});
for (const key of Object.keys(SIMPLE_PRINTERS)) {
for (const key of Object.keys(COMPILATION_SIMPLE_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
SIMPLE_PRINTERS[key](obj, ctx, stats)
COMPILATION_SIMPLE_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation">} */
(ctx),
stats
)
);
}
for (const key of Object.keys(ASSET_SIMPLE_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
ASSET_SIMPLE_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "asset">} */
(ctx),
stats
)
);
}
for (const key of Object.keys(MODULE_SIMPLE_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
MODULE_SIMPLE_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "module">} */
(ctx),
stats
)
);
}
for (const key of Object.keys(MODULE_ISSUER_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
MODULE_ISSUER_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "moduleIssuer">} */
(ctx),
stats
)
);
}
for (const key of Object.keys(MODULE_REASON_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
MODULE_REASON_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "moduleReason">} */
(ctx),
stats
)
);
}
for (const key of Object.keys(MODULE_PROFILE_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
MODULE_PROFILE_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "profile">} */
(ctx),
stats
)
);
}
for (const key of Object.keys(CHUNK_GROUP_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
CHUNK_GROUP_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "chunkGroupKind" | "chunkGroup">} */
(ctx),
stats
)
);
}
for (const key of Object.keys(CHUNK_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
CHUNK_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "chunk">} */
(ctx),
stats
)
);
}
for (const key of Object.keys(ERROR_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
ERROR_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "error">} */
(ctx),
stats
)
);
}
for (const key of Object.keys(LOG_ENTRY_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
LOG_ENTRY_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "logging">} */
(ctx),
stats
)
);
}
for (const key of Object.keys(MODULE_TRACE_DEPENDENCY_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
MODULE_TRACE_DEPENDENCY_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "moduleTraceDependency">} */
(ctx),
stats
)
);
}
for (const key of Object.keys(MODULE_TRACE_ITEM_PRINTERS)) {
stats.hooks.print
.for(key)
.tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
MODULE_TRACE_ITEM_PRINTERS[key](
obj,
/** @type {Required<KnownStatsPrinterColorFn> & Required<KnownStatsPrinterFormaters> & WithRequired<StatsPrinterContext, "type" | "compilation" | "moduleTraceItem">} */
(ctx),
stats
)
);
}
@ -1399,7 +1678,7 @@ class DefaultStatsPrinterPlugin {
const joiner = SIMPLE_ELEMENT_JOINERS[key];
stats.hooks.printElements
.for(key)
.tap("DefaultStatsPrinterPlugin", joiner);
.tap("DefaultStatsPrinterPlugin", /** @type {TODO} */ (joiner));
}
for (const key of Object.keys(RESULT_MODIFIER)) {

View File

@ -11,83 +11,108 @@ const smartGrouping = require("../util/smartGrouping");
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../Compilation").NormalizedStatsOptions} NormalizedStatsOptions */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../WebpackError")} WebpackError */
/** @typedef {import("../util/comparators").Comparator<any>} Comparator */
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
/** @typedef {import("../util/smartGrouping").GroupConfig<any, object>} GroupConfig */
/**
* @typedef {object} KnownStatsFactoryContext
* @property {string} type
* @property {function(string): string=} makePathsRelative
* @property {Compilation=} compilation
* @property {Set<Module>=} rootModules
* @property {Map<string,Chunk[]>=} compilationFileToChunks
* @property {Map<string,Chunk[]>=} compilationAuxiliaryFileToChunks
* @property {RuntimeSpec=} runtime
* @property {function(Compilation): WebpackError[]=} cachedGetErrors
* @property {function(Compilation): WebpackError[]=} cachedGetWarnings
* @property {function(string): string} makePathsRelative
* @property {Compilation} compilation
* @property {Set<Module>} rootModules
* @property {Map<string,Chunk[]>} compilationFileToChunks
* @property {Map<string,Chunk[]>} compilationAuxiliaryFileToChunks
* @property {RuntimeSpec} runtime
* @property {function(Compilation): WebpackError[]} cachedGetErrors
* @property {function(Compilation): WebpackError[]} cachedGetWarnings
*/
/** @typedef {KnownStatsFactoryContext & Record<string, any>} StatsFactoryContext */
/** @typedef {Record<string, any> & KnownStatsFactoryContext} StatsFactoryContext */
/** @typedef {any} CreatedObject */
/** @typedef {any} FactoryData */
/** @typedef {any} FactoryDataItem */
/** @typedef {any} Result */
/** @typedef {Record<string, any>} ObjectForExtract */
/**
* @typedef {object} StatsFactoryHooks
* @property {HookMap<SyncBailHook<[ObjectForExtract, FactoryData, StatsFactoryContext], undefined>>} extract
* @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext, number, number], boolean | undefined>>} filter
* @property {HookMap<SyncBailHook<[Comparator[], StatsFactoryContext], undefined>>} sort
* @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext, number, number], boolean | undefined>>} filterSorted
* @property {HookMap<SyncBailHook<[GroupConfig[], StatsFactoryContext], undefined>>} groupResults
* @property {HookMap<SyncBailHook<[Comparator[], StatsFactoryContext], undefined>>} sortResults
* @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext, number, number], boolean | undefined>>} filterResults
* @property {HookMap<SyncBailHook<[FactoryDataItem[], StatsFactoryContext], Result>>} merge
* @property {HookMap<SyncBailHook<[Result, StatsFactoryContext], Result>>} result
* @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext], string>>} getItemName
* @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext], StatsFactory | undefined>>} getItemFactory
*/
/**
* @template T
* @typedef {Map<string, T[]>} Caches
*/
class StatsFactory {
constructor() {
/** @type {StatsFactoryHooks} */
this.hooks = Object.freeze({
/** @type {HookMap<SyncBailHook<[object, any, StatsFactoryContext]>>} */
extract: new HookMap(
() => new SyncBailHook(["object", "data", "context"])
),
/** @type {HookMap<SyncBailHook<[any, StatsFactoryContext, number, number]>>} */
filter: new HookMap(
() => new SyncBailHook(["item", "context", "index", "unfilteredIndex"])
),
/** @type {HookMap<SyncBailHook<[(function(any, any): number)[], StatsFactoryContext]>>} */
sort: new HookMap(() => new SyncBailHook(["comparators", "context"])),
/** @type {HookMap<SyncBailHook<[any, StatsFactoryContext, number, number]>>} */
filterSorted: new HookMap(
() => new SyncBailHook(["item", "context", "index", "unfilteredIndex"])
),
/** @type {HookMap<SyncBailHook<[GroupConfig[], StatsFactoryContext]>>} */
groupResults: new HookMap(
() => new SyncBailHook(["groupConfigs", "context"])
),
/** @type {HookMap<SyncBailHook<[(function(any, any): number)[], StatsFactoryContext]>>} */
sortResults: new HookMap(
() => new SyncBailHook(["comparators", "context"])
),
/** @type {HookMap<SyncBailHook<[any, StatsFactoryContext, number, number]>>} */
filterResults: new HookMap(
() => new SyncBailHook(["item", "context", "index", "unfilteredIndex"])
),
/** @type {HookMap<SyncBailHook<[any[], StatsFactoryContext]>>} */
merge: new HookMap(() => new SyncBailHook(["items", "context"])),
/** @type {HookMap<SyncBailHook<[any[], StatsFactoryContext]>>} */
result: new HookMap(() => new SyncWaterfallHook(["result", "context"])),
/** @type {HookMap<SyncBailHook<[any, StatsFactoryContext]>>} */
getItemName: new HookMap(() => new SyncBailHook(["item", "context"])),
/** @type {HookMap<SyncBailHook<[any, StatsFactoryContext]>>} */
getItemFactory: new HookMap(() => new SyncBailHook(["item", "context"]))
});
const hooks = this.hooks;
this._caches =
/** @type {Record<keyof typeof hooks, Map<string, SyncBailHook<[any[], StatsFactoryContext]>[]>>} */ ({});
this._caches = /** @type {TODO} */ ({});
for (const key of Object.keys(hooks)) {
this._caches[key] = new Map();
this._caches[/** @type {keyof StatsFactoryHooks} */ (key)] = new Map();
}
this._inCreate = false;
}
/**
* @template {StatsFactoryHooks[keyof StatsFactoryHooks]} HM
* @template {HM extends HookMap<infer H> ? H : never} H
* @param {HM} hookMap hook map
* @param {Caches<H>} cache cache
* @param {string} type type
* @returns {H[]} hooks
* @private
*/
_getAllLevelHooks(hookMap, cache, type) {
const cacheEntry = cache.get(type);
if (cacheEntry !== undefined) {
return cacheEntry;
}
const hooks = [];
const hooks = /** @type {H[]} */ ([]);
const typeParts = type.split(".");
for (let i = 0; i < typeParts.length; i++) {
const hook = hookMap.get(typeParts.slice(i).join("."));
const hook = /** @type {H} */ (hookMap.get(typeParts.slice(i).join(".")));
if (hook) {
hooks.push(hook);
}
@ -96,27 +121,62 @@ class StatsFactory {
return hooks;
}
/**
* @template {StatsFactoryHooks[keyof StatsFactoryHooks]} HM
* @template {HM extends HookMap<infer H> ? H : never} H
* @template {H extends import("tapable").Hook<any, infer R> ? R : never} R
* @param {HM} hookMap hook map
* @param {Caches<H>} cache cache
* @param {string} type type
* @param {function(H): R | undefined} fn fn
* @returns {R | undefined} hook
* @private
*/
_forEachLevel(hookMap, cache, type, fn) {
for (const hook of this._getAllLevelHooks(hookMap, cache, type)) {
const result = fn(hook);
const result = fn(/** @type {H} */ (hook));
if (result !== undefined) return result;
}
}
/**
* @template {StatsFactoryHooks[keyof StatsFactoryHooks]} HM
* @template {HM extends HookMap<infer H> ? H : never} H
* @param {HM} hookMap hook map
* @param {Caches<H>} cache cache
* @param {string} type type
* @param {FactoryData} data data
* @param {function(H, FactoryData): FactoryData} fn fn
* @returns {FactoryData} data
* @private
*/
_forEachLevelWaterfall(hookMap, cache, type, data, fn) {
for (const hook of this._getAllLevelHooks(hookMap, cache, type)) {
data = fn(hook, data);
data = fn(/** @type {H} */ (hook), data);
}
return data;
}
/**
* @template {StatsFactoryHooks[keyof StatsFactoryHooks]} T
* @template {T extends HookMap<infer H> ? H : never} H
* @template {H extends import("tapable").Hook<any, infer R> ? R : never} R
* @param {T} hookMap hook map
* @param {Caches<H>} cache cache
* @param {string} type type
* @param {Array<FactoryData>} items items
* @param {function(H, R, number, number): R | undefined} fn fn
* @param {boolean} forceClone force clone
* @returns {R[]} result for each level
* @private
*/
_forEachLevelFilter(hookMap, cache, type, items, fn, forceClone) {
const hooks = this._getAllLevelHooks(hookMap, cache, type);
if (hooks.length === 0) return forceClone ? items.slice() : items;
let i = 0;
return items.filter((item, idx) => {
for (const hook of hooks) {
const r = fn(hook, item, idx, i);
const r = fn(/** @type {H} */ (hook), item, idx, i);
if (r !== undefined) {
if (r) i++;
return r;
@ -129,9 +189,9 @@ class StatsFactory {
/**
* @param {string} type type
* @param {any} data factory data
* @param {FactoryData} data factory data
* @param {Omit<StatsFactoryContext, "type">} baseContext context used as base
* @returns {any} created object
* @returns {CreatedObject} created object
*/
create(type, data, baseContext) {
if (this._inCreate) {
@ -141,17 +201,25 @@ class StatsFactory {
this._inCreate = true;
return this._create(type, data, baseContext);
} finally {
for (const key of Object.keys(this._caches)) this._caches[key].clear();
for (const key of Object.keys(this._caches))
this._caches[/** @type {keyof StatsFactoryHooks} */ (key)].clear();
this._inCreate = false;
}
}
/**
* @param {string} type type
* @param {FactoryData} data factory data
* @param {Omit<StatsFactoryContext, "type">} baseContext context used as base
* @returns {CreatedObject} created object
* @private
*/
_create(type, data, baseContext) {
const context = {
const context = /** @type {StatsFactoryContext} */ ({
...baseContext,
type,
[type]: data
};
});
if (Array.isArray(data)) {
// run filter on unsorted items
const items = this._forEachLevelFilter(
@ -164,6 +232,7 @@ class StatsFactory {
);
// sort items
/** @type {Comparator[]} */
const comparators = [];
this._forEachLevel(this.hooks.sort, this._caches.sort, type, h =>
h.call(comparators, context)
@ -187,6 +256,7 @@ class StatsFactory {
// for each item
let resultItems = items2.map((item, i) => {
/** @type {StatsFactoryContext} */
const itemContext = {
...context,
_index: i
@ -216,6 +286,7 @@ class StatsFactory {
});
// sort result items
/** @type {Comparator[]} */
const comparators2 = [];
this._forEachLevel(
this.hooks.sortResults,
@ -231,6 +302,7 @@ class StatsFactory {
}
// group result items
/** @type {GroupConfig[]} */
const groupConfigs = [];
this._forEachLevel(
this.hooks.groupResults,
@ -270,6 +342,7 @@ class StatsFactory {
(h, r) => h.call(r, context)
);
}
/** @type {ObjectForExtract} */
const object = {};
// run extract on value

View File

@ -7,14 +7,18 @@
const { HookMap, SyncWaterfallHook, SyncBailHook } = require("tapable");
/** @template T @typedef {import("tapable").AsArray<T>} AsArray<T> */
/** @typedef {import("tapable").Hook} Hook */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsAsset} StatsAsset */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsChunk} StatsChunk */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsChunkGroup} StatsChunkGroup */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsCompilation} StatsCompilation */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsError} StatsError */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsLogging} StatsLogging */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModule} StatsModule */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleIssuer} StatsModuleIssuer */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleReason} StatsModuleReason */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleTraceDependency} StatsModuleTraceDependency */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleTraceItem} StatsModuleTraceItem */
/** @typedef {import("./DefaultStatsFactoryPlugin").StatsProfile} StatsProfile */
/**
* @typedef {object} PrintedElement
@ -27,53 +31,78 @@ const { HookMap, SyncWaterfallHook, SyncBailHook } = require("tapable");
* @property {string=} type
* @property {StatsCompilation=} compilation
* @property {StatsChunkGroup=} chunkGroup
* @property {string=} chunkGroupKind
* @property {StatsAsset=} asset
* @property {StatsModule=} module
* @property {StatsChunk=} chunk
* @property {StatsModuleReason=} moduleReason
* @property {StatsModuleIssuer=} moduleIssuer
* @property {StatsError=} error
* @property {StatsProfile=} profile
* @property {StatsLogging=} logging
* @property {StatsModuleTraceItem=} moduleTraceItem
* @property {StatsModuleTraceDependency=} moduleTraceDependency
*/
/**
* @typedef {object} KnownStatsPrinterColorFn
* @property {(str: string) => string=} bold
* @property {(str: string) => string=} yellow
* @property {(str: string) => string=} red
* @property {(str: string) => string=} green
* @property {(str: string) => string=} magenta
* @property {(str: string) => string=} cyan
*/
/**
* @typedef {object} KnownStatsPrinterFormaters
* @property {(file: string, oversize?: boolean) => string=} formatFilename
* @property {(id: string) => string=} formatModuleId
* @property {(id: string, direction?: "parent"|"child"|"sibling") => string=} formatChunkId
* @property {(size: number) => string=} formatSize
* @property {(size: string) => string=} formatLayer
* @property {(dateTime: number) => string=} formatDateTime
* @property {(flag: string) => string=} formatFlag
* @property {(time: number, boldQuantity?: boolean) => string=} formatTime
* @property {string=} chunkGroupKind
* @property {(message: string) => string=} formatError
*/
/** @typedef {KnownStatsPrinterContext & Record<string, any>} StatsPrinterContext */
/** @typedef {Record<string, any> & KnownStatsPrinterColorFn & KnownStatsPrinterFormaters & KnownStatsPrinterContext} StatsPrinterContext */
/** @typedef {any} PrintObject */
/**
* @typedef {object} StatsPrintHooks
* @property {HookMap<SyncBailHook<[string[], StatsPrinterContext], void>>} sortElements
* @property {HookMap<SyncBailHook<[PrintedElement[], StatsPrinterContext], string | undefined>>} printElements
* @property {HookMap<SyncBailHook<[PrintObject[], StatsPrinterContext], true>>} sortItems
* @property {HookMap<SyncBailHook<[PrintObject, StatsPrinterContext], string>>} getItemName
* @property {HookMap<SyncBailHook<[string[], StatsPrinterContext], string | undefined>>} printItems
* @property {HookMap<SyncBailHook<[PrintObject, StatsPrinterContext], string | void>>} print
* @property {HookMap<SyncWaterfallHook<[string, StatsPrinterContext]>>} result
*/
class StatsPrinter {
constructor() {
/** @type {StatsPrintHooks} */
this.hooks = Object.freeze({
/** @type {HookMap<SyncBailHook<[string[], StatsPrinterContext], true>>} */
sortElements: new HookMap(
() => new SyncBailHook(["elements", "context"])
),
/** @type {HookMap<SyncBailHook<[PrintedElement[], StatsPrinterContext], string>>} */
printElements: new HookMap(
() => new SyncBailHook(["printedElements", "context"])
),
/** @type {HookMap<SyncBailHook<[any[], StatsPrinterContext], true>>} */
sortItems: new HookMap(() => new SyncBailHook(["items", "context"])),
/** @type {HookMap<SyncBailHook<[any, StatsPrinterContext], string>>} */
getItemName: new HookMap(() => new SyncBailHook(["item", "context"])),
/** @type {HookMap<SyncBailHook<[string[], StatsPrinterContext], string>>} */
printItems: new HookMap(
() => new SyncBailHook(["printedItems", "context"])
),
/** @type {HookMap<SyncBailHook<[{}, StatsPrinterContext], string>>} */
print: new HookMap(() => new SyncBailHook(["object", "context"])),
/** @type {HookMap<SyncWaterfallHook<[string, StatsPrinterContext]>>} */
result: new HookMap(() => new SyncWaterfallHook(["result", "context"]))
});
/** @type {Map<HookMap<Hook>, Map<string, Hook[]>>} */
/**
* @type {TODO}
*/
this._levelHookCache = new Map();
this._inPrint = false;
}
@ -81,15 +110,14 @@ class StatsPrinter {
/**
* get all level hooks
* @private
* @template {Hook} T
* @param {HookMap<T>} hookMap HookMap
* @template {StatsPrintHooks[keyof StatsPrintHooks]} HM
* @template {HM extends HookMap<infer H> ? H : never} H
* @param {HM} hookMap hook map
* @param {string} type type
* @returns {T[]} hooks
* @returns {H[]} hooks
*/
_getAllLevelHooks(hookMap, type) {
let cache = /** @type {Map<string, T[]>} */ (
this._levelHookCache.get(hookMap)
);
let cache = this._levelHookCache.get(hookMap);
if (cache === undefined) {
cache = new Map();
this._levelHookCache.set(hookMap, cache);
@ -98,11 +126,11 @@ class StatsPrinter {
if (cacheEntry !== undefined) {
return cacheEntry;
}
/** @type {T[]} */
/** @type {H[]} */
const hooks = [];
const typeParts = type.split(".");
for (let i = 0; i < typeParts.length; i++) {
const hook = hookMap.get(typeParts.slice(i).join("."));
const hook = /** @type {H} */ (hookMap.get(typeParts.slice(i).join(".")));
if (hook) {
hooks.push(hook);
}
@ -114,16 +142,17 @@ class StatsPrinter {
/**
* Run `fn` for each level
* @private
* @template T
* @template R
* @param {HookMap<SyncBailHook<T, R>>} hookMap HookMap
* @template {StatsPrintHooks[keyof StatsPrintHooks]} HM
* @template {HM extends HookMap<infer H> ? H : never} H
* @template {H extends import("tapable").Hook<any, infer R> ? R : never} R
* @param {HM} hookMap hook map
* @param {string} type type
* @param {(hook: SyncBailHook<T, R>) => R} fn function
* @returns {R} result of `fn`
* @param {function(H): R | undefined} fn fn
* @returns {R | undefined} hook
*/
_forEachLevel(hookMap, type, fn) {
for (const hook of this._getAllLevelHooks(hookMap, type)) {
const result = fn(hook);
const result = fn(/** @type {H} */ (hook));
if (result !== undefined) return result;
}
}
@ -131,24 +160,25 @@ class StatsPrinter {
/**
* Run `fn` for each level
* @private
* @template T
* @param {HookMap<SyncWaterfallHook<T>>} hookMap HookMap
* @template {StatsPrintHooks[keyof StatsPrintHooks]} HM
* @template {HM extends HookMap<infer H> ? H : never} H
* @param {HM} hookMap hook map
* @param {string} type type
* @param {AsArray<T>[0]} data data
* @param {(hook: SyncWaterfallHook<T>, data: AsArray<T>[0]) => AsArray<T>[0]} fn function
* @returns {AsArray<T>[0]} result of `fn`
* @param {string} data data
* @param {function(H, string): string} fn fn
* @returns {string} result of `fn`
*/
_forEachLevelWaterfall(hookMap, type, data, fn) {
for (const hook of this._getAllLevelHooks(hookMap, type)) {
data = fn(hook, data);
data = fn(/** @type {H} */ (hook), data);
}
return data;
}
/**
* @param {string} type The type
* @param {object} object Object to print
* @param {object=} baseContext The base context
* @param {PrintObject} object Object to print
* @param {StatsPrinterContext=} baseContext The base context
* @returns {string} printed result
*/
print(type, object, baseContext) {
@ -167,11 +197,12 @@ class StatsPrinter {
/**
* @private
* @param {string} type type
* @param {object} object object
* @param {object=} baseContext context
* @param {PrintObject} object object
* @param {StatsPrinterContext=} baseContext context
* @returns {string} printed result
*/
_print(type, object, baseContext) {
/** @type {StatsPrinterContext} */
const context = {
...baseContext,
type,
@ -188,6 +219,7 @@ class StatsPrinter {
h.call(sortedItems, context)
);
const printedItems = sortedItems.map((item, i) => {
/** @type {StatsPrinterContext} */
const itemContext = {
...context,
_index: i
@ -240,7 +272,7 @@ class StatsPrinter {
return this._forEachLevelWaterfall(
this.hooks.result,
type,
printResult,
/** @type {string} */ (printResult),
(h, r) => h.call(r, context)
);
}

View File

@ -20,7 +20,7 @@ let inHandleResult = 0;
* @template T
* @callback Callback
* @param {(WebpackError | null)=} err
* @param {T=} result
* @param {(T | null)=} result
*/
/**
@ -37,15 +37,27 @@ class AsyncQueueEntry {
this.item = item;
/** @type {typeof QUEUED_STATE | typeof PROCESSING_STATE | typeof DONE_STATE} */
this.state = QUEUED_STATE;
/** @type {Callback<R> | undefined} */
this.callback = callback;
/** @type {Callback<R>[] | undefined} */
this.callbacks = undefined;
/** @type {R | null | undefined} */
this.result = undefined;
/** @type {WebpackError | undefined} */
/** @type {WebpackError | null | undefined} */
this.error = undefined;
}
}
/**
* @template T, K
* @typedef {function(T): K} getKey
*/
/**
* @template T, R
* @typedef {function(T, Callback<R>): void} Processor
*/
/**
* @template T
* @template K
@ -57,15 +69,16 @@ class AsyncQueue {
* @param {string=} options.name name of the queue
* @param {number=} options.parallelism how many items should be processed at once
* @param {AsyncQueue<any, any, any>=} options.parent parent queue, which will have priority over this queue and with shared parallelism
* @param {function(T): K=} options.getKey extract key from item
* @param {function(T, Callback<R>): void} options.processor async function to process items
* @param {getKey<T, K>=} options.getKey extract key from item
* @param {Processor<T, R>} options.processor async function to process items
*/
constructor({ name, parallelism, parent, processor, getKey }) {
this._name = name;
this._parallelism = parallelism || 1;
this._processor = processor;
this._getKey =
getKey || /** @type {(T) => K} */ (item => /** @type {any} */ (item));
getKey ||
/** @type {getKey<T, K>} */ (item => /** @type {T & K} */ (item));
/** @type {Map<K, AsyncQueueEntry<T, K, R>>} */
this._entries = new Map();
/** @type {ArrayQueue<AsyncQueueEntry<T, K, R>>} */
@ -76,6 +89,7 @@ class AsyncQueue {
this._willEnsureProcessing = false;
this._needProcessing = false;
this._stopped = false;
/** @type {AsyncQueue<any, any, any>} */
this._root = parent ? parent._root : this;
if (parent) {
if (this._root._children === undefined) {
@ -94,7 +108,7 @@ class AsyncQueue {
beforeStart: new AsyncSeriesHook(["item"]),
/** @type {SyncHook<[T]>} */
started: new SyncHook(["item"]),
/** @type {SyncHook<[T, Error, R]>} */
/** @type {SyncHook<[T, WebpackError | null | undefined, R | null | undefined]>} */
result: new SyncHook(["item", "error", "result"])
};
@ -202,9 +216,14 @@ class AsyncQueue {
this._queued = new ArrayQueue();
const root = this._root;
for (const entry of queue) {
this._entries.delete(this._getKey(entry.item));
this._entries.delete(
this._getKey(/** @type {AsyncQueueEntry<T, K, R>} */ (entry).item)
);
root._activeTasks++;
this._handleResult(entry, new WebpackError("Queue was stopped"));
this._handleResult(
/** @type {AsyncQueueEntry<T, K, R>} */ (entry),
new WebpackError("Queue was stopped")
);
}
}
@ -308,7 +327,7 @@ class AsyncQueue {
});
} catch (err) {
if (inCallback) throw err;
this._handleResult(entry, err, null);
this._handleResult(entry, /** @type {WebpackError} */ (err), null);
}
this.hooks.started.call(entry.item);
});
@ -316,8 +335,8 @@ class AsyncQueue {
/**
* @param {AsyncQueueEntry<T, K, R>} entry the entry
* @param {WebpackError=} err error, if any
* @param {R=} result result, if any
* @param {(WebpackError | null)=} err error, if any
* @param {(R | null)=} result result, if any
* @returns {void}
*/
_handleResult(entry, err, result) {
@ -326,7 +345,7 @@ class AsyncQueue {
? makeWebpackError(hookError, `AsyncQueue(${this._name}).hooks.result`)
: err;
const callback = entry.callback;
const callback = /** @type {Callback<R>} */ (entry.callback);
const callbacks = entry.callbacks;
entry.state = DONE_STATE;
entry.callback = undefined;

View File

@ -24,7 +24,7 @@ class SortableSet extends Set {
super(initialIterable);
/**
* @private
* @type {undefined | function(T, T): number}}
* @type {undefined | SortFunction<T>}
*/
this._sortFn = defaultSort;
/**
@ -77,7 +77,7 @@ class SortableSet extends Set {
/**
* Sort with a comparer function
* @param {SortFunction<T>} sortFn Sorting comparer function
* @param {SortFunction<T> | undefined} sortFn Sorting comparer function
* @returns {void}
*/
sortWith(sortFn) {

View File

@ -92,7 +92,7 @@ class StackedCacheMap {
/**
* @param {K} item the key of the element to return
* @returns {V} the value of the element
* @returns {V | undefined} the value of the element
*/
get(item) {
for (const map of this.stack) {
@ -128,7 +128,7 @@ class StackedCacheMap {
next() {
let result = current.next();
while (result.done && iterators.length > 0) {
current = iterators.pop();
current = /** @type {IterableIterator<[K, V]>} */ (iterators.pop());
result = current.next();
}
return result;

View File

@ -10,14 +10,26 @@ const { compareRuntime } = require("./runtime");
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Chunk").ChunkId} ChunkId */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("../ChunkGroup")} ChunkGroup */
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../ModuleGraph")} ModuleGraph */
/** @template T @typedef {function(T, T): -1|0|1} Comparator */
/** @template TArg @template T @typedef {function(TArg, T, T): -1|0|1} RawParameterizedComparator */
/** @template TArg @template T @typedef {function(TArg): Comparator<T>} ParameterizedComparator */
/**
* @template T
* @typedef {function(T, T): -1|0|1} Comparator
*/
/**
* @template TArg
* @template T
* @typedef {function(TArg, T, T): -1|0|1} RawParameterizedComparator
*/
/**
* @template TArg
* @template T
* @typedef {function(TArg): Comparator<T>} ParameterizedComparator
*/
/**
* @template T
@ -64,7 +76,10 @@ module.exports.compareModulesByIdentifier = (a, b) =>
* @returns {-1|0|1} compare result
*/
const compareModulesById = (chunkGraph, a, b) =>
compareIds(chunkGraph.getModuleId(a), chunkGraph.getModuleId(b));
compareIds(
/** @type {ModuleId} */ (chunkGraph.getModuleId(a)),
/** @type {ModuleId} */ (chunkGraph.getModuleId(b))
);
/** @type {ParameterizedComparator<ChunkGraph, Module>} */
module.exports.compareModulesById =
createCachedParameterizedComparator(compareModulesById);
@ -203,7 +218,10 @@ module.exports.compareModulesByPreOrderIndexOrIdentifier =
* @returns {-1|0|1} compare result
*/
const compareModulesByIdOrIdentifier = (chunkGraph, a, b) => {
const cmp = compareIds(chunkGraph.getModuleId(a), chunkGraph.getModuleId(b));
const cmp = compareIds(
/** @type {ModuleId} */ (chunkGraph.getModuleId(a)),
/** @type {ModuleId} */ (chunkGraph.getModuleId(b))
);
if (cmp !== 0) return cmp;
return compareIds(a.identifier(), b.identifier());
};

View File

@ -229,7 +229,7 @@ class Group {
newSimilarities.push(
lastNode === this.nodes[i - 1]
? /** @type {number[]} */ (this.similarities)[i - 1]
: similarity(lastNode.key, node.key)
: similarity(/** @type {Node<T>} */ (lastNode).key, node.key)
);
}
newNodes.push(node);

View File

@ -85,24 +85,48 @@ const requestToAbsolute = (context, relativePath) => {
return relativePath;
};
/**
* @template T
* @typedef {function(string, object=): T} MakeCacheableResult
*/
/**
* @template T
* @typedef {function(string): T} BindCacheResultFn
*/
/**
* @template T
* @typedef {function(object): BindCacheResultFn<T>} BindCache
*/
/**
* @template T
* @param {(function(string): T)} realFn real function
* @returns {MakeCacheableResult<T> & { bindCache: BindCache<T> }} cacheable function
*/
const makeCacheable = realFn => {
/** @type {WeakMap<object, Map<string, ParsedResource>>} */
/**
* @template T
* @typedef {Map<string, T>} CacheItem
*/
/** @type {WeakMap<object, CacheItem<T>>} */
const cache = new WeakMap();
/**
* @param {object} associatedObjectForCache an object to which the cache will be attached
* @returns {CacheItem<T>} cache item
*/
const getCache = associatedObjectForCache => {
const entry = cache.get(associatedObjectForCache);
if (entry !== undefined) return entry;
/** @type {Map<string, ParsedResource>} */
/** @type {Map<string, T>} */
const map = new Map();
cache.set(associatedObjectForCache, map);
return map;
};
/**
* @param {string} str the path with query and fragment
* @param {object=} associatedObjectForCache an object to which the cache will be attached
* @returns {ParsedResource} parsed parts
*/
/** @type {MakeCacheableResult<T> & { bindCache: BindCache<T> }} */
const fn = (str, associatedObjectForCache) => {
if (!associatedObjectForCache) return realFn(str);
const cache = getCache(associatedObjectForCache);
@ -113,8 +137,13 @@ const makeCacheable = realFn => {
return result;
};
/** @type {BindCache<T>} */
fn.bindCache = associatedObjectForCache => {
const cache = getCache(associatedObjectForCache);
/**
* @param {string} str string
* @returns {T} value
*/
return str => {
const entry = cache.get(str);
if (entry !== undefined) return entry;
@ -127,16 +156,21 @@ const makeCacheable = realFn => {
return fn;
};
/** @typedef {function(string, string, object=): string} MakeCacheableWithContextResult */
/** @typedef {function(string, string): string} BindCacheForContextResultFn */
/** @typedef {function(string): string} BindContextCacheForContextResultFn */
/** @typedef {function(object=): BindCacheForContextResultFn} BindCacheForContext */
/** @typedef {function(string, object=): BindContextCacheForContextResultFn} BindContextCacheForContext */
/**
* @param {function(string, string): string} fn function
* @returns {MakeCacheableWithContextResult & { bindCache: BindCacheForContext, bindContextCache: BindContextCacheForContext }} cacheable function with context
*/
const makeCacheableWithContext = fn => {
/** @type {WeakMap<object, Map<string, Map<string, string>>>} */
const cache = new WeakMap();
/**
* @param {string} context context used to create relative path
* @param {string} identifier identifier used to create relative path
* @param {object=} associatedObjectForCache an object to which the cache will be attached
* @returns {string} the returned relative path
*/
/** @type {MakeCacheableWithContextResult & { bindCache: BindCacheForContext, bindContextCache: BindContextCacheForContext }} */
const cachedFn = (context, identifier, associatedObjectForCache) => {
if (!associatedObjectForCache) return fn(context, identifier);
@ -162,10 +196,7 @@ const makeCacheableWithContext = fn => {
return result;
};
/**
* @param {object=} associatedObjectForCache an object to which the cache will be attached
* @returns {function(string, string): string} cached function
*/
/** @type {BindCacheForContext} */
cachedFn.bindCache = associatedObjectForCache => {
let innerCache;
if (associatedObjectForCache) {
@ -203,11 +234,7 @@ const makeCacheableWithContext = fn => {
return boundFn;
};
/**
* @param {string} context context used to create relative path
* @param {object=} associatedObjectForCache an object to which the cache will be attached
* @returns {function(string): string} cached function
*/
/** @type {BindContextCacheForContext} */
cachedFn.bindContextCache = (context, associatedObjectForCache) => {
let innerSubCache;
if (associatedObjectForCache) {
@ -311,7 +338,9 @@ const PATH_QUERY_REGEXP = /^((?:\0.|[^?\0])*)(\?.*)?$/;
* @returns {ParsedResource} parsed parts
*/
const _parseResource = str => {
const match = PATH_QUERY_FRAGMENT_REGEXP.exec(str);
const match =
/** @type {[string, string, string | undefined, string | undefined]} */
(/** @type {unknown} */ (PATH_QUERY_FRAGMENT_REGEXP.exec(str)));
return {
resource: str,
path: match[1].replace(/\0(.)/g, "$1"),
@ -327,7 +356,9 @@ module.exports.parseResource = makeCacheable(_parseResource);
* @returns {ParsedResourceWithoutFragment} parsed parts
*/
const _parseResourceWithoutFragment = str => {
const match = PATH_QUERY_REGEXP.exec(str);
const match =
/** @type {[string, string, string | undefined]} */
(/** @type {unknown} */ (PATH_QUERY_REGEXP.exec(str)));
return {
resource: str,
path: match[1].replace(/\0(.)/g, "$1"),

View File

@ -9,7 +9,7 @@ const { register } = require("./serialization");
const Position = /** @type {TODO} */ (require("acorn")).Position;
const SourceLocation = require("acorn").SourceLocation;
const ValidationError = require("schema-utils/dist/ValidationError").default;
const ValidationError = require("schema-utils").ValidationError;
const {
CachedSource,
ConcatSource,

View File

@ -16,7 +16,7 @@
* @template T
* @template R
* @typedef {object} GroupConfig
* @property {function(T): string[]} getKeys
* @property {function(T): string[] | undefined} getKeys
* @property {function(string, (R | T)[], T[]): R} createGroup
* @property {function(string, T[]): GroupOptions=} getOptions
*/

View File

@ -13,6 +13,7 @@ const WebAssemblyUtils = require("./WebAssemblyUtils");
/** @typedef {import("@webassemblyjs/ast").Signature} Signature */
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../ChunkGraph")} ChunkGraph */
/** @typedef {import("../ChunkGraph").ModuleId} ModuleId */
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../Module")} Module */
/** @typedef {import("../Module").ReadOnlyRuntimeRequirements} ReadOnlyRuntimeRequirements */
@ -89,7 +90,8 @@ const generateImportObject = (
const instanceVar = `m${waitForInstances.size}`;
waitForInstances.set(
instanceVar,
chunkGraph.getModuleId(/** @type {Module} */ (importedModule))
/** @type {ModuleId} */
(chunkGraph.getModuleId(/** @type {Module} */ (importedModule)))
);
properties.push({
module,

449
types.d.ts vendored
View File

@ -400,7 +400,9 @@ declare abstract class AsyncQueue<T, K, R> {
added: SyncHook<[T]>;
beforeStart: AsyncSeriesHook<[T]>;
started: SyncHook<[T]>;
result: SyncHook<[T, Error, R]>;
result: SyncHook<
[T, undefined | null | WebpackError, undefined | null | R]
>;
};
add(item: T, callback: CallbackAsyncQueue<R>): void;
invalidate(item: T): void;
@ -996,7 +998,7 @@ declare interface CallExpressionInfo {
getMemberRanges: () => [number, number][];
}
declare interface CallbackAsyncQueue<T> {
(err?: null | WebpackError, result?: T): any;
(err?: null | WebpackError, result?: null | T): any;
}
declare interface CallbackCacheCache<T> {
(err: null | WebpackError, result?: T): void;
@ -1217,7 +1219,7 @@ declare class ChunkGraph {
chunkGroup: ChunkGroup
): void;
disconnectChunkGroup(chunkGroup: ChunkGroup): void;
getModuleId(module: Module): ModuleId;
getModuleId(module: Module): null | string | number;
setModuleId(module: Module, id: ModuleId): void;
getRuntimeId(runtime: string): string | number;
setRuntimeId(runtime: string, id: string | number): void;
@ -1609,7 +1611,7 @@ declare interface CodeGenerationResult {
/**
* the runtime requirements
*/
runtimeRequirements: ReadonlySet<string>;
runtimeRequirements: null | ReadonlySet<string>;
/**
* a hash of the code generation result (will be automatically calculated from sources and runtimeRequirements if not provided)
@ -1711,10 +1713,10 @@ declare class Compilation {
* inspect, analyze, and/or modify the chunk graph.
*/
afterChunks: SyncHook<[Iterable<Chunk>]>;
optimizeDependencies: SyncBailHook<[Iterable<Module>], any>;
optimizeDependencies: SyncBailHook<[Iterable<Module>], boolean | void>;
afterOptimizeDependencies: SyncHook<[Iterable<Module>]>;
optimize: SyncHook<[]>;
optimizeModules: SyncBailHook<[Iterable<Module>], any>;
optimizeModules: SyncBailHook<[Iterable<Module>], boolean | void>;
afterOptimizeModules: SyncHook<[Iterable<Module>]>;
optimizeChunks: SyncBailHook<
[Iterable<Chunk>, ChunkGroup[]],
@ -1739,13 +1741,13 @@ declare class Compilation {
[Module, Set<string>, RuntimeRequirementsContext]
>;
runtimeRequirementInModule: HookMap<
SyncBailHook<[Module, Set<string>, RuntimeRequirementsContext], any>
SyncBailHook<[Module, Set<string>, RuntimeRequirementsContext], void>
>;
additionalTreeRuntimeRequirements: SyncHook<
[Chunk, Set<string>, RuntimeRequirementsContext]
>;
runtimeRequirementInTree: HookMap<
SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext], any>
SyncBailHook<[Chunk, Set<string>, RuntimeRequirementsContext], void>
>;
runtimeModule: SyncHook<[RuntimeModule, Chunk]>;
reviveModules: SyncHook<[Iterable<Module>, any]>;
@ -1830,7 +1832,9 @@ declare class Compilation {
>;
statsFactory: SyncHook<[StatsFactory, NormalizedStatsOptions]>;
statsPrinter: SyncHook<[StatsPrinter, NormalizedStatsOptions]>;
get normalModuleLoader(): SyncHook<[object, NormalModule]>;
get normalModuleLoader(): SyncHook<
[LoaderContextNormalModule<any>, NormalModule]
>;
}>;
name?: string;
startTime?: number;
@ -2941,8 +2945,8 @@ declare interface ContextTimestampAndHash {
resolved?: ResolvedContextTimestampAndHash;
symlinks?: Set<string>;
}
type CreateStatsOptionsContext = KnownCreateStatsOptionsContext &
Record<string, any>;
type CreateStatsOptionsContext = Record<string, any> &
KnownCreateStatsOptionsContext;
type CreateWriteStreamFSImplementation = FSImplementation & {
write: (...args: any[]) => any;
close?: (...args: any[]) => any;
@ -3122,8 +3126,8 @@ declare class DefinePlugin {
): RuntimeValue;
}
declare class DelegatedPlugin {
constructor(options?: any);
options: any;
constructor(options: Options);
options: Options;
/**
* Apply the plugin
@ -3620,6 +3624,9 @@ declare interface Effect {
type: string;
value: any;
}
declare interface EffectData {
[index: string]: any;
}
declare class ElectronTargetPlugin {
constructor(context?: "main" | "preload" | "renderer");
@ -3982,9 +3989,9 @@ declare interface Environment {
templateLiteral?: boolean;
}
declare class EnvironmentPlugin {
constructor(...keys: any[]);
keys: any[];
defaultValues: any;
constructor(...keys: (string | string[] | Record<string, string>)[]);
keys: string[];
defaultValues: Record<string, string>;
/**
* Apply the plugin
@ -4219,7 +4226,7 @@ declare abstract class ExportInfo {
findTarget(
moduleGraph: ModuleGraph,
validTargetModuleFilter: (arg0: Module) => boolean
): undefined | false | { module: Module; export?: string[] };
): undefined | null | false | { module: Module; export?: string[] };
getTarget(
moduleGraph: ModuleGraph,
resolveTargetFilter?: (arg0: {
@ -4244,8 +4251,8 @@ declare abstract class ExportInfo {
): undefined | { module: Module; export?: string[] };
createNestedExportsInfo(): undefined | ExportsInfo;
getNestedExportsInfo(): undefined | ExportsInfo;
hasInfo(baseInfo?: any, runtime?: any): boolean;
updateHash(hash?: any, runtime?: any): void;
hasInfo(baseInfo: ExportInfo, runtime: RuntimeSpec): boolean;
updateHash(hash: Hash, runtime: RuntimeSpec): void;
getUsedInfo(): string;
getProvidedInfo():
| "no provided info"
@ -4810,16 +4817,12 @@ declare interface FileSystem {
declare abstract class FileSystemInfo {
fs: InputFileSystem;
logger?: WebpackLogger;
fileTimestampQueue: AsyncQueue<string, string, null | FileSystemInfoEntry>;
fileHashQueue: AsyncQueue<string, string, null | string>;
contextTimestampQueue: AsyncQueue<
string,
string,
null | ContextFileSystemInfoEntry
>;
contextHashQueue: AsyncQueue<string, string, null | ContextHash>;
contextTshQueue: AsyncQueue<string, string, null | ContextTimestampAndHash>;
managedItemQueue: AsyncQueue<string, string, null | string>;
fileTimestampQueue: AsyncQueue<string, string, FileSystemInfoEntry>;
fileHashQueue: AsyncQueue<string, string, string>;
contextTimestampQueue: AsyncQueue<string, string, ContextFileSystemInfoEntry>;
contextHashQueue: AsyncQueue<string, string, ContextHash>;
contextTshQueue: AsyncQueue<string, string, ContextTimestampAndHash>;
managedItemQueue: AsyncQueue<string, string, string>;
managedItemDirectoryQueue: AsyncQueue<string, string, Set<string>>;
unmanagedPathsWithSlash: string[];
unmanagedPathsRegExps: RegExp[];
@ -4865,7 +4868,7 @@ declare abstract class FileSystemInfo {
path: string,
callback: (
arg0?: null | WebpackError,
arg1?: ResolvedContextTimestampAndHash
arg1?: null | ResolvedContextTimestampAndHash
) => void
): void;
resolveBuildDependencies(
@ -4886,7 +4889,7 @@ declare abstract class FileSystemInfo {
directories: null | Iterable<string>,
missing: null | Iterable<string>,
options: undefined | null | SnapshotOptionsFileSystemInfo,
callback: (arg0?: null | WebpackError, arg1?: null | Snapshot) => void
callback: (arg0: null | WebpackError, arg1: null | Snapshot) => void
): void;
mergeSnapshots(snapshot1: Snapshot, snapshot2: Snapshot): Snapshot;
checkSnapshotValid(
@ -5074,7 +5077,7 @@ declare class GetChunkFilenameRuntimeModule extends RuntimeModule {
static STAGE_TRIGGER: number;
}
declare interface GroupConfig {
getKeys: (arg0?: any) => string[];
getKeys: (arg0?: any) => undefined | string[];
createGroup: (arg0: string, arg1: any[], arg2: any[]) => object;
getOptions?: (arg0: string, arg1: any[]) => GroupOptions;
}
@ -6976,14 +6979,14 @@ declare interface KnownStatsChunk {
recorded: boolean;
reason?: string;
size: number;
sizes?: Record<string, number>;
names?: string[];
idHints?: string[];
sizes: Record<string, number>;
names: string[];
idHints: string[];
runtime?: string[];
files?: string[];
auxiliaryFiles?: string[];
files: string[];
auxiliaryFiles: string[];
hash: string;
childrenByOrder?: Record<string, (string | number)[]>;
childrenByOrder: Record<string, (string | number)[]>;
id?: string | number;
siblings?: (string | number)[];
parents?: (string | number)[];
@ -7006,11 +7009,11 @@ declare interface KnownStatsChunkGroup {
isOverSizeLimit?: boolean;
}
declare interface KnownStatsChunkOrigin {
module?: string;
moduleIdentifier?: string;
moduleName?: string;
loc?: string;
request?: string;
module: string;
moduleIdentifier: string;
moduleName: string;
loc: string;
request: string;
moduleId?: string | number;
}
declare interface KnownStatsCompilation {
@ -7055,14 +7058,14 @@ declare interface KnownStatsError {
}
declare interface KnownStatsFactoryContext {
type: string;
makePathsRelative?: (arg0: string) => string;
compilation?: Compilation;
rootModules?: Set<Module>;
compilationFileToChunks?: Map<string, Chunk[]>;
compilationAuxiliaryFileToChunks?: Map<string, Chunk[]>;
runtime?: RuntimeSpec;
cachedGetErrors?: (arg0: Compilation) => WebpackError[];
cachedGetWarnings?: (arg0: Compilation) => WebpackError[];
makePathsRelative: (arg0: string) => string;
compilation: Compilation;
rootModules: Set<Module>;
compilationFileToChunks: Map<string, Chunk[]>;
compilationAuxiliaryFileToChunks: Map<string, Chunk[]>;
runtime: RuntimeSpec;
cachedGetErrors: (arg0: Compilation) => WebpackError[];
cachedGetWarnings: (arg0: Compilation) => WebpackError[];
}
declare interface KnownStatsLogging {
entries: StatsLoggingEntry[];
@ -7071,7 +7074,7 @@ declare interface KnownStatsLogging {
}
declare interface KnownStatsLoggingEntry {
type: string;
message: string;
message?: string;
trace?: string[];
children?: StatsLoggingEntry[];
args?: any[];
@ -7080,10 +7083,10 @@ declare interface KnownStatsLoggingEntry {
declare interface KnownStatsModule {
type?: string;
moduleType?: string;
layer?: string;
layer?: null | string;
identifier?: string;
name?: string;
nameForCondition?: string;
nameForCondition?: null | string;
index?: number;
preOrderIndex?: number;
index2?: number;
@ -7098,45 +7101,45 @@ declare interface KnownStatsModule {
optional?: boolean;
orphan?: boolean;
id?: string | number;
issuerId?: string | number;
issuerId?: null | string | number;
chunks?: (string | number)[];
assets?: (string | number)[];
dependent?: boolean;
issuer?: string;
issuerName?: string;
issuer?: null | string;
issuerName?: null | string;
issuerPath?: StatsModuleIssuer[];
failed?: boolean;
errors?: number;
warnings?: number;
profile?: StatsProfile;
reasons?: StatsModuleReason[];
usedExports?: boolean | string[];
providedExports?: string[];
usedExports?: null | boolean | string[];
providedExports?: null | string[];
optimizationBailout?: string[];
depth?: number;
depth?: null | number;
modules?: StatsModule[];
filteredModules?: number;
source?: string | Buffer;
}
declare interface KnownStatsModuleIssuer {
identifier?: string;
name?: string;
identifier: string;
name: string;
id?: string | number;
profile?: StatsProfile;
profile: StatsProfile;
}
declare interface KnownStatsModuleReason {
moduleIdentifier?: string;
module?: string;
moduleName?: string;
resolvedModuleIdentifier?: string;
resolvedModule?: string;
type?: string;
moduleIdentifier: null | string;
module: null | string;
moduleName: null | string;
resolvedModuleIdentifier: null | string;
resolvedModule: null | string;
type: null | string;
active: boolean;
explanation?: string;
userRequest?: string;
loc?: string;
moduleId?: string | number;
resolvedModuleId?: string | number;
explanation: null | string;
userRequest: null | string;
loc?: null | string;
moduleId?: null | string | number;
resolvedModuleId?: null | string | number;
}
declare interface KnownStatsModuleTraceDependency {
loc?: string;
@ -7150,20 +7153,31 @@ declare interface KnownStatsModuleTraceItem {
originId?: string | number;
moduleId?: string | number;
}
declare interface KnownStatsPrinterContext {
type?: string;
compilation?: StatsCompilation;
chunkGroup?: StatsChunkGroup;
asset?: StatsAsset;
module?: StatsModule;
chunk?: StatsChunk;
moduleReason?: StatsModuleReason;
declare interface KnownStatsPrinterColorFn {
bold?: (str: string) => string;
yellow?: (str: string) => string;
red?: (str: string) => string;
green?: (str: string) => string;
magenta?: (str: string) => string;
cyan?: (str: string) => string;
}
declare interface KnownStatsPrinterContext {
type?: string;
compilation?: StatsCompilation;
chunkGroup?: StatsChunkGroup;
chunkGroupKind?: string;
asset?: StatsAsset;
module?: StatsModule;
chunk?: StatsChunk;
moduleReason?: StatsModuleReason;
moduleIssuer?: StatsModuleIssuer;
error?: StatsError;
profile?: StatsProfile;
logging?: StatsLogging;
moduleTraceItem?: StatsModuleTraceItem;
moduleTraceDependency?: StatsModuleTraceDependency;
}
declare interface KnownStatsPrinterFormaters {
formatFilename?: (file: string, oversize?: boolean) => string;
formatModuleId?: (id: string) => string;
formatChunkId?: (
@ -7171,10 +7185,11 @@ declare interface KnownStatsPrinterContext {
direction?: "parent" | "child" | "sibling"
) => string;
formatSize?: (size: number) => string;
formatLayer?: (size: string) => string;
formatDateTime?: (dateTime: number) => string;
formatFlag?: (flag: string) => string;
formatTime?: (time: number, boldQuantity?: boolean) => string;
chunkGroupKind?: string;
formatError?: (message: string) => string;
}
declare interface KnownStatsProfile {
total: number;
@ -7551,8 +7566,13 @@ declare class LoadScriptRuntimeModule extends HelperRuntimeModule {
declare interface Loader {
[index: string]: any;
}
type LoaderContext<OptionsType> = NormalModuleLoaderContext<OptionsType> &
LoaderRunnerLoaderContext<OptionsType> &
type LoaderContextDeclarationsIndex<OptionsType> =
NormalModuleLoaderContext<OptionsType> &
LoaderRunnerLoaderContext<OptionsType> &
LoaderPluginLoaderContext &
HotModuleReplacementPluginLoaderContext;
type LoaderContextNormalModule<T> = NormalModuleLoaderContext<T> &
LoaderRunnerLoaderContext<T> &
LoaderPluginLoaderContext &
HotModuleReplacementPluginLoaderContext;
type LoaderDefinition<
@ -7638,14 +7658,14 @@ declare interface LoaderPluginLoaderContext {
request: string,
callback: (
err: null | Error,
source: string,
sourceMap: any,
module: NormalModule
source?: string | Buffer,
sourceMap?: null | object,
module?: Module
) => void
): void;
importModule(
request: string,
options: ImportModuleOptions,
options: undefined | ImportModuleOptions,
callback: (err?: null | Error, exports?: any) => any
): void;
importModule(request: string, options?: ImportModuleOptions): Promise<any>;
@ -8034,7 +8054,7 @@ declare class Module extends DependenciesBlock {
buildInfo?: BuildInfo;
presentationalDependencies?: Dependency[];
codeGenerationDependencies?: Dependency[];
id: ModuleId;
id: null | string | number;
get hash(): string;
get renderedHash(): string;
profile?: ModuleProfile;
@ -8737,8 +8757,8 @@ declare abstract class MultiStats {
get hash(): string;
hasErrors(): boolean;
hasWarnings(): boolean;
toJson(options?: any): StatsCompilation;
toString(options?: any): string;
toJson(options?: string | boolean | StatsOptions): StatsCompilation;
toString(options?: string | boolean | StatsOptions): string;
}
declare abstract class MultiWatching {
watchings: Watching[];
@ -8921,14 +8941,18 @@ declare class NormalModule extends Module {
static deserialize(context?: any): NormalModule;
}
declare interface NormalModuleCompilationHooks {
loader: SyncHook<[object, NormalModule]>;
beforeLoaders: SyncHook<[LoaderItem[], NormalModule, object]>;
loader: SyncHook<[LoaderContextNormalModule<any>, NormalModule]>;
beforeLoaders: SyncHook<
[LoaderItem[], NormalModule, LoaderContextNormalModule<any>]
>;
beforeParse: SyncHook<[NormalModule]>;
beforeSnapshot: SyncHook<[NormalModule]>;
readResourceForScheme: HookMap<
AsyncSeriesBailHook<[string, NormalModule], string | Buffer>
AsyncSeriesBailHook<[string, NormalModule], null | string | Buffer>
>;
readResource: HookMap<
AsyncSeriesBailHook<[LoaderContextNormalModule<any>], string | Buffer>
>;
readResource: HookMap<AsyncSeriesBailHook<[object], string | Buffer>>;
needBuild: AsyncSeriesBailHook<[NormalModule, NeedBuildContext], boolean>;
}
declare interface NormalModuleCreateData {
@ -9224,6 +9248,9 @@ declare interface ObjectEncodingOptions {
| "base64url"
| "hex";
}
declare interface ObjectForExtract {
[index: string]: any;
}
declare interface ObjectSerializer {
serialize: (arg0: any, arg1: ObjectSerializerContext) => void;
deserialize: (arg0: ObjectDeserializerContext) => any;
@ -9676,6 +9703,42 @@ declare interface OptimizationSplitChunksOptions {
*/
usedExports?: boolean;
}
declare interface Options {
/**
* source
*/
source: string;
/**
* absolute context path to which lib ident is relative to
*/
context: string;
/**
* content
*/
content: DllReferencePluginOptionsContent;
/**
* type
*/
type?: "object" | "require";
/**
* extensions
*/
extensions?: string[];
/**
* scope
*/
scope?: string;
/**
* object for caching
*/
associatedObjectForCache?: object;
}
declare abstract class OptionsApply {
process(options?: any, compiler?: any): void;
}
@ -11489,7 +11552,7 @@ declare interface ResolveBuildDependenciesResult {
/**
* stored resolve results
*/
resolveResults: Map<string, string | false>;
resolveResults: Map<string, undefined | string | false>;
/**
* dependencies of the resolving
@ -12068,7 +12131,7 @@ declare interface RuleSet {
/**
* execute the rule set
*/
exec: (arg0: object) => Effect[];
exec: (arg0: EffectData) => Effect[];
}
type RuleSetCondition =
| string
@ -13159,32 +13222,36 @@ declare abstract class Snapshot {
children?: Set<Snapshot>;
hasStartTime(): boolean;
setStartTime(value: number): void;
setMergedStartTime(value?: any, snapshot?: any): void;
setMergedStartTime(value: undefined | number, snapshot: Snapshot): void;
hasFileTimestamps(): boolean;
setFileTimestamps(value?: any): void;
setFileTimestamps(value: Map<string, null | FileSystemInfoEntry>): void;
hasFileHashes(): boolean;
setFileHashes(value?: any): void;
setFileHashes(value: Map<string, null | string>): void;
hasFileTshs(): boolean;
setFileTshs(value?: any): void;
setFileTshs(value: Map<string, null | string | TimestampAndHash>): void;
hasContextTimestamps(): boolean;
setContextTimestamps(value?: any): void;
setContextTimestamps(
value: Map<string, null | ResolvedContextFileSystemInfoEntry>
): void;
hasContextHashes(): boolean;
setContextHashes(value?: any): void;
setContextHashes(value: Map<string, null | string>): void;
hasContextTshs(): boolean;
setContextTshs(value?: any): void;
setContextTshs(
value: Map<string, null | ResolvedContextTimestampAndHash>
): void;
hasMissingExistence(): boolean;
setMissingExistence(value?: any): void;
setMissingExistence(value: Map<string, boolean>): void;
hasManagedItemInfo(): boolean;
setManagedItemInfo(value?: any): void;
setManagedItemInfo(value: Map<string, string>): void;
hasManagedFiles(): boolean;
setManagedFiles(value?: any): void;
setManagedFiles(value: Set<string>): void;
hasManagedContexts(): boolean;
setManagedContexts(value?: any): void;
setManagedContexts(value: Set<string>): void;
hasManagedMissing(): boolean;
setManagedMissing(value?: any): void;
setManagedMissing(value: Set<string>): void;
hasChildren(): boolean;
setChildren(value?: any): void;
addChild(child?: any): void;
setChildren(value: Set<Snapshot>): void;
addChild(child: Snapshot): void;
serialize(__0: ObjectSerializerContext): void;
deserialize(__0: ObjectDeserializerContext): void;
getFileIterable(): Iterable<string>;
@ -13285,7 +13352,7 @@ declare abstract class SortableSet<T> extends Set<T> {
/**
* Sort with a comparer function
*/
sortWith(sortFn: SortFunction<T>): void;
sortWith(sortFn?: SortFunction<T>): void;
sort(): SortableSet<T>;
/**
@ -13657,59 +13724,73 @@ declare class Stats {
toJson(options?: string | boolean | StatsOptions): StatsCompilation;
toString(options?: string | boolean | StatsOptions): string;
}
type StatsAsset = KnownStatsAsset & Record<string, any>;
type StatsChunk = KnownStatsChunk & Record<string, any>;
type StatsChunkGroup = KnownStatsChunkGroup & Record<string, any>;
type StatsChunkOrigin = KnownStatsChunkOrigin & Record<string, any>;
type StatsCompilation = KnownStatsCompilation & Record<string, any>;
type StatsError = KnownStatsError & Record<string, any>;
type StatsAsset = Record<string, any> & KnownStatsAsset;
type StatsChunk = Record<string, any> & KnownStatsChunk;
type StatsChunkGroup = Record<string, any> & KnownStatsChunkGroup;
type StatsChunkOrigin = Record<string, any> & KnownStatsChunkOrigin;
type StatsCompilation = Record<string, any> & KnownStatsCompilation;
type StatsError = Record<string, any> & KnownStatsError;
declare abstract class StatsFactory {
hooks: Readonly<{
extract: HookMap<SyncBailHook<[object, any, StatsFactoryContext], any>>;
filter: HookMap<
SyncBailHook<[any, StatsFactoryContext, number, number], any>
>;
sort: HookMap<
SyncBailHook<
[((arg0?: any, arg1?: any) => number)[], StatsFactoryContext],
any
>
>;
filterSorted: HookMap<
SyncBailHook<[any, StatsFactoryContext, number, number], any>
>;
groupResults: HookMap<
SyncBailHook<[GroupConfig[], StatsFactoryContext], any>
>;
sortResults: HookMap<
SyncBailHook<
[((arg0?: any, arg1?: any) => number)[], StatsFactoryContext],
any
>
>;
filterResults: HookMap<
SyncBailHook<[any, StatsFactoryContext, number, number], any>
>;
merge: HookMap<SyncBailHook<[any[], StatsFactoryContext], any>>;
result: HookMap<SyncBailHook<[any[], StatsFactoryContext], any>>;
getItemName: HookMap<SyncBailHook<[any, StatsFactoryContext], any>>;
getItemFactory: HookMap<SyncBailHook<[any, StatsFactoryContext], any>>;
}>;
hooks: StatsFactoryHooks;
create(
type: string,
data: any,
baseContext: Omit<StatsFactoryContext, "type">
): any;
}
type StatsFactoryContext = KnownStatsFactoryContext & Record<string, any>;
type StatsLogging = KnownStatsLogging & Record<string, any>;
type StatsLoggingEntry = KnownStatsLoggingEntry & Record<string, any>;
type StatsModule = KnownStatsModule & Record<string, any>;
type StatsModuleIssuer = KnownStatsModuleIssuer & Record<string, any>;
type StatsModuleReason = KnownStatsModuleReason & Record<string, any>;
type StatsModuleTraceDependency = KnownStatsModuleTraceDependency &
Record<string, any>;
type StatsModuleTraceItem = KnownStatsModuleTraceItem & Record<string, any>;
type StatsFactoryContext = Record<string, any> & KnownStatsFactoryContext;
declare interface StatsFactoryHooks {
extract: HookMap<
SyncBailHook<[ObjectForExtract, any, StatsFactoryContext], undefined>
>;
filter: HookMap<
SyncBailHook<
[any, StatsFactoryContext, number, number],
undefined | boolean
>
>;
sort: HookMap<
SyncBailHook<
[((arg0?: any, arg1?: any) => 0 | 1 | -1)[], StatsFactoryContext],
undefined
>
>;
filterSorted: HookMap<
SyncBailHook<
[any, StatsFactoryContext, number, number],
undefined | boolean
>
>;
groupResults: HookMap<
SyncBailHook<[GroupConfig[], StatsFactoryContext], undefined>
>;
sortResults: HookMap<
SyncBailHook<
[((arg0?: any, arg1?: any) => 0 | 1 | -1)[], StatsFactoryContext],
undefined
>
>;
filterResults: HookMap<
SyncBailHook<
[any, StatsFactoryContext, number, number],
undefined | boolean
>
>;
merge: HookMap<SyncBailHook<[any[], StatsFactoryContext], any>>;
result: HookMap<SyncBailHook<[any, StatsFactoryContext], any>>;
getItemName: HookMap<SyncBailHook<[any, StatsFactoryContext], string>>;
getItemFactory: HookMap<
SyncBailHook<[any, StatsFactoryContext], undefined | StatsFactory>
>;
}
type StatsLogging = Record<string, any> & KnownStatsLogging;
type StatsLoggingEntry = Record<string, any> & KnownStatsLoggingEntry;
type StatsModule = Record<string, any> & KnownStatsModule;
type StatsModuleIssuer = Record<string, any> & KnownStatsModuleIssuer;
type StatsModuleReason = Record<string, any> & KnownStatsModuleReason;
type StatsModuleTraceDependency = Record<string, any> &
KnownStatsModuleTraceDependency;
type StatsModuleTraceItem = Record<string, any> & KnownStatsModuleTraceItem;
/**
* Stats options object.
@ -14158,22 +14239,28 @@ declare interface StatsOptions {
*/
warningsSpace?: number;
}
declare abstract class StatsPrinter {
hooks: Readonly<{
sortElements: HookMap<SyncBailHook<[string[], StatsPrinterContext], true>>;
printElements: HookMap<
SyncBailHook<[PrintedElement[], StatsPrinterContext], string>
>;
sortItems: HookMap<SyncBailHook<[any[], StatsPrinterContext], true>>;
getItemName: HookMap<SyncBailHook<[any, StatsPrinterContext], string>>;
printItems: HookMap<SyncBailHook<[string[], StatsPrinterContext], string>>;
print: HookMap<SyncBailHook<[{}, StatsPrinterContext], string>>;
result: HookMap<SyncWaterfallHook<[string, StatsPrinterContext]>>;
}>;
print(type: string, object: object, baseContext?: object): string;
declare interface StatsPrintHooks {
sortElements: HookMap<SyncBailHook<[string[], StatsPrinterContext], void>>;
printElements: HookMap<
SyncBailHook<[PrintedElement[], StatsPrinterContext], undefined | string>
>;
sortItems: HookMap<SyncBailHook<[any[], StatsPrinterContext], true>>;
getItemName: HookMap<SyncBailHook<[any, StatsPrinterContext], string>>;
printItems: HookMap<
SyncBailHook<[string[], StatsPrinterContext], undefined | string>
>;
print: HookMap<SyncBailHook<[any, StatsPrinterContext], string | void>>;
result: HookMap<SyncWaterfallHook<[string, StatsPrinterContext]>>;
}
type StatsPrinterContext = KnownStatsPrinterContext & Record<string, any>;
type StatsProfile = KnownStatsProfile & Record<string, any>;
declare abstract class StatsPrinter {
hooks: StatsPrintHooks;
print(type: string, object?: any, baseContext?: StatsPrinterContext): string;
}
type StatsPrinterContext = Record<string, any> &
KnownStatsPrinterColorFn &
KnownStatsPrinterFormaters &
KnownStatsPrinterContext;
type StatsProfile = Record<string, any> & KnownStatsProfile;
type StatsValue =
| boolean
| StatsOptions
@ -14202,7 +14289,7 @@ declare class SyncModuleIdsPlugin {
/**
* operation mode (defaults to merge)
*/
mode?: "read" | "merge" | "create" | "update";
mode?: "read" | "create" | "merge" | "update";
});
/**
@ -14310,6 +14397,7 @@ declare interface UpdateHashContextGenerator {
runtimeTemplate?: RuntimeTemplate;
}
type UsageStateType = 0 | 1 | 2 | 3 | 4;
type Value = string | number | boolean | RegExp;
declare abstract class VariableInfo {
declaredScope: ScopeInfo;
freeName?: string | true;
@ -14992,14 +15080,7 @@ declare namespace exports {
export let processArguments: (
args: Record<string, Argument>,
config: any,
values: Record<
string,
| string
| number
| boolean
| RegExp
| (string | number | boolean | RegExp)[]
>
values: Record<string, Value[]>
) => null | Problem[];
}
export namespace ModuleFilenameHelpers {
@ -15581,7 +15662,7 @@ declare namespace exports {
LoaderDefinitionFunction,
PitchLoaderDefinitionFunction,
RawLoaderDefinitionFunction,
LoaderContext
LoaderContextDeclarationsIndex as LoaderContext
};
}
declare const topLevelSymbolTag: unique symbol;