feat: refactoring project
This commit is contained in:
717
node_modules/webpack/lib/stats/DefaultStatsFactoryPlugin.js
generated
vendored
717
node_modules/webpack/lib/stats/DefaultStatsFactoryPlugin.js
generated
vendored
File diff suppressed because it is too large
Load Diff
91
node_modules/webpack/lib/stats/DefaultStatsPresetPlugin.js
generated
vendored
91
node_modules/webpack/lib/stats/DefaultStatsPresetPlugin.js
generated
vendored
@@ -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) => {
|
||||
|
||||
471
node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js
generated
vendored
471
node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js
generated
vendored
@@ -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,22 +90,29 @@ const mapLines = (str, fn) => str.split("\n").map(fn).join("\n");
|
||||
*/
|
||||
const twoDigit = n => (n >= 10 ? `${n}` : `0${n}`);
|
||||
|
||||
const isValidId = id => {
|
||||
return typeof id === "number" || id;
|
||||
};
|
||||
/**
|
||||
* @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) => {
|
||||
return list && list.length > 0 ? `+ ${count}` : `${count}`;
|
||||
};
|
||||
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!": (
|
||||
_,
|
||||
{
|
||||
@@ -125,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})` : "";
|
||||
@@ -161,7 +174,7 @@ const SIMPLE_PRINTERS = {
|
||||
} else if (errorsCount === 0 && warningsCount === 0) {
|
||||
statusMessage = `compiled ${green("successfully")}`;
|
||||
} else {
|
||||
statusMessage = `compiled`;
|
||||
statusMessage = "compiled";
|
||||
}
|
||||
if (
|
||||
builtAtMessage ||
|
||||
@@ -258,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(
|
||||
@@ -281,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(
|
||||
@@ -299,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 }) =>
|
||||
@@ -356,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,
|
||||
@@ -433,11 +453,11 @@ const SIMPLE_PRINTERS = {
|
||||
providedExportsCount === usedExports.length
|
||||
) {
|
||||
return cyan(formatFlag("all exports used"));
|
||||
} else {
|
||||
return cyan(
|
||||
formatFlag(`only some exports used: ${usedExports.join(", ")}`)
|
||||
);
|
||||
}
|
||||
|
||||
return cyan(
|
||||
formatFlag(`only some exports used: ${usedExports.join(", ")}`)
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -470,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)),
|
||||
@@ -496,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)}`,
|
||||
@@ -512,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),
|
||||
@@ -541,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
|
||||
@@ -560,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,
|
||||
@@ -611,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 }) =>
|
||||
@@ -622,21 +661,23 @@ const SIMPLE_PRINTERS = {
|
||||
"error.chunkInitial": (chunkInitial, { formatFlag }) =>
|
||||
chunkInitial ? formatFlag("initial") : undefined,
|
||||
"error.file": (file, { bold }) => bold(file),
|
||||
"error.moduleName": (moduleName, { bold }) => {
|
||||
return moduleName.includes("!")
|
||||
"error.moduleName": (moduleName, { bold }) =>
|
||||
moduleName.includes("!")
|
||||
? `${bold(moduleName.replace(/^(\s|\S)*!/, ""))} (${moduleName})`
|
||||
: `${bold(moduleName)}`;
|
||||
},
|
||||
: `${bold(moduleName)}`,
|
||||
"error.loc": (loc, { green }) => green(loc),
|
||||
"error.message": (message, { bold, formatError }) =>
|
||||
message.includes("\u001b[") ? message : bold(formatError(message)),
|
||||
message.includes("\u001B[") ? message : bold(formatError(message)),
|
||||
"error.details": (details, { formatError }) => formatError(details),
|
||||
"error.filteredDetails": filteredDetails =>
|
||||
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 }) =>
|
||||
@@ -666,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",
|
||||
@@ -908,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,
|
||||
@@ -952,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;
|
||||
@@ -1006,13 +1070,24 @@ 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");
|
||||
const rem = str.replace(/\n([^\n])/g, `\n${prefix}$1`);
|
||||
if (noPrefixInFirstLine) return rem;
|
||||
const ind = str[0] === "\n" ? "" : prefix;
|
||||
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;
|
||||
@@ -1027,22 +1102,34 @@ const joinExplicitNewLine = (items, indenter) => {
|
||||
first = false;
|
||||
const noJoiner = firstInLine || content.startsWith("\n");
|
||||
firstInLine = content.endsWith("\n");
|
||||
return noJoiner ? content : " " + content;
|
||||
return noJoiner ? content : ` ${content}`;
|
||||
})
|
||||
.filter(Boolean)
|
||||
.join("")
|
||||
.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 = [];
|
||||
@@ -1119,23 +1206,20 @@ const SIMPLE_ELEMENT_JOINERS = {
|
||||
},
|
||||
chunk: items => {
|
||||
let hasEntry = false;
|
||||
return (
|
||||
"chunk " +
|
||||
joinExplicitNewLine(
|
||||
items.filter(item => {
|
||||
switch (item.element) {
|
||||
case "entry":
|
||||
if (item.content) hasEntry = true;
|
||||
break;
|
||||
case "initial":
|
||||
if (hasEntry) return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
" "
|
||||
)
|
||||
);
|
||||
return `chunk ${joinExplicitNewLine(
|
||||
items.filter(item => {
|
||||
switch (item.element) {
|
||||
case "entry":
|
||||
if (item.content) hasEntry = true;
|
||||
break;
|
||||
case "initial":
|
||||
if (hasEntry) return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
" "
|
||||
)}`;
|
||||
},
|
||||
"chunk.childrenByOrder[]": items => `(${joinOneLine(items)})`,
|
||||
chunkGroup: items => joinExplicitNewLine(items, " "),
|
||||
@@ -1196,23 +1280,27 @@ const SIMPLE_ELEMENT_JOINERS = {
|
||||
},
|
||||
"module.profile": joinInBrackets,
|
||||
moduleIssuer: joinOneLine,
|
||||
chunkOrigin: items => "> " + joinOneLine(items),
|
||||
chunkOrigin: items => `> ${joinOneLine(items)}`,
|
||||
"errors[].error": joinError(true),
|
||||
"warnings[].error": joinError(false),
|
||||
loggingGroup: items => joinExplicitNewLine(items, "").trimEnd(),
|
||||
moduleTraceItem: items => " @ " + joinOneLine(items),
|
||||
moduleTraceItem: items => ` @ ${joinOneLine(items)}`,
|
||||
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",
|
||||
red: "\u001b[1m\u001b[31m",
|
||||
green: "\u001b[1m\u001b[32m",
|
||||
cyan: "\u001b[1m\u001b[36m",
|
||||
magenta: "\u001b[1m\u001b[35m"
|
||||
bold: "\u001B[1m",
|
||||
yellow: "\u001B[1m\u001B[33m",
|
||||
red: "\u001B[1m\u001B[31m",
|
||||
green: "\u001B[1m\u001B[32m",
|
||||
cyan: "\u001B[1m\u001B[36m",
|
||||
magenta: "\u001B[1m\u001B[35m"
|
||||
};
|
||||
|
||||
/** @type {Record<string, function(any, Required<KnownStatsPrinterColorFn> & StatsPrinterContext, ...any): string>} */
|
||||
const AVAILABLE_FORMATS = {
|
||||
formatChunkId: (id, { yellow }, direction) => {
|
||||
switch (direction) {
|
||||
@@ -1256,13 +1344,12 @@ const AVAILABLE_FORMATS = {
|
||||
else if (time < times[2]) return bold(`${time}${unit}`);
|
||||
else if (time < times[1]) return green(`${time}${unit}`);
|
||||
else if (time < times[0]) return yellow(`${time}${unit}`);
|
||||
else return red(`${time}${unit}`);
|
||||
} else {
|
||||
return `${boldQuantity ? bold(time) : time}${unit}`;
|
||||
return red(`${time}${unit}`);
|
||||
}
|
||||
return `${boldQuantity ? bold(time) : time}${unit}`;
|
||||
},
|
||||
formatError: (message, { green, yellow, red }) => {
|
||||
if (message.includes("\u001b[")) return message;
|
||||
if (message.includes("\u001B[")) return message;
|
||||
const highlights = [
|
||||
{ regExp: /(Did you mean .+)/g, format: green },
|
||||
{
|
||||
@@ -1290,23 +1377,36 @@ const AVAILABLE_FORMATS = {
|
||||
}
|
||||
];
|
||||
for (const { regExp, format } of highlights) {
|
||||
message = message.replace(regExp, (match, content) => {
|
||||
return 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 => {
|
||||
return indent(result, "| ");
|
||||
}
|
||||
"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) {
|
||||
@@ -1333,49 +1433,218 @@ 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"
|
||||
? str.replace(
|
||||
/((\u001b\[39m|\u001b\[22m|\u001b\[0m)+)/g,
|
||||
/((\u001B\[39m|\u001B\[22m|\u001B\[0m)+)/g,
|
||||
`$1${start}`
|
||||
)
|
||||
: str
|
||||
}\u001b[39m\u001b[22m`;
|
||||
}\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
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1409,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)) {
|
||||
|
||||
185
node_modules/webpack/lib/stats/StatsFactory.js
generated
vendored
185
node_modules/webpack/lib/stats/StatsFactory.js
generated
vendored
@@ -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], void>>} extract
|
||||
* @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext, number, number], boolean | void>>} filter
|
||||
* @property {HookMap<SyncBailHook<[Comparator[], StatsFactoryContext], void>>} sort
|
||||
* @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext, number, number], boolean | void>>} filterSorted
|
||||
* @property {HookMap<SyncBailHook<[GroupConfig[], StatsFactoryContext], void>>} groupResults
|
||||
* @property {HookMap<SyncBailHook<[Comparator[], StatsFactoryContext], void>>} sortResults
|
||||
* @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext, number, number], boolean | void>>} filterResults
|
||||
* @property {HookMap<SyncBailHook<[FactoryDataItem[], StatsFactoryContext], Result | void>>} merge
|
||||
* @property {HookMap<SyncBailHook<[Result, StatsFactoryContext], Result>>} result
|
||||
* @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext], string | void>>} getItemName
|
||||
* @property {HookMap<SyncBailHook<[FactoryDataItem, StatsFactoryContext], StatsFactory | void>>} 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 | void} fn fn
|
||||
* @returns {R | void} 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,30 +189,37 @@ 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) {
|
||||
return this._create(type, data, baseContext);
|
||||
} else {
|
||||
try {
|
||||
this._inCreate = true;
|
||||
return this._create(type, data, baseContext);
|
||||
} finally {
|
||||
for (const key of Object.keys(this._caches)) this._caches[key].clear();
|
||||
this._inCreate = false;
|
||||
}
|
||||
}
|
||||
try {
|
||||
this._inCreate = true;
|
||||
return this._create(type, data, baseContext);
|
||||
} finally {
|
||||
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(
|
||||
@@ -165,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)
|
||||
@@ -188,6 +256,7 @@ class StatsFactory {
|
||||
|
||||
// for each item
|
||||
let resultItems = items2.map((item, i) => {
|
||||
/** @type {StatsFactoryContext} */
|
||||
const itemContext = {
|
||||
...context,
|
||||
_index: i
|
||||
@@ -217,6 +286,7 @@ class StatsFactory {
|
||||
});
|
||||
|
||||
// sort result items
|
||||
/** @type {Comparator[]} */
|
||||
const comparators2 = [];
|
||||
this._forEachLevel(
|
||||
this.hooks.sortResults,
|
||||
@@ -232,6 +302,7 @@ class StatsFactory {
|
||||
}
|
||||
|
||||
// group result items
|
||||
/** @type {GroupConfig[]} */
|
||||
const groupConfigs = [];
|
||||
this._forEachLevel(
|
||||
this.hooks.groupResults,
|
||||
@@ -270,23 +341,23 @@ class StatsFactory {
|
||||
result,
|
||||
(h, r) => h.call(r, context)
|
||||
);
|
||||
} else {
|
||||
const object = {};
|
||||
|
||||
// run extract on value
|
||||
this._forEachLevel(this.hooks.extract, this._caches.extract, type, h =>
|
||||
h.call(object, data, context)
|
||||
);
|
||||
|
||||
// run result on extracted object
|
||||
return this._forEachLevelWaterfall(
|
||||
this.hooks.result,
|
||||
this._caches.result,
|
||||
type,
|
||||
object,
|
||||
(h, r) => h.call(r, context)
|
||||
);
|
||||
}
|
||||
/** @type {ObjectForExtract} */
|
||||
const object = {};
|
||||
|
||||
// run extract on value
|
||||
this._forEachLevel(this.hooks.extract, this._caches.extract, type, h =>
|
||||
h.call(object, data, context)
|
||||
);
|
||||
|
||||
// run result on extracted object
|
||||
return this._forEachLevelWaterfall(
|
||||
this.hooks.result,
|
||||
this._caches.result,
|
||||
type,
|
||||
object,
|
||||
(h, r) => h.call(r, context)
|
||||
);
|
||||
}
|
||||
}
|
||||
module.exports = StatsFactory;
|
||||
|
||||
119
node_modules/webpack/lib/stats/StatsPrinter.js
generated
vendored
119
node_modules/webpack/lib/stats/StatsPrinter.js
generated
vendored
@@ -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, EXPECTED_ANY> & KnownStatsPrinterColorFn & KnownStatsPrinterFormaters & KnownStatsPrinterContext} StatsPrinterContext */
|
||||
/** @typedef {any} PrintObject */
|
||||
|
||||
/**
|
||||
* @typedef {object} StatsPrintHooks
|
||||
* @property {HookMap<SyncBailHook<[string[], StatsPrinterContext], void>>} sortElements
|
||||
* @property {HookMap<SyncBailHook<[PrintedElement[], StatsPrinterContext], string | void>>} printElements
|
||||
* @property {HookMap<SyncBailHook<[PrintObject[], StatsPrinterContext], boolean | void>>} sortItems
|
||||
* @property {HookMap<SyncBailHook<[PrintObject, StatsPrinterContext], string | void>>} getItemName
|
||||
* @property {HookMap<SyncBailHook<[string[], StatsPrinterContext], string | void>>} 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 | void} fn fn
|
||||
* @returns {R | void} 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,48 +160,49 @@ 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) {
|
||||
if (this._inPrint) {
|
||||
return this._print(type, object, baseContext);
|
||||
} else {
|
||||
try {
|
||||
this._inPrint = true;
|
||||
return this._print(type, object, baseContext);
|
||||
} finally {
|
||||
this._levelHookCache.clear();
|
||||
this._inPrint = false;
|
||||
}
|
||||
}
|
||||
try {
|
||||
this._inPrint = true;
|
||||
return this._print(type, object, baseContext);
|
||||
} finally {
|
||||
this._levelHookCache.clear();
|
||||
this._inPrint = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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,
|
||||
@@ -189,6 +219,7 @@ class StatsPrinter {
|
||||
h.call(sortedItems, context)
|
||||
);
|
||||
const printedItems = sortedItems.map((item, i) => {
|
||||
/** @type {StatsPrinterContext} */
|
||||
const itemContext = {
|
||||
...context,
|
||||
_index: i
|
||||
@@ -241,7 +272,7 @@ class StatsPrinter {
|
||||
return this._forEachLevelWaterfall(
|
||||
this.hooks.result,
|
||||
type,
|
||||
printResult,
|
||||
/** @type {string} */ (printResult),
|
||||
(h, r) => h.call(r, context)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user