summaryrefslogtreecommitdiff
path: root/node_modules/webpack/lib/stats
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2023-11-05 17:16:09 +0800
committerlittleblack111 <littleblack11111@gmail.com>2023-11-05 17:16:09 +0800
commitd1d9f00b1bd660842addf5e6b1d1b64c852a9eea (patch)
tree60fb37ae73a1109d95301de5ec9b61b5726a4b61 /node_modules/webpack/lib/stats
parent7c85166c4cbdd862fc4252007d2df5befcbc2a58 (diff)
added hover prefixer
Diffstat (limited to 'node_modules/webpack/lib/stats')
-rw-r--r--node_modules/webpack/lib/stats/DefaultStatsFactoryPlugin.js2474
-rw-r--r--node_modules/webpack/lib/stats/DefaultStatsPresetPlugin.js335
-rw-r--r--node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js1423
-rw-r--r--node_modules/webpack/lib/stats/StatsFactory.js292
-rw-r--r--node_modules/webpack/lib/stats/StatsPrinter.js249
5 files changed, 4773 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/stats/DefaultStatsFactoryPlugin.js b/node_modules/webpack/lib/stats/DefaultStatsFactoryPlugin.js
new file mode 100644
index 00000000..a18aa475
--- /dev/null
+++ b/node_modules/webpack/lib/stats/DefaultStatsFactoryPlugin.js
@@ -0,0 +1,2474 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const util = require("util");
+const { WEBPACK_MODULE_TYPE_RUNTIME } = require("../ModuleTypeConstants");
+const ModuleDependency = require("../dependencies/ModuleDependency");
+const formatLocation = require("../formatLocation");
+const { LogType } = require("../logging/Logger");
+const AggressiveSplittingPlugin = require("../optimize/AggressiveSplittingPlugin");
+const SizeLimitsPlugin = require("../performance/SizeLimitsPlugin");
+const { countIterable } = require("../util/IterableHelpers");
+const {
+ compareLocations,
+ compareChunksById,
+ compareNumbers,
+ compareIds,
+ concatComparators,
+ compareSelect,
+ compareModulesByIdentifier
+} = require("../util/comparators");
+const { makePathsRelative, parseResource } = require("../util/identifier");
+
+/** @typedef {import("webpack-sources").Source} Source */
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../ChunkGroup")} ChunkGroup */
+/** @typedef {import("../ChunkGroup").OriginRecord} OriginRecord */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compilation").Asset} Asset */
+/** @typedef {import("../Compilation").AssetInfo} AssetInfo */
+/** @typedef {import("../Compilation").NormalizedStatsOptions} NormalizedStatsOptions */
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("../Dependency")} Dependency */
+/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../ModuleGraphConnection")} ModuleGraphConnection */
+/** @typedef {import("../ModuleProfile")} ModuleProfile */
+/** @typedef {import("../RequestShortener")} RequestShortener */
+/** @typedef {import("../WebpackError")} WebpackError */
+/** @template T @typedef {import("../util/comparators").Comparator<T>} Comparator<T> */
+/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
+/** @typedef {import("../util/smartGrouping").GroupConfig<any, object>} GroupConfig */
+/** @typedef {import("./StatsFactory")} StatsFactory */
+/** @typedef {import("./StatsFactory").StatsFactoryContext} StatsFactoryContext */
+
+/** @typedef {KnownStatsCompilation & Record<string, any>} StatsCompilation */
+/**
+ * @typedef {Object} KnownStatsCompilation
+ * @property {any=} env
+ * @property {string=} name
+ * @property {string=} hash
+ * @property {string=} version
+ * @property {number=} time
+ * @property {number=} builtAt
+ * @property {boolean=} needAdditionalPass
+ * @property {string=} publicPath
+ * @property {string=} outputPath
+ * @property {Record<string, string[]>=} assetsByChunkName
+ * @property {StatsAsset[]=} assets
+ * @property {number=} filteredAssets
+ * @property {StatsChunk[]=} chunks
+ * @property {StatsModule[]=} modules
+ * @property {number=} filteredModules
+ * @property {Record<string, StatsChunkGroup>=} entrypoints
+ * @property {Record<string, StatsChunkGroup>=} namedChunkGroups
+ * @property {StatsError[]=} errors
+ * @property {number=} errorsCount
+ * @property {StatsError[]=} warnings
+ * @property {number=} warningsCount
+ * @property {StatsCompilation[]=} children
+ * @property {Record<string, StatsLogging>=} logging
+ */
+
+/** @typedef {KnownStatsLogging & Record<string, any>} StatsLogging */
+/**
+ * @typedef {Object} KnownStatsLogging
+ * @property {StatsLoggingEntry[]} entries
+ * @property {number} filteredEntries
+ * @property {boolean} debug
+ */
+
+/** @typedef {KnownStatsLoggingEntry & Record<string, any>} StatsLoggingEntry */
+/**
+ * @typedef {Object} KnownStatsLoggingEntry
+ * @property {string} type
+ * @property {string} message
+ * @property {string[]=} trace
+ * @property {StatsLoggingEntry[]=} children
+ * @property {any[]=} args
+ * @property {number=} time
+ */
+
+/** @typedef {KnownStatsAsset & Record<string, any>} StatsAsset */
+/**
+ * @typedef {Object} KnownStatsAsset
+ * @property {string} type
+ * @property {string} name
+ * @property {AssetInfo} info
+ * @property {number} size
+ * @property {boolean} emitted
+ * @property {boolean} comparedForEmit
+ * @property {boolean} cached
+ * @property {StatsAsset[]=} related
+ * @property {(string|number)[]=} chunkNames
+ * @property {(string|number)[]=} chunkIdHints
+ * @property {(string|number)[]=} chunks
+ * @property {(string|number)[]=} auxiliaryChunkNames
+ * @property {(string|number)[]=} auxiliaryChunks
+ * @property {(string|number)[]=} auxiliaryChunkIdHints
+ * @property {number=} filteredRelated
+ * @property {boolean=} isOverSizeLimit
+ */
+
+/** @typedef {KnownStatsChunkGroup & Record<string, any>} StatsChunkGroup */
+/**
+ * @typedef {Object} KnownStatsChunkGroup
+ * @property {string=} name
+ * @property {(string|number)[]=} chunks
+ * @property {({ name: string, size?: number })[]=} assets
+ * @property {number=} filteredAssets
+ * @property {number=} assetsSize
+ * @property {({ name: string, size?: number })[]=} auxiliaryAssets
+ * @property {number=} filteredAuxiliaryAssets
+ * @property {number=} auxiliaryAssetsSize
+ * @property {{ [x: string]: StatsChunkGroup[] }=} children
+ * @property {{ [x: string]: string[] }=} childAssets
+ * @property {boolean=} isOverSizeLimit
+ */
+
+/** @typedef {KnownStatsModule & Record<string, any>} StatsModule */
+/**
+ * @typedef {Object} KnownStatsModule
+ * @property {string=} type
+ * @property {string=} moduleType
+ * @property {string=} layer
+ * @property {string=} identifier
+ * @property {string=} name
+ * @property {string=} nameForCondition
+ * @property {number=} index
+ * @property {number=} preOrderIndex
+ * @property {number=} index2
+ * @property {number=} postOrderIndex
+ * @property {number=} size
+ * @property {{[x: string]: number}=} sizes
+ * @property {boolean=} cacheable
+ * @property {boolean=} built
+ * @property {boolean=} codeGenerated
+ * @property {boolean=} buildTimeExecuted
+ * @property {boolean=} cached
+ * @property {boolean=} optional
+ * @property {boolean=} orphan
+ * @property {string|number=} id
+ * @property {string|number=} issuerId
+ * @property {(string|number)[]=} chunks
+ * @property {(string|number)[]=} assets
+ * @property {boolean=} dependent
+ * @property {string=} issuer
+ * @property {string=} issuerName
+ * @property {StatsModuleIssuer[]=} issuerPath
+ * @property {boolean=} failed
+ * @property {number=} errors
+ * @property {number=} warnings
+ * @property {StatsProfile=} profile
+ * @property {StatsModuleReason[]=} reasons
+ * @property {(boolean | string[])=} usedExports
+ * @property {string[]=} providedExports
+ * @property {string[]=} optimizationBailout
+ * @property {number=} depth
+ * @property {StatsModule[]=} modules
+ * @property {number=} filteredModules
+ * @property {ReturnType<Source["source"]>=} source
+ */
+
+/** @typedef {KnownStatsProfile & Record<string, any>} StatsProfile */
+/**
+ * @typedef {Object} KnownStatsProfile
+ * @property {number} total
+ * @property {number} resolving
+ * @property {number} restoring
+ * @property {number} building
+ * @property {number} integration
+ * @property {number} storing
+ * @property {number} additionalResolving
+ * @property {number} additionalIntegration
+ * @property {number} factory
+ * @property {number} dependencies
+ */
+
+/** @typedef {KnownStatsModuleIssuer & Record<string, any>} StatsModuleIssuer */
+/**
+ * @typedef {Object} KnownStatsModuleIssuer
+ * @property {string=} identifier
+ * @property {string=} name
+ * @property {(string|number)=} id
+ * @property {StatsProfile=} profile
+ */
+
+/** @typedef {KnownStatsModuleReason & Record<string, any>} StatsModuleReason */
+/**
+ * @typedef {Object} KnownStatsModuleReason
+ * @property {string=} moduleIdentifier
+ * @property {string=} module
+ * @property {string=} moduleName
+ * @property {string=} resolvedModuleIdentifier
+ * @property {string=} resolvedModule
+ * @property {string=} type
+ * @property {boolean} active
+ * @property {string=} explanation
+ * @property {string=} userRequest
+ * @property {string=} loc
+ * @property {(string|number)=} moduleId
+ * @property {(string|number)=} resolvedModuleId
+ */
+
+/** @typedef {KnownStatsChunk & Record<string, any>} StatsChunk */
+/**
+ * @typedef {Object} KnownStatsChunk
+ * @property {boolean} rendered
+ * @property {boolean} initial
+ * @property {boolean} entry
+ * @property {boolean} recorded
+ * @property {string=} reason
+ * @property {number} size
+ * @property {Record<string, number>=} sizes
+ * @property {string[]=} names
+ * @property {string[]=} idHints
+ * @property {string[]=} runtime
+ * @property {string[]=} files
+ * @property {string[]=} auxiliaryFiles
+ * @property {string} hash
+ * @property {Record<string, (string|number)[]>=} childrenByOrder
+ * @property {(string|number)=} id
+ * @property {(string|number)[]=} siblings
+ * @property {(string|number)[]=} parents
+ * @property {(string|number)[]=} children
+ * @property {StatsModule[]=} modules
+ * @property {number=} filteredModules
+ * @property {StatsChunkOrigin[]=} origins
+ */
+
+/** @typedef {KnownStatsChunkOrigin & Record<string, any>} StatsChunkOrigin */
+/**
+ * @typedef {Object} KnownStatsChunkOrigin
+ * @property {string=} module
+ * @property {string=} moduleIdentifier
+ * @property {string=} moduleName
+ * @property {string=} loc
+ * @property {string=} request
+ * @property {(string|number)=} moduleId
+ */
+
+/** @typedef {KnownStatsModuleTraceItem & Record<string, any>} StatsModuleTraceItem */
+/**
+ * @typedef {Object} KnownStatsModuleTraceItem
+ * @property {string=} originIdentifier
+ * @property {string=} originName
+ * @property {string=} moduleIdentifier
+ * @property {string=} moduleName
+ * @property {StatsModuleTraceDependency[]=} dependencies
+ * @property {(string|number)=} originId
+ * @property {(string|number)=} moduleId
+ */
+
+/** @typedef {KnownStatsModuleTraceDependency & Record<string, any>} StatsModuleTraceDependency */
+/**
+ * @typedef {Object} KnownStatsModuleTraceDependency
+ * @property {string=} loc
+ */
+
+/** @typedef {KnownStatsError & Record<string, any>} StatsError */
+/**
+ * @typedef {Object} KnownStatsError
+ * @property {string} message
+ * @property {string=} chunkName
+ * @property {boolean=} chunkEntry
+ * @property {boolean=} chunkInitial
+ * @property {string=} file
+ * @property {string=} moduleIdentifier
+ * @property {string=} moduleName
+ * @property {string=} loc
+ * @property {string|number=} chunkId
+ * @property {string|number=} moduleId
+ * @property {StatsModuleTraceItem[]=} moduleTrace
+ * @property {any=} details
+ * @property {string=} stack
+ */
+
+/** @typedef {Asset & { type: string, related: PreprocessedAsset[] }} PreprocessedAsset */
+
+/**
+ * @template T
+ * @template O
+ * @typedef {Record<string, (object: O, data: T, context: StatsFactoryContext, options: NormalizedStatsOptions, factory: StatsFactory) => void>} ExtractorsByOption
+ */
+
+/**
+ * @typedef {Object} SimpleExtractors
+ * @property {ExtractorsByOption<Compilation, StatsCompilation>} compilation
+ * @property {ExtractorsByOption<PreprocessedAsset, StatsAsset>} asset
+ * @property {ExtractorsByOption<PreprocessedAsset, StatsAsset>} asset$visible
+ * @property {ExtractorsByOption<{ name: string, chunkGroup: ChunkGroup }, StatsChunkGroup>} chunkGroup
+ * @property {ExtractorsByOption<Module, StatsModule>} module
+ * @property {ExtractorsByOption<Module, StatsModule>} module$visible
+ * @property {ExtractorsByOption<Module, StatsModuleIssuer>} moduleIssuer
+ * @property {ExtractorsByOption<ModuleProfile, StatsProfile>} profile
+ * @property {ExtractorsByOption<ModuleGraphConnection, StatsModuleReason>} moduleReason
+ * @property {ExtractorsByOption<Chunk, StatsChunk>} chunk
+ * @property {ExtractorsByOption<OriginRecord, StatsChunkOrigin>} chunkOrigin
+ * @property {ExtractorsByOption<WebpackError, StatsError>} error
+ * @property {ExtractorsByOption<WebpackError, StatsError>} warning
+ * @property {ExtractorsByOption<{ origin: Module, module: Module }, StatsModuleTraceItem>} moduleTraceItem
+ * @property {ExtractorsByOption<Dependency, StatsModuleTraceDependency>} moduleTraceDependency
+ */
+
+/**
+ * @template T
+ * @template I
+ * @param {Iterable<T>} items items to select from
+ * @param {function(T): Iterable<I>} selector selector function to select values from item
+ * @returns {I[]} array of values
+ */
+const uniqueArray = (items, selector) => {
+ /** @type {Set<I>} */
+ const set = new Set();
+ for (const item of items) {
+ for (const i of selector(item)) {
+ set.add(i);
+ }
+ }
+ return Array.from(set);
+};
+
+/**
+ * @template T
+ * @template I
+ * @param {Iterable<T>} items items to select from
+ * @param {function(T): Iterable<I>} selector selector function to select values from item
+ * @param {Comparator<I>} comparator comparator function
+ * @returns {I[]} array of values
+ */
+const uniqueOrderedArray = (items, selector, comparator) => {
+ return uniqueArray(items, selector).sort(comparator);
+};
+
+/** @template T @template R @typedef {{ [P in keyof T]: R }} MappedValues<T, R> */
+
+/**
+ * @template T
+ * @template R
+ * @param {T} obj object to be mapped
+ * @param {function(T[keyof T], keyof T): R} fn mapping function
+ * @returns {MappedValues<T, R>} mapped object
+ */
+const mapObject = (obj, fn) => {
+ const newObj = Object.create(null);
+ for (const key of Object.keys(obj)) {
+ newObj[key] = fn(obj[key], /** @type {keyof T} */ (key));
+ }
+ return newObj;
+};
+
+/**
+ * @param {Compilation} compilation the compilation
+ * @param {function(Compilation, string): any[]} getItems get items
+ * @returns {number} total number
+ */
+const countWithChildren = (compilation, getItems) => {
+ let count = getItems(compilation, "").length;
+ for (const child of compilation.children) {
+ count += countWithChildren(child, (c, type) =>
+ getItems(c, `.children[].compilation${type}`)
+ );
+ }
+ return count;
+};
+
+/** @type {ExtractorsByOption<WebpackError | string, StatsError>} */
+const EXTRACT_ERROR = {
+ _: (object, error, context, { requestShortener }) => {
+ // TODO webpack 6 disallow strings in the errors/warnings list
+ if (typeof error === "string") {
+ object.message = error;
+ } else {
+ if (error.chunk) {
+ object.chunkName = error.chunk.name;
+ object.chunkEntry = error.chunk.hasRuntime();
+ object.chunkInitial = error.chunk.canBeInitial();
+ }
+ if (error.file) {
+ object.file = error.file;
+ }
+ if (error.module) {
+ object.moduleIdentifier = error.module.identifier();
+ object.moduleName = error.module.readableIdentifier(requestShortener);
+ }
+ if (error.loc) {
+ object.loc = formatLocation(error.loc);
+ }
+ object.message = error.message;
+ }
+ },
+ ids: (object, error, { compilation: { chunkGraph } }) => {
+ if (typeof error !== "string") {
+ if (error.chunk) {
+ object.chunkId = error.chunk.id;
+ }
+ if (error.module) {
+ object.moduleId = chunkGraph.getModuleId(error.module);
+ }
+ }
+ },
+ moduleTrace: (object, error, context, options, factory) => {
+ if (typeof error !== "string" && error.module) {
+ const {
+ type,
+ compilation: { moduleGraph }
+ } = context;
+ /** @type {Set<Module>} */
+ const visitedModules = new Set();
+ const moduleTrace = [];
+ let current = error.module;
+ while (current) {
+ if (visitedModules.has(current)) break; // circular (technically impossible, but how knows)
+ visitedModules.add(current);
+ const origin = moduleGraph.getIssuer(current);
+ if (!origin) break;
+ moduleTrace.push({ origin, module: current });
+ current = origin;
+ }
+ object.moduleTrace = factory.create(
+ `${type}.moduleTrace`,
+ moduleTrace,
+ context
+ );
+ }
+ },
+ errorDetails: (
+ object,
+ error,
+ { type, compilation, cachedGetErrors, cachedGetWarnings },
+ { errorDetails }
+ ) => {
+ if (
+ typeof error !== "string" &&
+ (errorDetails === true ||
+ (type.endsWith(".error") && cachedGetErrors(compilation).length < 3))
+ ) {
+ object.details = error.details;
+ }
+ },
+ errorStack: (object, error) => {
+ if (typeof error !== "string") {
+ object.stack = error.stack;
+ }
+ }
+};
+
+/** @type {SimpleExtractors} */
+const SIMPLE_EXTRACTORS = {
+ compilation: {
+ _: (object, compilation, context, options) => {
+ if (!context.makePathsRelative) {
+ context.makePathsRelative = makePathsRelative.bindContextCache(
+ compilation.compiler.context,
+ compilation.compiler.root
+ );
+ }
+ if (!context.cachedGetErrors) {
+ const map = new WeakMap();
+ context.cachedGetErrors = compilation => {
+ return (
+ map.get(compilation) ||
+ (errors => (map.set(compilation, errors), errors))(
+ compilation.getErrors()
+ )
+ );
+ };
+ }
+ if (!context.cachedGetWarnings) {
+ const map = new WeakMap();
+ context.cachedGetWarnings = compilation => {
+ return (
+ map.get(compilation) ||
+ (warnings => (map.set(compilation, warnings), warnings))(
+ compilation.getWarnings()
+ )
+ );
+ };
+ }
+ if (compilation.name) {
+ object.name = compilation.name;
+ }
+ if (compilation.needAdditionalPass) {
+ object.needAdditionalPass = true;
+ }
+
+ const { logging, loggingDebug, loggingTrace } = options;
+ if (logging || (loggingDebug && loggingDebug.length > 0)) {
+ const util = require("util");
+ object.logging = {};
+ let acceptedTypes;
+ let collapsedGroups = false;
+ switch (logging) {
+ default:
+ acceptedTypes = new Set();
+ break;
+ case "error":
+ acceptedTypes = new Set([LogType.error]);
+ break;
+ case "warn":
+ acceptedTypes = new Set([LogType.error, LogType.warn]);
+ break;
+ case "info":
+ acceptedTypes = new Set([
+ LogType.error,
+ LogType.warn,
+ LogType.info
+ ]);
+ break;
+ case "log":
+ acceptedTypes = new Set([
+ LogType.error,
+ LogType.warn,
+ LogType.info,
+ LogType.log,
+ LogType.group,
+ LogType.groupEnd,
+ LogType.groupCollapsed,
+ LogType.clear
+ ]);
+ break;
+ case "verbose":
+ acceptedTypes = new Set([
+ LogType.error,
+ LogType.warn,
+ LogType.info,
+ LogType.log,
+ LogType.group,
+ LogType.groupEnd,
+ LogType.groupCollapsed,
+ LogType.profile,
+ LogType.profileEnd,
+ LogType.time,
+ LogType.status,
+ LogType.clear
+ ]);
+ collapsedGroups = true;
+ break;
+ }
+ const cachedMakePathsRelative = makePathsRelative.bindContextCache(
+ options.context,
+ compilation.compiler.root
+ );
+ let depthInCollapsedGroup = 0;
+ for (const [origin, logEntries] of compilation.logging) {
+ const debugMode = loggingDebug.some(fn => fn(origin));
+ if (logging === false && !debugMode) continue;
+ /** @type {KnownStatsLoggingEntry[]} */
+ const groupStack = [];
+ /** @type {KnownStatsLoggingEntry[]} */
+ const rootList = [];
+ let currentList = rootList;
+ let processedLogEntries = 0;
+ for (const entry of logEntries) {
+ let type = entry.type;
+ if (!debugMode && !acceptedTypes.has(type)) continue;
+
+ // Expand groups in verbose and debug modes
+ if (
+ type === LogType.groupCollapsed &&
+ (debugMode || collapsedGroups)
+ )
+ type = LogType.group;
+
+ if (depthInCollapsedGroup === 0) {
+ processedLogEntries++;
+ }
+
+ if (type === LogType.groupEnd) {
+ groupStack.pop();
+ if (groupStack.length > 0) {
+ currentList = groupStack[groupStack.length - 1].children;
+ } else {
+ currentList = rootList;
+ }
+ if (depthInCollapsedGroup > 0) depthInCollapsedGroup--;
+ continue;
+ }
+ let message = undefined;
+ if (entry.type === LogType.time) {
+ message = `${entry.args[0]}: ${
+ entry.args[1] * 1000 + entry.args[2] / 1000000
+ } ms`;
+ } else if (entry.args && entry.args.length > 0) {
+ message = util.format(entry.args[0], ...entry.args.slice(1));
+ }
+ /** @type {KnownStatsLoggingEntry} */
+ const newEntry = {
+ ...entry,
+ type,
+ message,
+ trace: loggingTrace ? entry.trace : undefined,
+ children:
+ type === LogType.group || type === LogType.groupCollapsed
+ ? []
+ : undefined
+ };
+ currentList.push(newEntry);
+ if (newEntry.children) {
+ groupStack.push(newEntry);
+ currentList = newEntry.children;
+ if (depthInCollapsedGroup > 0) {
+ depthInCollapsedGroup++;
+ } else if (type === LogType.groupCollapsed) {
+ depthInCollapsedGroup = 1;
+ }
+ }
+ }
+ let name = cachedMakePathsRelative(origin).replace(/\|/g, " ");
+ if (name in object.logging) {
+ let i = 1;
+ while (`${name}#${i}` in object.logging) {
+ i++;
+ }
+ name = `${name}#${i}`;
+ }
+ object.logging[name] = {
+ entries: rootList,
+ filteredEntries: logEntries.length - processedLogEntries,
+ debug: debugMode
+ };
+ }
+ }
+ },
+ hash: (object, compilation) => {
+ object.hash = compilation.hash;
+ },
+ version: object => {
+ object.version = require("../../package.json").version;
+ },
+ env: (object, compilation, context, { _env }) => {
+ object.env = _env;
+ },
+ timings: (object, compilation) => {
+ object.time = compilation.endTime - compilation.startTime;
+ },
+ builtAt: (object, compilation) => {
+ object.builtAt = compilation.endTime;
+ },
+ publicPath: (object, compilation) => {
+ object.publicPath = compilation.getPath(
+ compilation.outputOptions.publicPath
+ );
+ },
+ outputPath: (object, compilation) => {
+ object.outputPath = compilation.outputOptions.path;
+ },
+ assets: (object, compilation, context, options, factory) => {
+ const { type } = context;
+ /** @type {Map<string, Chunk[]>} */
+ const compilationFileToChunks = new Map();
+ /** @type {Map<string, Chunk[]>} */
+ const compilationAuxiliaryFileToChunks = new Map();
+ for (const chunk of compilation.chunks) {
+ for (const file of chunk.files) {
+ let array = compilationFileToChunks.get(file);
+ if (array === undefined) {
+ array = [];
+ compilationFileToChunks.set(file, array);
+ }
+ array.push(chunk);
+ }
+ for (const file of chunk.auxiliaryFiles) {
+ let array = compilationAuxiliaryFileToChunks.get(file);
+ if (array === undefined) {
+ array = [];
+ compilationAuxiliaryFileToChunks.set(file, array);
+ }
+ array.push(chunk);
+ }
+ }
+ /** @type {Map<string, PreprocessedAsset>} */
+ const assetMap = new Map();
+ /** @type {Set<PreprocessedAsset>} */
+ const assets = new Set();
+ for (const asset of compilation.getAssets()) {
+ /** @type {PreprocessedAsset} */
+ const item = {
+ ...asset,
+ type: "asset",
+ related: undefined
+ };
+ assets.add(item);
+ assetMap.set(asset.name, item);
+ }
+ for (const item of assetMap.values()) {
+ const related = item.info.related;
+ if (!related) continue;
+ for (const type of Object.keys(related)) {
+ const relatedEntry = related[type];
+ const deps = Array.isArray(relatedEntry)
+ ? relatedEntry
+ : [relatedEntry];
+ for (const dep of deps) {
+ const depItem = assetMap.get(dep);
+ if (!depItem) continue;
+ assets.delete(depItem);
+ depItem.type = type;
+ item.related = item.related || [];
+ item.related.push(depItem);
+ }
+ }
+ }
+
+ object.assetsByChunkName = {};
+ for (const [file, chunks] of compilationFileToChunks) {
+ for (const chunk of chunks) {
+ const name = chunk.name;
+ if (!name) continue;
+ if (
+ !Object.prototype.hasOwnProperty.call(
+ object.assetsByChunkName,
+ name
+ )
+ ) {
+ object.assetsByChunkName[name] = [];
+ }
+ object.assetsByChunkName[name].push(file);
+ }
+ }
+
+ const groupedAssets = factory.create(
+ `${type}.assets`,
+ Array.from(assets),
+ {
+ ...context,
+ compilationFileToChunks,
+ compilationAuxiliaryFileToChunks
+ }
+ );
+ const limited = spaceLimited(groupedAssets, options.assetsSpace);
+ object.assets = limited.children;
+ object.filteredAssets = limited.filteredChildren;
+ },
+ chunks: (object, compilation, context, options, factory) => {
+ const { type } = context;
+ object.chunks = factory.create(
+ `${type}.chunks`,
+ Array.from(compilation.chunks),
+ context
+ );
+ },
+ modules: (object, compilation, context, options, factory) => {
+ const { type } = context;
+ const array = Array.from(compilation.modules);
+ const groupedModules = factory.create(`${type}.modules`, array, context);
+ const limited = spaceLimited(groupedModules, options.modulesSpace);
+ object.modules = limited.children;
+ object.filteredModules = limited.filteredChildren;
+ },
+ entrypoints: (
+ object,
+ compilation,
+ context,
+ { entrypoints, chunkGroups, chunkGroupAuxiliary, chunkGroupChildren },
+ factory
+ ) => {
+ const { type } = context;
+ const array = Array.from(compilation.entrypoints, ([key, value]) => ({
+ name: key,
+ chunkGroup: value
+ }));
+ if (entrypoints === "auto" && !chunkGroups) {
+ if (array.length > 5) return;
+ if (
+ !chunkGroupChildren &&
+ array.every(({ chunkGroup }) => {
+ if (chunkGroup.chunks.length !== 1) return false;
+ const chunk = chunkGroup.chunks[0];
+ return (
+ chunk.files.size === 1 &&
+ (!chunkGroupAuxiliary || chunk.auxiliaryFiles.size === 0)
+ );
+ })
+ ) {
+ return;
+ }
+ }
+ object.entrypoints = factory.create(
+ `${type}.entrypoints`,
+ array,
+ context
+ );
+ },
+ chunkGroups: (object, compilation, context, options, factory) => {
+ const { type } = context;
+ const array = Array.from(
+ compilation.namedChunkGroups,
+ ([key, value]) => ({
+ name: key,
+ chunkGroup: value
+ })
+ );
+ object.namedChunkGroups = factory.create(
+ `${type}.namedChunkGroups`,
+ array,
+ context
+ );
+ },
+ errors: (object, compilation, context, options, factory) => {
+ const { type, cachedGetErrors } = context;
+ const rawErrors = cachedGetErrors(compilation);
+ const factorizedErrors = factory.create(
+ `${type}.errors`,
+ cachedGetErrors(compilation),
+ context
+ );
+ let filtered = 0;
+ if (options.errorDetails === "auto" && rawErrors.length >= 3) {
+ filtered = rawErrors
+ .map(e => typeof e !== "string" && e.details)
+ .filter(Boolean).length;
+ }
+ if (
+ options.errorDetails === true ||
+ !Number.isFinite(options.errorsSpace)
+ ) {
+ object.errors = factorizedErrors;
+ if (filtered) object.filteredErrorDetailsCount = filtered;
+ return;
+ }
+ const [errors, filteredBySpace] = errorsSpaceLimit(
+ factorizedErrors,
+ options.errorsSpace
+ );
+ object.filteredErrorDetailsCount = filtered + filteredBySpace;
+ object.errors = errors;
+ },
+ errorsCount: (object, compilation, { cachedGetErrors }) => {
+ object.errorsCount = countWithChildren(compilation, c =>
+ cachedGetErrors(c)
+ );
+ },
+ warnings: (object, compilation, context, options, factory) => {
+ const { type, cachedGetWarnings } = context;
+ const rawWarnings = factory.create(
+ `${type}.warnings`,
+ cachedGetWarnings(compilation),
+ context
+ );
+ let filtered = 0;
+ if (options.errorDetails === "auto") {
+ filtered = cachedGetWarnings(compilation)
+ .map(e => typeof e !== "string" && e.details)
+ .filter(Boolean).length;
+ }
+ if (
+ options.errorDetails === true ||
+ !Number.isFinite(options.warningsSpace)
+ ) {
+ object.warnings = rawWarnings;
+ if (filtered) object.filteredWarningDetailsCount = filtered;
+ return;
+ }
+ const [warnings, filteredBySpace] = errorsSpaceLimit(
+ rawWarnings,
+ options.warningsSpace
+ );
+ object.filteredWarningDetailsCount = filtered + filteredBySpace;
+ object.warnings = warnings;
+ },
+ warningsCount: (
+ object,
+ compilation,
+ context,
+ { warningsFilter },
+ factory
+ ) => {
+ const { type, cachedGetWarnings } = context;
+ object.warningsCount = countWithChildren(compilation, (c, childType) => {
+ if (!warningsFilter && warningsFilter.length === 0)
+ return cachedGetWarnings(c);
+ return factory
+ .create(`${type}${childType}.warnings`, cachedGetWarnings(c), context)
+ .filter(warning => {
+ const warningString = Object.keys(warning)
+ .map(key => `${warning[key]}`)
+ .join("\n");
+ return !warningsFilter.some(filter =>
+ filter(warning, warningString)
+ );
+ });
+ });
+ },
+ children: (object, compilation, context, options, factory) => {
+ const { type } = context;
+ object.children = factory.create(
+ `${type}.children`,
+ compilation.children,
+ context
+ );
+ }
+ },
+ asset: {
+ _: (object, asset, context, options, factory) => {
+ const { compilation } = context;
+ object.type = asset.type;
+ object.name = asset.name;
+ object.size = asset.source.size();
+ object.emitted = compilation.emittedAssets.has(asset.name);
+ object.comparedForEmit = compilation.comparedForEmitAssets.has(
+ asset.name
+ );
+ const cached = !object.emitted && !object.comparedForEmit;
+ object.cached = cached;
+ object.info = asset.info;
+ if (!cached || options.cachedAssets) {
+ Object.assign(
+ object,
+ factory.create(`${context.type}$visible`, asset, context)
+ );
+ }
+ }
+ },
+ asset$visible: {
+ _: (
+ object,
+ asset,
+ { compilation, compilationFileToChunks, compilationAuxiliaryFileToChunks }
+ ) => {
+ const chunks = compilationFileToChunks.get(asset.name) || [];
+ const auxiliaryChunks =
+ compilationAuxiliaryFileToChunks.get(asset.name) || [];
+ object.chunkNames = uniqueOrderedArray(
+ chunks,
+ c => (c.name ? [c.name] : []),
+ compareIds
+ );
+ object.chunkIdHints = uniqueOrderedArray(
+ chunks,
+ c => Array.from(c.idNameHints),
+ compareIds
+ );
+ object.auxiliaryChunkNames = uniqueOrderedArray(
+ auxiliaryChunks,
+ c => (c.name ? [c.name] : []),
+ compareIds
+ );
+ object.auxiliaryChunkIdHints = uniqueOrderedArray(
+ auxiliaryChunks,
+ c => Array.from(c.idNameHints),
+ compareIds
+ );
+ object.filteredRelated = asset.related ? asset.related.length : undefined;
+ },
+ relatedAssets: (object, asset, context, options, factory) => {
+ const { type } = context;
+ object.related = factory.create(
+ `${type.slice(0, -8)}.related`,
+ asset.related,
+ context
+ );
+ object.filteredRelated = asset.related
+ ? asset.related.length - object.related.length
+ : undefined;
+ },
+ ids: (
+ object,
+ asset,
+ { compilationFileToChunks, compilationAuxiliaryFileToChunks }
+ ) => {
+ const chunks = compilationFileToChunks.get(asset.name) || [];
+ const auxiliaryChunks =
+ compilationAuxiliaryFileToChunks.get(asset.name) || [];
+ object.chunks = uniqueOrderedArray(chunks, c => c.ids, compareIds);
+ object.auxiliaryChunks = uniqueOrderedArray(
+ auxiliaryChunks,
+ c => c.ids,
+ compareIds
+ );
+ },
+ performance: (object, asset) => {
+ object.isOverSizeLimit = SizeLimitsPlugin.isOverSizeLimit(asset.source);
+ }
+ },
+ chunkGroup: {
+ _: (
+ object,
+ { name, chunkGroup },
+ { compilation, compilation: { moduleGraph, chunkGraph } },
+ { ids, chunkGroupAuxiliary, chunkGroupChildren, chunkGroupMaxAssets }
+ ) => {
+ const children =
+ chunkGroupChildren &&
+ chunkGroup.getChildrenByOrders(moduleGraph, chunkGraph);
+ /**
+ * @param {string} name Name
+ * @returns {{ name: string, size: number }} Asset object
+ */
+ const toAsset = name => {
+ const asset = compilation.getAsset(name);
+ return {
+ name,
+ size: asset ? asset.info.size : -1
+ };
+ };
+ /** @type {(total: number, asset: { size: number }) => number} */
+ const sizeReducer = (total, { size }) => total + size;
+ const assets = uniqueArray(chunkGroup.chunks, c => c.files).map(toAsset);
+ const auxiliaryAssets = uniqueOrderedArray(
+ chunkGroup.chunks,
+ c => c.auxiliaryFiles,
+ compareIds
+ ).map(toAsset);
+ const assetsSize = assets.reduce(sizeReducer, 0);
+ const auxiliaryAssetsSize = auxiliaryAssets.reduce(sizeReducer, 0);
+ /** @type {KnownStatsChunkGroup} */
+ const statsChunkGroup = {
+ name,
+ chunks: ids ? chunkGroup.chunks.map(c => c.id) : undefined,
+ assets: assets.length <= chunkGroupMaxAssets ? assets : undefined,
+ filteredAssets:
+ assets.length <= chunkGroupMaxAssets ? 0 : assets.length,
+ assetsSize,
+ auxiliaryAssets:
+ chunkGroupAuxiliary && auxiliaryAssets.length <= chunkGroupMaxAssets
+ ? auxiliaryAssets
+ : undefined,
+ filteredAuxiliaryAssets:
+ chunkGroupAuxiliary && auxiliaryAssets.length <= chunkGroupMaxAssets
+ ? 0
+ : auxiliaryAssets.length,
+ auxiliaryAssetsSize,
+ children: children
+ ? mapObject(children, groups =>
+ groups.map(group => {
+ const assets = uniqueArray(group.chunks, c => c.files).map(
+ toAsset
+ );
+ const auxiliaryAssets = uniqueOrderedArray(
+ group.chunks,
+ c => c.auxiliaryFiles,
+ compareIds
+ ).map(toAsset);
+
+ /** @type {KnownStatsChunkGroup} */
+ const childStatsChunkGroup = {
+ name: group.name,
+ chunks: ids ? group.chunks.map(c => c.id) : undefined,
+ assets:
+ assets.length <= chunkGroupMaxAssets ? assets : undefined,
+ filteredAssets:
+ assets.length <= chunkGroupMaxAssets ? 0 : assets.length,
+ auxiliaryAssets:
+ chunkGroupAuxiliary &&
+ auxiliaryAssets.length <= chunkGroupMaxAssets
+ ? auxiliaryAssets
+ : undefined,
+ filteredAuxiliaryAssets:
+ chunkGroupAuxiliary &&
+ auxiliaryAssets.length <= chunkGroupMaxAssets
+ ? 0
+ : auxiliaryAssets.length
+ };
+
+ return childStatsChunkGroup;
+ })
+ )
+ : undefined,
+ childAssets: children
+ ? mapObject(children, groups => {
+ /** @type {Set<string>} */
+ const set = new Set();
+ for (const group of groups) {
+ for (const chunk of group.chunks) {
+ for (const asset of chunk.files) {
+ set.add(asset);
+ }
+ }
+ }
+ return Array.from(set);
+ })
+ : undefined
+ };
+ Object.assign(object, statsChunkGroup);
+ },
+ performance: (object, { chunkGroup }) => {
+ object.isOverSizeLimit = SizeLimitsPlugin.isOverSizeLimit(chunkGroup);
+ }
+ },
+ module: {
+ _: (object, module, context, options, factory) => {
+ const { compilation, type } = context;
+ const built = compilation.builtModules.has(module);
+ const codeGenerated = compilation.codeGeneratedModules.has(module);
+ const buildTimeExecuted =
+ compilation.buildTimeExecutedModules.has(module);
+ /** @type {{[x: string]: number}} */
+ const sizes = {};
+ for (const sourceType of module.getSourceTypes()) {
+ sizes[sourceType] = module.size(sourceType);
+ }
+ /** @type {KnownStatsModule} */
+ const statsModule = {
+ type: "module",
+ moduleType: module.type,
+ layer: module.layer,
+ size: module.size(),
+ sizes,
+ built,
+ codeGenerated,
+ buildTimeExecuted,
+ cached: !built && !codeGenerated
+ };
+ Object.assign(object, statsModule);
+
+ if (built || codeGenerated || options.cachedModules) {
+ Object.assign(
+ object,
+ factory.create(`${type}$visible`, module, context)
+ );
+ }
+ }
+ },
+ module$visible: {
+ _: (object, module, context, { requestShortener }, factory) => {
+ const { compilation, type, rootModules } = context;
+ const { moduleGraph } = compilation;
+ /** @type {Module[]} */
+ const path = [];
+ const issuer = moduleGraph.getIssuer(module);
+ let current = issuer;
+ while (current) {
+ path.push(current);
+ current = moduleGraph.getIssuer(current);
+ }
+ path.reverse();
+ const profile = moduleGraph.getProfile(module);
+ const errors = module.getErrors();
+ const errorsCount = errors !== undefined ? countIterable(errors) : 0;
+ const warnings = module.getWarnings();
+ const warningsCount =
+ warnings !== undefined ? countIterable(warnings) : 0;
+ /** @type {{[x: string]: number}} */
+ const sizes = {};
+ for (const sourceType of module.getSourceTypes()) {
+ sizes[sourceType] = module.size(sourceType);
+ }
+ /** @type {KnownStatsModule} */
+ const statsModule = {
+ identifier: module.identifier(),
+ name: module.readableIdentifier(requestShortener),
+ nameForCondition: module.nameForCondition(),
+ index: moduleGraph.getPreOrderIndex(module),
+ preOrderIndex: moduleGraph.getPreOrderIndex(module),
+ index2: moduleGraph.getPostOrderIndex(module),
+ postOrderIndex: moduleGraph.getPostOrderIndex(module),
+ cacheable: module.buildInfo.cacheable,
+ optional: module.isOptional(moduleGraph),
+ orphan:
+ !type.endsWith("module.modules[].module$visible") &&
+ compilation.chunkGraph.getNumberOfModuleChunks(module) === 0,
+ dependent: rootModules ? !rootModules.has(module) : undefined,
+ issuer: issuer && issuer.identifier(),
+ issuerName: issuer && issuer.readableIdentifier(requestShortener),
+ issuerPath:
+ issuer &&
+ factory.create(`${type.slice(0, -8)}.issuerPath`, path, context),
+ failed: errorsCount > 0,
+ errors: errorsCount,
+ warnings: warningsCount
+ };
+ Object.assign(object, statsModule);
+ if (profile) {
+ object.profile = factory.create(
+ `${type.slice(0, -8)}.profile`,
+ profile,
+ context
+ );
+ }
+ },
+ ids: (object, module, { compilation: { chunkGraph, moduleGraph } }) => {
+ object.id = chunkGraph.getModuleId(module);
+ const issuer = moduleGraph.getIssuer(module);
+ object.issuerId = issuer && chunkGraph.getModuleId(issuer);
+ object.chunks = Array.from(
+ chunkGraph.getOrderedModuleChunksIterable(module, compareChunksById),
+ chunk => chunk.id
+ );
+ },
+ moduleAssets: (object, module) => {
+ object.assets = module.buildInfo.assets
+ ? Object.keys(module.buildInfo.assets)
+ : [];
+ },
+ reasons: (object, module, context, options, factory) => {
+ const {
+ type,
+ compilation: { moduleGraph }
+ } = context;
+ const groupsReasons = factory.create(
+ `${type.slice(0, -8)}.reasons`,
+ Array.from(moduleGraph.getIncomingConnections(module)),
+ context
+ );
+ const limited = spaceLimited(groupsReasons, options.reasonsSpace);
+ object.reasons = limited.children;
+ object.filteredReasons = limited.filteredChildren;
+ },
+ usedExports: (
+ object,
+ module,
+ { runtime, compilation: { moduleGraph } }
+ ) => {
+ const usedExports = moduleGraph.getUsedExports(module, runtime);
+ if (usedExports === null) {
+ object.usedExports = null;
+ } else if (typeof usedExports === "boolean") {
+ object.usedExports = usedExports;
+ } else {
+ object.usedExports = Array.from(usedExports);
+ }
+ },
+ providedExports: (object, module, { compilation: { moduleGraph } }) => {
+ const providedExports = moduleGraph.getProvidedExports(module);
+ object.providedExports = Array.isArray(providedExports)
+ ? providedExports
+ : null;
+ },
+ optimizationBailout: (
+ object,
+ module,
+ { compilation: { moduleGraph } },
+ { requestShortener }
+ ) => {
+ object.optimizationBailout = moduleGraph
+ .getOptimizationBailout(module)
+ .map(item => {
+ if (typeof item === "function") return item(requestShortener);
+ return item;
+ });
+ },
+ depth: (object, module, { compilation: { moduleGraph } }) => {
+ object.depth = moduleGraph.getDepth(module);
+ },
+ nestedModules: (object, module, context, options, factory) => {
+ const { type } = context;
+ const innerModules = /** @type {Module & { modules?: Module[] }} */ (
+ module
+ ).modules;
+ if (Array.isArray(innerModules)) {
+ const groupedModules = factory.create(
+ `${type.slice(0, -8)}.modules`,
+ innerModules,
+ context
+ );
+ const limited = spaceLimited(
+ groupedModules,
+ options.nestedModulesSpace
+ );
+ object.modules = limited.children;
+ object.filteredModules = limited.filteredChildren;
+ }
+ },
+ source: (object, module) => {
+ const originalSource = module.originalSource();
+ if (originalSource) {
+ object.source = originalSource.source();
+ }
+ }
+ },
+ profile: {
+ _: (object, profile) => {
+ /** @type {KnownStatsProfile} */
+ const statsProfile = {
+ total:
+ profile.factory +
+ profile.restoring +
+ profile.integration +
+ profile.building +
+ profile.storing,
+ resolving: profile.factory,
+ restoring: profile.restoring,
+ building: profile.building,
+ integration: profile.integration,
+ storing: profile.storing,
+ additionalResolving: profile.additionalFactories,
+ additionalIntegration: profile.additionalIntegration,
+ // TODO remove this in webpack 6
+ factory: profile.factory,
+ // TODO remove this in webpack 6
+ dependencies: profile.additionalFactories
+ };
+ Object.assign(object, statsProfile);
+ }
+ },
+ moduleIssuer: {
+ _: (object, module, context, { requestShortener }, factory) => {
+ const { compilation, type } = context;
+ const { moduleGraph } = compilation;
+ const profile = moduleGraph.getProfile(module);
+ /** @type {KnownStatsModuleIssuer} */
+ const statsModuleIssuer = {
+ identifier: module.identifier(),
+ name: module.readableIdentifier(requestShortener)
+ };
+ Object.assign(object, statsModuleIssuer);
+ if (profile) {
+ object.profile = factory.create(`${type}.profile`, profile, context);
+ }
+ },
+ ids: (object, module, { compilation: { chunkGraph } }) => {
+ object.id = chunkGraph.getModuleId(module);
+ }
+ },
+ moduleReason: {
+ _: (object, reason, { runtime }, { requestShortener }) => {
+ const dep = reason.dependency;
+ const moduleDep =
+ dep && dep instanceof ModuleDependency ? dep : undefined;
+ /** @type {KnownStatsModuleReason} */
+ const statsModuleReason = {
+ moduleIdentifier: reason.originModule
+ ? reason.originModule.identifier()
+ : null,
+ module: reason.originModule
+ ? reason.originModule.readableIdentifier(requestShortener)
+ : null,
+ moduleName: reason.originModule
+ ? reason.originModule.readableIdentifier(requestShortener)
+ : null,
+ resolvedModuleIdentifier: reason.resolvedOriginModule
+ ? reason.resolvedOriginModule.identifier()
+ : null,
+ resolvedModule: reason.resolvedOriginModule
+ ? reason.resolvedOriginModule.readableIdentifier(requestShortener)
+ : null,
+ type: reason.dependency ? reason.dependency.type : null,
+ active: reason.isActive(runtime),
+ explanation: reason.explanation,
+ userRequest: (moduleDep && moduleDep.userRequest) || null
+ };
+ Object.assign(object, statsModuleReason);
+ if (reason.dependency) {
+ const locInfo = formatLocation(reason.dependency.loc);
+ if (locInfo) {
+ object.loc = locInfo;
+ }
+ }
+ },
+ ids: (object, reason, { compilation: { chunkGraph } }) => {
+ object.moduleId = reason.originModule
+ ? chunkGraph.getModuleId(reason.originModule)
+ : null;
+ object.resolvedModuleId = reason.resolvedOriginModule
+ ? chunkGraph.getModuleId(reason.resolvedOriginModule)
+ : null;
+ }
+ },
+ chunk: {
+ _: (object, chunk, { makePathsRelative, compilation: { chunkGraph } }) => {
+ const childIdByOrder = chunk.getChildIdsByOrders(chunkGraph);
+
+ /** @type {KnownStatsChunk} */
+ const statsChunk = {
+ rendered: chunk.rendered,
+ initial: chunk.canBeInitial(),
+ entry: chunk.hasRuntime(),
+ recorded: AggressiveSplittingPlugin.wasChunkRecorded(chunk),
+ reason: chunk.chunkReason,
+ size: chunkGraph.getChunkModulesSize(chunk),
+ sizes: chunkGraph.getChunkModulesSizes(chunk),
+ names: chunk.name ? [chunk.name] : [],
+ idHints: Array.from(chunk.idNameHints),
+ runtime:
+ chunk.runtime === undefined
+ ? undefined
+ : typeof chunk.runtime === "string"
+ ? [makePathsRelative(chunk.runtime)]
+ : Array.from(chunk.runtime.sort(), makePathsRelative),
+ files: Array.from(chunk.files),
+ auxiliaryFiles: Array.from(chunk.auxiliaryFiles).sort(compareIds),
+ hash: chunk.renderedHash,
+ childrenByOrder: childIdByOrder
+ };
+ Object.assign(object, statsChunk);
+ },
+ ids: (object, chunk) => {
+ object.id = chunk.id;
+ },
+ chunkRelations: (object, chunk, { compilation: { chunkGraph } }) => {
+ /** @type {Set<string|number>} */
+ const parents = new Set();
+ /** @type {Set<string|number>} */
+ const children = new Set();
+ /** @type {Set<string|number>} */
+ const siblings = new Set();
+
+ for (const chunkGroup of chunk.groupsIterable) {
+ for (const parentGroup of chunkGroup.parentsIterable) {
+ for (const chunk of parentGroup.chunks) {
+ parents.add(chunk.id);
+ }
+ }
+ for (const childGroup of chunkGroup.childrenIterable) {
+ for (const chunk of childGroup.chunks) {
+ children.add(chunk.id);
+ }
+ }
+ for (const sibling of chunkGroup.chunks) {
+ if (sibling !== chunk) siblings.add(sibling.id);
+ }
+ }
+ object.siblings = Array.from(siblings).sort(compareIds);
+ object.parents = Array.from(parents).sort(compareIds);
+ object.children = Array.from(children).sort(compareIds);
+ },
+ chunkModules: (object, chunk, context, options, factory) => {
+ const {
+ type,
+ compilation: { chunkGraph }
+ } = context;
+ const array = chunkGraph.getChunkModules(chunk);
+ const groupedModules = factory.create(`${type}.modules`, array, {
+ ...context,
+ runtime: chunk.runtime,
+ rootModules: new Set(chunkGraph.getChunkRootModules(chunk))
+ });
+ const limited = spaceLimited(groupedModules, options.chunkModulesSpace);
+ object.modules = limited.children;
+ object.filteredModules = limited.filteredChildren;
+ },
+ chunkOrigins: (object, chunk, context, options, factory) => {
+ const {
+ type,
+ compilation: { chunkGraph }
+ } = context;
+ /** @type {Set<string>} */
+ const originsKeySet = new Set();
+ const origins = [];
+ for (const g of chunk.groupsIterable) {
+ origins.push(...g.origins);
+ }
+ const array = origins.filter(origin => {
+ const key = [
+ origin.module ? chunkGraph.getModuleId(origin.module) : undefined,
+ formatLocation(origin.loc),
+ origin.request
+ ].join();
+ if (originsKeySet.has(key)) return false;
+ originsKeySet.add(key);
+ return true;
+ });
+ object.origins = factory.create(`${type}.origins`, array, context);
+ }
+ },
+ chunkOrigin: {
+ _: (object, origin, context, { requestShortener }) => {
+ /** @type {KnownStatsChunkOrigin} */
+ const statsChunkOrigin = {
+ module: origin.module ? origin.module.identifier() : "",
+ moduleIdentifier: origin.module ? origin.module.identifier() : "",
+ moduleName: origin.module
+ ? origin.module.readableIdentifier(requestShortener)
+ : "",
+ loc: formatLocation(origin.loc),
+ request: origin.request
+ };
+ Object.assign(object, statsChunkOrigin);
+ },
+ ids: (object, origin, { compilation: { chunkGraph } }) => {
+ object.moduleId = origin.module
+ ? chunkGraph.getModuleId(origin.module)
+ : undefined;
+ }
+ },
+ error: EXTRACT_ERROR,
+ warning: EXTRACT_ERROR,
+ moduleTraceItem: {
+ _: (object, { origin, module }, context, { requestShortener }, factory) => {
+ const {
+ type,
+ compilation: { moduleGraph }
+ } = context;
+ object.originIdentifier = origin.identifier();
+ object.originName = origin.readableIdentifier(requestShortener);
+ object.moduleIdentifier = module.identifier();
+ object.moduleName = module.readableIdentifier(requestShortener);
+ const dependencies = Array.from(
+ moduleGraph.getIncomingConnections(module)
+ )
+ .filter(c => c.resolvedOriginModule === origin && c.dependency)
+ .map(c => c.dependency);
+ object.dependencies = factory.create(
+ `${type}.dependencies`,
+ Array.from(new Set(dependencies)),
+ context
+ );
+ },
+ ids: (object, { origin, module }, { compilation: { chunkGraph } }) => {
+ object.originId = chunkGraph.getModuleId(origin);
+ object.moduleId = chunkGraph.getModuleId(module);
+ }
+ },
+ moduleTraceDependency: {
+ _: (object, dependency) => {
+ object.loc = formatLocation(dependency.loc);
+ }
+ }
+};
+
+/** @type {Record<string, Record<string, (thing: any, context: StatsFactoryContext, options: NormalizedStatsOptions) => boolean | undefined>>} */
+const FILTER = {
+ "module.reasons": {
+ "!orphanModules": (reason, { compilation: { chunkGraph } }) => {
+ if (
+ reason.originModule &&
+ chunkGraph.getNumberOfModuleChunks(reason.originModule) === 0
+ ) {
+ return false;
+ }
+ }
+ }
+};
+
+/** @type {Record<string, Record<string, (thing: Object, context: StatsFactoryContext, options: NormalizedStatsOptions) => boolean | undefined>>} */
+const FILTER_RESULTS = {
+ "compilation.warnings": {
+ warningsFilter: util.deprecate(
+ (warning, context, { warningsFilter }) => {
+ const warningString = Object.keys(warning)
+ .map(key => `${warning[key]}`)
+ .join("\n");
+ return !warningsFilter.some(filter => filter(warning, warningString));
+ },
+ "config.stats.warningsFilter is deprecated in favor of config.ignoreWarnings",
+ "DEP_WEBPACK_STATS_WARNINGS_FILTER"
+ )
+ }
+};
+
+/** @type {Record<string, (comparators: Function[], context: StatsFactoryContext) => void>} */
+const MODULES_SORTER = {
+ _: (comparators, { compilation: { moduleGraph } }) => {
+ comparators.push(
+ compareSelect(
+ /**
+ * @param {Module} m module
+ * @returns {number} depth
+ */
+ m => moduleGraph.getDepth(m),
+ compareNumbers
+ ),
+ compareSelect(
+ /**
+ * @param {Module} m module
+ * @returns {number} index
+ */
+ m => moduleGraph.getPreOrderIndex(m),
+ compareNumbers
+ ),
+ compareSelect(
+ /**
+ * @param {Module} m module
+ * @returns {string} identifier
+ */
+ m => m.identifier(),
+ compareIds
+ )
+ );
+ }
+};
+
+/** @type {Record<string, Record<string, (comparators: Function[], context: StatsFactoryContext) => void>>} */
+const SORTERS = {
+ "compilation.chunks": {
+ _: comparators => {
+ comparators.push(compareSelect(c => c.id, compareIds));
+ }
+ },
+ "compilation.modules": MODULES_SORTER,
+ "chunk.rootModules": MODULES_SORTER,
+ "chunk.modules": MODULES_SORTER,
+ "module.modules": MODULES_SORTER,
+ "module.reasons": {
+ _: (comparators, { compilation: { chunkGraph } }) => {
+ comparators.push(
+ compareSelect(x => x.originModule, compareModulesByIdentifier)
+ );
+ comparators.push(
+ compareSelect(x => x.resolvedOriginModule, compareModulesByIdentifier)
+ );
+ comparators.push(
+ compareSelect(
+ x => x.dependency,
+ concatComparators(
+ compareSelect(
+ /**
+ * @param {Dependency} x dependency
+ * @returns {DependencyLocation} location
+ */
+ x => x.loc,
+ compareLocations
+ ),
+ compareSelect(x => x.type, compareIds)
+ )
+ )
+ );
+ }
+ },
+ "chunk.origins": {
+ _: (comparators, { compilation: { chunkGraph } }) => {
+ comparators.push(
+ compareSelect(
+ origin =>
+ origin.module ? chunkGraph.getModuleId(origin.module) : undefined,
+ compareIds
+ ),
+ compareSelect(origin => formatLocation(origin.loc), compareIds),
+ compareSelect(origin => origin.request, compareIds)
+ );
+ }
+ }
+};
+
+const getItemSize = item => {
+ // Each item takes 1 line
+ // + the size of the children
+ // + 1 extra line when it has children and filteredChildren
+ return !item.children
+ ? 1
+ : item.filteredChildren
+ ? 2 + getTotalSize(item.children)
+ : 1 + getTotalSize(item.children);
+};
+
+const getTotalSize = children => {
+ let size = 0;
+ for (const child of children) {
+ size += getItemSize(child);
+ }
+ return size;
+};
+
+const getTotalItems = children => {
+ let count = 0;
+ for (const child of children) {
+ if (!child.children && !child.filteredChildren) {
+ count++;
+ } else {
+ if (child.children) count += getTotalItems(child.children);
+ if (child.filteredChildren) count += child.filteredChildren;
+ }
+ }
+ return count;
+};
+
+const collapse = children => {
+ // After collapse each child must take exactly one line
+ const newChildren = [];
+ for (const child of children) {
+ if (child.children) {
+ let filteredChildren = child.filteredChildren || 0;
+ filteredChildren += getTotalItems(child.children);
+ newChildren.push({
+ ...child,
+ children: undefined,
+ filteredChildren
+ });
+ } else {
+ newChildren.push(child);
+ }
+ }
+ return newChildren;
+};
+
+const spaceLimited = (
+ itemsAndGroups,
+ max,
+ filteredChildrenLineReserved = false
+) => {
+ if (max < 1) {
+ return {
+ children: undefined,
+ filteredChildren: getTotalItems(itemsAndGroups)
+ };
+ }
+ /** @type {any[] | undefined} */
+ let children = undefined;
+ /** @type {number | undefined} */
+ let filteredChildren = undefined;
+ // This are the groups, which take 1+ lines each
+ const groups = [];
+ // The sizes of the groups are stored in groupSizes
+ const groupSizes = [];
+ // This are the items, which take 1 line each
+ const items = [];
+ // The total of group sizes
+ let groupsSize = 0;
+
+ for (const itemOrGroup of itemsAndGroups) {
+ // is item
+ if (!itemOrGroup.children && !itemOrGroup.filteredChildren) {
+ items.push(itemOrGroup);
+ } else {
+ groups.push(itemOrGroup);
+ const size = getItemSize(itemOrGroup);
+ groupSizes.push(size);
+ groupsSize += size;
+ }
+ }
+
+ if (groupsSize + items.length <= max) {
+ // The total size in the current state fits into the max
+ // keep all
+ children = groups.length > 0 ? groups.concat(items) : items;
+ } else if (groups.length === 0) {
+ // slice items to max
+ // inner space marks that lines for filteredChildren already reserved
+ const limit = max - (filteredChildrenLineReserved ? 0 : 1);
+ filteredChildren = items.length - limit;
+ items.length = limit;
+ children = items;
+ } else {
+ // limit is the size when all groups are collapsed
+ const limit =
+ groups.length +
+ (filteredChildrenLineReserved || items.length === 0 ? 0 : 1);
+ if (limit < max) {
+ // calculate how much we are over the size limit
+ // this allows to approach the limit faster
+ let oversize;
+ // If each group would take 1 line the total would be below the maximum
+ // collapse some groups, keep items
+ while (
+ (oversize =
+ groupsSize +
+ items.length +
+ (filteredChildren && !filteredChildrenLineReserved ? 1 : 0) -
+ max) > 0
+ ) {
+ // Find the maximum group and process only this one
+ const maxGroupSize = Math.max(...groupSizes);
+ if (maxGroupSize < items.length) {
+ filteredChildren = items.length;
+ items.length = 0;
+ continue;
+ }
+ for (let i = 0; i < groups.length; i++) {
+ if (groupSizes[i] === maxGroupSize) {
+ const group = groups[i];
+ // run this algorithm recursively and limit the size of the children to
+ // current size - oversize / number of groups
+ // So it should always end up being smaller
+ const headerSize = group.filteredChildren ? 2 : 1;
+ const limited = spaceLimited(
+ group.children,
+ maxGroupSize -
+ // we should use ceil to always feet in max
+ Math.ceil(oversize / groups.length) -
+ // we substitute size of group head
+ headerSize,
+ headerSize === 2
+ );
+ groups[i] = {
+ ...group,
+ children: limited.children,
+ filteredChildren: limited.filteredChildren
+ ? (group.filteredChildren || 0) + limited.filteredChildren
+ : group.filteredChildren
+ };
+ const newSize = getItemSize(groups[i]);
+ groupsSize -= maxGroupSize - newSize;
+ groupSizes[i] = newSize;
+ break;
+ }
+ }
+ }
+ children = groups.concat(items);
+ } else if (limit === max) {
+ // If we have only enough space to show one line per group and one line for the filtered items
+ // collapse all groups and items
+ children = collapse(groups);
+ filteredChildren = items.length;
+ } else {
+ // If we have no space
+ // collapse complete group
+ filteredChildren = getTotalItems(itemsAndGroups);
+ }
+ }
+
+ return {
+ children,
+ filteredChildren
+ };
+};
+
+const errorsSpaceLimit = (errors, max) => {
+ let filtered = 0;
+ // Can not fit into limit
+ // print only messages
+ if (errors.length + 1 >= max)
+ return [
+ errors.map(error => {
+ if (typeof error === "string" || !error.details) return error;
+ filtered++;
+ return { ...error, details: "" };
+ }),
+ filtered
+ ];
+ let fullLength = errors.length;
+ let result = errors;
+
+ let i = 0;
+ for (; i < errors.length; i++) {
+ const error = errors[i];
+ if (typeof error !== "string" && error.details) {
+ const splitted = error.details.split("\n");
+ const len = splitted.length;
+ fullLength += len;
+ if (fullLength > max) {
+ result = i > 0 ? errors.slice(0, i) : [];
+ const overLimit = fullLength - max + 1;
+ const error = errors[i++];
+ result.push({
+ ...error,
+ details: error.details.split("\n").slice(0, -overLimit).join("\n"),
+ filteredDetails: overLimit
+ });
+ filtered = errors.length - i;
+ for (; i < errors.length; i++) {
+ const error = errors[i];
+ if (typeof error === "string" || !error.details) result.push(error);
+ result.push({ ...error, details: "" });
+ }
+ break;
+ } else if (fullLength === max) {
+ result = errors.slice(0, ++i);
+ filtered = errors.length - i;
+ for (; i < errors.length; i++) {
+ const error = errors[i];
+ if (typeof error === "string" || !error.details) result.push(error);
+ result.push({ ...error, details: "" });
+ }
+ break;
+ }
+ }
+ }
+
+ return [result, filtered];
+};
+
+const assetGroup = (children, assets) => {
+ let size = 0;
+ for (const asset of children) {
+ size += asset.size;
+ }
+ return {
+ size
+ };
+};
+
+const moduleGroup = (children, modules) => {
+ let size = 0;
+ const sizes = {};
+ for (const module of children) {
+ size += module.size;
+ for (const key of Object.keys(module.sizes)) {
+ sizes[key] = (sizes[key] || 0) + module.sizes[key];
+ }
+ }
+ return {
+ size,
+ sizes
+ };
+};
+
+const reasonGroup = (children, reasons) => {
+ let active = false;
+ for (const reason of children) {
+ active = active || reason.active;
+ }
+ return {
+ active
+ };
+};
+
+const GROUP_EXTENSION_REGEXP = /(\.[^.]+?)(?:\?|(?: \+ \d+ modules?)?$)/;
+const GROUP_PATH_REGEXP = /(.+)[/\\][^/\\]+?(?:\?|(?: \+ \d+ modules?)?$)/;
+
+/** @type {Record<string, (groupConfigs: GroupConfig[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>} */
+const ASSETS_GROUPERS = {
+ _: (groupConfigs, context, options) => {
+ const groupByFlag = (name, exclude) => {
+ groupConfigs.push({
+ getKeys: asset => {
+ return asset[name] ? ["1"] : undefined;
+ },
+ getOptions: () => {
+ return {
+ groupChildren: !exclude,
+ force: exclude
+ };
+ },
+ createGroup: (key, children, assets) => {
+ return exclude
+ ? {
+ type: "assets by status",
+ [name]: !!key,
+ filteredChildren: assets.length,
+ ...assetGroup(children, assets)
+ }
+ : {
+ type: "assets by status",
+ [name]: !!key,
+ children,
+ ...assetGroup(children, assets)
+ };
+ }
+ });
+ };
+ const {
+ groupAssetsByEmitStatus,
+ groupAssetsByPath,
+ groupAssetsByExtension
+ } = options;
+ if (groupAssetsByEmitStatus) {
+ groupByFlag("emitted");
+ groupByFlag("comparedForEmit");
+ groupByFlag("isOverSizeLimit");
+ }
+ if (groupAssetsByEmitStatus || !options.cachedAssets) {
+ groupByFlag("cached", !options.cachedAssets);
+ }
+ if (groupAssetsByPath || groupAssetsByExtension) {
+ groupConfigs.push({
+ getKeys: asset => {
+ const extensionMatch =
+ groupAssetsByExtension && GROUP_EXTENSION_REGEXP.exec(asset.name);
+ const extension = extensionMatch ? extensionMatch[1] : "";
+ const pathMatch =
+ groupAssetsByPath && GROUP_PATH_REGEXP.exec(asset.name);
+ const path = pathMatch ? pathMatch[1].split(/[/\\]/) : [];
+ const keys = [];
+ if (groupAssetsByPath) {
+ keys.push(".");
+ if (extension)
+ keys.push(
+ path.length
+ ? `${path.join("/")}/*${extension}`
+ : `*${extension}`
+ );
+ while (path.length > 0) {
+ keys.push(path.join("/") + "/");
+ path.pop();
+ }
+ } else {
+ if (extension) keys.push(`*${extension}`);
+ }
+ return keys;
+ },
+ createGroup: (key, children, assets) => {
+ return {
+ type: groupAssetsByPath ? "assets by path" : "assets by extension",
+ name: key,
+ children,
+ ...assetGroup(children, assets)
+ };
+ }
+ });
+ }
+ },
+ groupAssetsByInfo: (groupConfigs, context, options) => {
+ const groupByAssetInfoFlag = name => {
+ groupConfigs.push({
+ getKeys: asset => {
+ return asset.info && asset.info[name] ? ["1"] : undefined;
+ },
+ createGroup: (key, children, assets) => {
+ return {
+ type: "assets by info",
+ info: {
+ [name]: !!key
+ },
+ children,
+ ...assetGroup(children, assets)
+ };
+ }
+ });
+ };
+ groupByAssetInfoFlag("immutable");
+ groupByAssetInfoFlag("development");
+ groupByAssetInfoFlag("hotModuleReplacement");
+ },
+ groupAssetsByChunk: (groupConfigs, context, options) => {
+ const groupByNames = name => {
+ groupConfigs.push({
+ getKeys: asset => {
+ return asset[name];
+ },
+ createGroup: (key, children, assets) => {
+ return {
+ type: "assets by chunk",
+ [name]: [key],
+ children,
+ ...assetGroup(children, assets)
+ };
+ }
+ });
+ };
+ groupByNames("chunkNames");
+ groupByNames("auxiliaryChunkNames");
+ groupByNames("chunkIdHints");
+ groupByNames("auxiliaryChunkIdHints");
+ },
+ excludeAssets: (groupConfigs, context, { excludeAssets }) => {
+ groupConfigs.push({
+ getKeys: asset => {
+ const ident = asset.name;
+ const excluded = excludeAssets.some(fn => fn(ident, asset));
+ if (excluded) return ["excluded"];
+ },
+ getOptions: () => ({
+ groupChildren: false,
+ force: true
+ }),
+ createGroup: (key, children, assets) => ({
+ type: "hidden assets",
+ filteredChildren: assets.length,
+ ...assetGroup(children, assets)
+ })
+ });
+ }
+};
+
+/** @type {function("module" | "chunk" | "root-of-chunk" | "nested"): Record<string, (groupConfigs: GroupConfig[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>} */
+const MODULES_GROUPERS = type => ({
+ _: (groupConfigs, context, options) => {
+ const groupByFlag = (name, type, exclude) => {
+ groupConfigs.push({
+ getKeys: module => {
+ return module[name] ? ["1"] : undefined;
+ },
+ getOptions: () => {
+ return {
+ groupChildren: !exclude,
+ force: exclude
+ };
+ },
+ createGroup: (key, children, modules) => {
+ return {
+ type,
+ [name]: !!key,
+ ...(exclude ? { filteredChildren: modules.length } : { children }),
+ ...moduleGroup(children, modules)
+ };
+ }
+ });
+ };
+ const {
+ groupModulesByCacheStatus,
+ groupModulesByLayer,
+ groupModulesByAttributes,
+ groupModulesByType,
+ groupModulesByPath,
+ groupModulesByExtension
+ } = options;
+ if (groupModulesByAttributes) {
+ groupByFlag("errors", "modules with errors");
+ groupByFlag("warnings", "modules with warnings");
+ groupByFlag("assets", "modules with assets");
+ groupByFlag("optional", "optional modules");
+ }
+ if (groupModulesByCacheStatus) {
+ groupByFlag("cacheable", "cacheable modules");
+ groupByFlag("built", "built modules");
+ groupByFlag("codeGenerated", "code generated modules");
+ }
+ if (groupModulesByCacheStatus || !options.cachedModules) {
+ groupByFlag("cached", "cached modules", !options.cachedModules);
+ }
+ if (groupModulesByAttributes || !options.orphanModules) {
+ groupByFlag("orphan", "orphan modules", !options.orphanModules);
+ }
+ if (groupModulesByAttributes || !options.dependentModules) {
+ groupByFlag("dependent", "dependent modules", !options.dependentModules);
+ }
+ if (groupModulesByType || !options.runtimeModules) {
+ groupConfigs.push({
+ getKeys: module => {
+ if (!module.moduleType) return;
+ if (groupModulesByType) {
+ return [module.moduleType.split("/", 1)[0]];
+ } else if (module.moduleType === WEBPACK_MODULE_TYPE_RUNTIME) {
+ return [WEBPACK_MODULE_TYPE_RUNTIME];
+ }
+ },
+ getOptions: key => {
+ const exclude =
+ key === WEBPACK_MODULE_TYPE_RUNTIME && !options.runtimeModules;
+ return {
+ groupChildren: !exclude,
+ force: exclude
+ };
+ },
+ createGroup: (key, children, modules) => {
+ const exclude =
+ key === WEBPACK_MODULE_TYPE_RUNTIME && !options.runtimeModules;
+ return {
+ type: `${key} modules`,
+ moduleType: key,
+ ...(exclude ? { filteredChildren: modules.length } : { children }),
+ ...moduleGroup(children, modules)
+ };
+ }
+ });
+ }
+ if (groupModulesByLayer) {
+ groupConfigs.push({
+ getKeys: module => {
+ return [module.layer];
+ },
+ createGroup: (key, children, modules) => {
+ return {
+ type: "modules by layer",
+ layer: key,
+ children,
+ ...moduleGroup(children, modules)
+ };
+ }
+ });
+ }
+ if (groupModulesByPath || groupModulesByExtension) {
+ groupConfigs.push({
+ getKeys: module => {
+ if (!module.name) return;
+ const resource = parseResource(module.name.split("!").pop()).path;
+ const dataUrl = /^data:[^,;]+/.exec(resource);
+ if (dataUrl) return [dataUrl[0]];
+ const extensionMatch =
+ groupModulesByExtension && GROUP_EXTENSION_REGEXP.exec(resource);
+ const extension = extensionMatch ? extensionMatch[1] : "";
+ const pathMatch =
+ groupModulesByPath && GROUP_PATH_REGEXP.exec(resource);
+ const path = pathMatch ? pathMatch[1].split(/[/\\]/) : [];
+ const keys = [];
+ if (groupModulesByPath) {
+ if (extension)
+ keys.push(
+ path.length
+ ? `${path.join("/")}/*${extension}`
+ : `*${extension}`
+ );
+ while (path.length > 0) {
+ keys.push(path.join("/") + "/");
+ path.pop();
+ }
+ } else {
+ if (extension) keys.push(`*${extension}`);
+ }
+ return keys;
+ },
+ createGroup: (key, children, modules) => {
+ const isDataUrl = key.startsWith("data:");
+ return {
+ type: isDataUrl
+ ? "modules by mime type"
+ : groupModulesByPath
+ ? "modules by path"
+ : "modules by extension",
+ name: isDataUrl ? key.slice(/* 'data:'.length */ 5) : key,
+ children,
+ ...moduleGroup(children, modules)
+ };
+ }
+ });
+ }
+ },
+ excludeModules: (groupConfigs, context, { excludeModules }) => {
+ groupConfigs.push({
+ getKeys: module => {
+ const name = module.name;
+ if (name) {
+ const excluded = excludeModules.some(fn => fn(name, module, type));
+ if (excluded) return ["1"];
+ }
+ },
+ getOptions: () => ({
+ groupChildren: false,
+ force: true
+ }),
+ createGroup: (key, children, modules) => ({
+ type: "hidden modules",
+ filteredChildren: children.length,
+ ...moduleGroup(children, modules)
+ })
+ });
+ }
+});
+
+/** @type {Record<string, Record<string, (groupConfigs: GroupConfig[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>>} */
+const RESULT_GROUPERS = {
+ "compilation.assets": ASSETS_GROUPERS,
+ "asset.related": ASSETS_GROUPERS,
+ "compilation.modules": MODULES_GROUPERS("module"),
+ "chunk.modules": MODULES_GROUPERS("chunk"),
+ "chunk.rootModules": MODULES_GROUPERS("root-of-chunk"),
+ "module.modules": MODULES_GROUPERS("nested"),
+ "module.reasons": {
+ groupReasonsByOrigin: groupConfigs => {
+ groupConfigs.push({
+ getKeys: reason => {
+ return [reason.module];
+ },
+ createGroup: (key, children, reasons) => {
+ return {
+ type: "from origin",
+ module: key,
+ children,
+ ...reasonGroup(children, reasons)
+ };
+ }
+ });
+ }
+ }
+};
+
+// remove a prefixed "!" that can be specified to reverse sort order
+const normalizeFieldKey = field => {
+ if (field[0] === "!") {
+ return field.slice(1);
+ }
+ return field;
+};
+
+// if a field is prefixed by a "!" reverse sort order
+const sortOrderRegular = field => {
+ if (field[0] === "!") {
+ return false;
+ }
+ return true;
+};
+
+/**
+ * @param {string} field field name
+ * @returns {function(Object, Object): number} comparators
+ */
+const sortByField = field => {
+ if (!field) {
+ /**
+ * @param {any} a first
+ * @param {any} b second
+ * @returns {-1|0|1} zero
+ */
+ const noSort = (a, b) => 0;
+ return noSort;
+ }
+
+ const fieldKey = normalizeFieldKey(field);
+
+ let sortFn = compareSelect(m => m[fieldKey], compareIds);
+
+ // if a field is prefixed with a "!" the sort is reversed!
+ const sortIsRegular = sortOrderRegular(field);
+
+ if (!sortIsRegular) {
+ const oldSortFn = sortFn;
+ sortFn = (a, b) => oldSortFn(b, a);
+ }
+
+ return sortFn;
+};
+
+const ASSET_SORTERS = {
+ /** @type {(comparators: Function[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void} */
+ assetsSort: (comparators, context, { assetsSort }) => {
+ comparators.push(sortByField(assetsSort));
+ },
+ _: comparators => {
+ comparators.push(compareSelect(a => a.name, compareIds));
+ }
+};
+
+/** @type {Record<string, Record<string, (comparators: Function[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>>} */
+const RESULT_SORTERS = {
+ "compilation.chunks": {
+ chunksSort: (comparators, context, { chunksSort }) => {
+ comparators.push(sortByField(chunksSort));
+ }
+ },
+ "compilation.modules": {
+ modulesSort: (comparators, context, { modulesSort }) => {
+ comparators.push(sortByField(modulesSort));
+ }
+ },
+ "chunk.modules": {
+ chunkModulesSort: (comparators, context, { chunkModulesSort }) => {
+ comparators.push(sortByField(chunkModulesSort));
+ }
+ },
+ "module.modules": {
+ nestedModulesSort: (comparators, context, { nestedModulesSort }) => {
+ comparators.push(sortByField(nestedModulesSort));
+ }
+ },
+ "compilation.assets": ASSET_SORTERS,
+ "asset.related": ASSET_SORTERS
+};
+
+/**
+ * @param {Record<string, Record<string, Function>>} config the config see above
+ * @param {NormalizedStatsOptions} options stats options
+ * @param {function(string, Function): void} fn handler function called for every active line in config
+ * @returns {void}
+ */
+const iterateConfig = (config, options, fn) => {
+ for (const hookFor of Object.keys(config)) {
+ const subConfig = config[hookFor];
+ for (const option of Object.keys(subConfig)) {
+ if (option !== "_") {
+ if (option.startsWith("!")) {
+ if (options[option.slice(1)]) continue;
+ } else {
+ const value = options[option];
+ if (
+ value === false ||
+ value === undefined ||
+ (Array.isArray(value) && value.length === 0)
+ )
+ continue;
+ }
+ }
+ fn(hookFor, subConfig[option]);
+ }
+ }
+};
+
+/** @type {Record<string, string>} */
+const ITEM_NAMES = {
+ "compilation.children[]": "compilation",
+ "compilation.modules[]": "module",
+ "compilation.entrypoints[]": "chunkGroup",
+ "compilation.namedChunkGroups[]": "chunkGroup",
+ "compilation.errors[]": "error",
+ "compilation.warnings[]": "warning",
+ "chunk.modules[]": "module",
+ "chunk.rootModules[]": "module",
+ "chunk.origins[]": "chunkOrigin",
+ "compilation.chunks[]": "chunk",
+ "compilation.assets[]": "asset",
+ "asset.related[]": "asset",
+ "module.issuerPath[]": "moduleIssuer",
+ "module.reasons[]": "moduleReason",
+ "module.modules[]": "module",
+ "module.children[]": "module",
+ "moduleTrace[]": "moduleTraceItem",
+ "moduleTraceItem.dependencies[]": "moduleTraceDependency"
+};
+
+/**
+ * @param {Object[]} items items to be merged
+ * @returns {Object} an object
+ */
+const mergeToObject = items => {
+ const obj = Object.create(null);
+ for (const item of items) {
+ obj[item.name] = item;
+ }
+ return obj;
+};
+
+/** @type {Record<string, (items: Object[]) => any>} */
+const MERGER = {
+ "compilation.entrypoints": mergeToObject,
+ "compilation.namedChunkGroups": mergeToObject
+};
+
+class DefaultStatsFactoryPlugin {
+ /**
+ * Apply the plugin
+ * @param {Compiler} compiler the compiler instance
+ * @returns {void}
+ */
+ apply(compiler) {
+ compiler.hooks.compilation.tap("DefaultStatsFactoryPlugin", compilation => {
+ compilation.hooks.statsFactory.tap(
+ "DefaultStatsFactoryPlugin",
+ (stats, options, context) => {
+ iterateConfig(SIMPLE_EXTRACTORS, options, (hookFor, fn) => {
+ stats.hooks.extract
+ .for(hookFor)
+ .tap("DefaultStatsFactoryPlugin", (obj, data, ctx) =>
+ fn(obj, data, ctx, options, stats)
+ );
+ });
+ iterateConfig(FILTER, options, (hookFor, fn) => {
+ stats.hooks.filter
+ .for(hookFor)
+ .tap("DefaultStatsFactoryPlugin", (item, ctx, idx, i) =>
+ fn(item, ctx, options, idx, i)
+ );
+ });
+ iterateConfig(FILTER_RESULTS, options, (hookFor, fn) => {
+ stats.hooks.filterResults
+ .for(hookFor)
+ .tap("DefaultStatsFactoryPlugin", (item, ctx, idx, i) =>
+ fn(item, ctx, options, idx, i)
+ );
+ });
+ iterateConfig(SORTERS, options, (hookFor, fn) => {
+ stats.hooks.sort
+ .for(hookFor)
+ .tap("DefaultStatsFactoryPlugin", (comparators, ctx) =>
+ fn(comparators, ctx, options)
+ );
+ });
+ iterateConfig(RESULT_SORTERS, options, (hookFor, fn) => {
+ stats.hooks.sortResults
+ .for(hookFor)
+ .tap("DefaultStatsFactoryPlugin", (comparators, ctx) =>
+ fn(comparators, ctx, options)
+ );
+ });
+ iterateConfig(RESULT_GROUPERS, options, (hookFor, fn) => {
+ stats.hooks.groupResults
+ .for(hookFor)
+ .tap("DefaultStatsFactoryPlugin", (groupConfigs, ctx) =>
+ fn(groupConfigs, ctx, options)
+ );
+ });
+ for (const key of Object.keys(ITEM_NAMES)) {
+ const itemName = ITEM_NAMES[key];
+ stats.hooks.getItemName
+ .for(key)
+ .tap("DefaultStatsFactoryPlugin", () => itemName);
+ }
+ for (const key of Object.keys(MERGER)) {
+ const merger = MERGER[key];
+ stats.hooks.merge.for(key).tap("DefaultStatsFactoryPlugin", merger);
+ }
+ if (options.children) {
+ if (Array.isArray(options.children)) {
+ stats.hooks.getItemFactory
+ .for("compilation.children[].compilation")
+ .tap("DefaultStatsFactoryPlugin", (comp, { _index: idx }) => {
+ if (idx < options.children.length) {
+ return compilation.createStatsFactory(
+ compilation.createStatsOptions(
+ options.children[idx],
+ context
+ )
+ );
+ }
+ });
+ } else if (options.children !== true) {
+ const childFactory = compilation.createStatsFactory(
+ compilation.createStatsOptions(options.children, context)
+ );
+ stats.hooks.getItemFactory
+ .for("compilation.children[].compilation")
+ .tap("DefaultStatsFactoryPlugin", () => {
+ return childFactory;
+ });
+ }
+ }
+ }
+ );
+ });
+ }
+}
+module.exports = DefaultStatsFactoryPlugin;
diff --git a/node_modules/webpack/lib/stats/DefaultStatsPresetPlugin.js b/node_modules/webpack/lib/stats/DefaultStatsPresetPlugin.js
new file mode 100644
index 00000000..77795dcb
--- /dev/null
+++ b/node_modules/webpack/lib/stats/DefaultStatsPresetPlugin.js
@@ -0,0 +1,335 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const RequestShortener = require("../RequestShortener");
+
+/** @typedef {import("../../declarations/WebpackOptions").StatsOptions} StatsOptions */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Compilation").CreateStatsOptionsContext} CreateStatsOptionsContext */
+/** @typedef {import("../Compiler")} Compiler */
+
+const applyDefaults = (options, defaults) => {
+ for (const key of Object.keys(defaults)) {
+ if (typeof options[key] === "undefined") {
+ options[key] = defaults[key];
+ }
+ }
+};
+
+const NAMED_PRESETS = {
+ verbose: {
+ hash: true,
+ builtAt: true,
+ relatedAssets: true,
+ entrypoints: true,
+ chunkGroups: true,
+ ids: true,
+ modules: false,
+ chunks: true,
+ chunkRelations: true,
+ chunkModules: true,
+ dependentModules: true,
+ chunkOrigins: true,
+ depth: true,
+ env: true,
+ reasons: true,
+ usedExports: true,
+ providedExports: true,
+ optimizationBailout: true,
+ errorDetails: true,
+ errorStack: true,
+ publicPath: true,
+ logging: "verbose",
+ orphanModules: true,
+ runtimeModules: true,
+ exclude: false,
+ errorsSpace: Infinity,
+ warningsSpace: Infinity,
+ modulesSpace: Infinity,
+ chunkModulesSpace: Infinity,
+ assetsSpace: Infinity,
+ reasonsSpace: Infinity,
+ children: true
+ },
+ detailed: {
+ hash: true,
+ builtAt: true,
+ relatedAssets: true,
+ entrypoints: true,
+ chunkGroups: true,
+ ids: true,
+ chunks: true,
+ chunkRelations: true,
+ chunkModules: false,
+ chunkOrigins: true,
+ depth: true,
+ usedExports: true,
+ providedExports: true,
+ optimizationBailout: true,
+ errorDetails: true,
+ publicPath: true,
+ logging: true,
+ runtimeModules: true,
+ exclude: false,
+ errorsSpace: 1000,
+ warningsSpace: 1000,
+ modulesSpace: 1000,
+ assetsSpace: 1000,
+ reasonsSpace: 1000
+ },
+ minimal: {
+ all: false,
+ version: true,
+ timings: true,
+ modules: true,
+ errorsSpace: 0,
+ warningsSpace: 0,
+ modulesSpace: 0,
+ assets: true,
+ assetsSpace: 0,
+ errors: true,
+ errorsCount: true,
+ warnings: true,
+ warningsCount: true,
+ logging: "warn"
+ },
+ "errors-only": {
+ all: false,
+ errors: true,
+ errorsCount: true,
+ errorsSpace: Infinity,
+ moduleTrace: true,
+ logging: "error"
+ },
+ "errors-warnings": {
+ all: false,
+ errors: true,
+ errorsCount: true,
+ errorsSpace: Infinity,
+ warnings: true,
+ warningsCount: true,
+ warningsSpace: Infinity,
+ logging: "warn"
+ },
+ summary: {
+ all: false,
+ version: true,
+ errorsCount: true,
+ warningsCount: true
+ },
+ none: {
+ all: false
+ }
+};
+
+const NORMAL_ON = ({ all }) => all !== false;
+const NORMAL_OFF = ({ all }) => all === true;
+const ON_FOR_TO_STRING = ({ all }, { forToString }) =>
+ forToString ? all !== false : all === true;
+const OFF_FOR_TO_STRING = ({ all }, { forToString }) =>
+ forToString ? all === true : all !== false;
+const AUTO_FOR_TO_STRING = ({ all }, { forToString }) => {
+ if (all === false) return false;
+ if (all === true) return true;
+ if (forToString) return "auto";
+ return true;
+};
+
+/** @type {Record<string, (options: StatsOptions, context: CreateStatsOptionsContext, compilation: Compilation) => any>} */
+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),
+ performance: NORMAL_ON,
+ hash: OFF_FOR_TO_STRING,
+ env: NORMAL_OFF,
+ version: NORMAL_ON,
+ timings: NORMAL_ON,
+ builtAt: OFF_FOR_TO_STRING,
+ assets: NORMAL_ON,
+ entrypoints: AUTO_FOR_TO_STRING,
+ chunkGroups: OFF_FOR_TO_STRING,
+ chunkGroupAuxiliary: OFF_FOR_TO_STRING,
+ chunkGroupChildren: OFF_FOR_TO_STRING,
+ chunkGroupMaxAssets: (o, { forToString }) => (forToString ? 5 : Infinity),
+ chunks: OFF_FOR_TO_STRING,
+ chunkRelations: OFF_FOR_TO_STRING,
+ chunkModules: ({ all, modules }) => {
+ if (all === false) return false;
+ if (all === true) return true;
+ if (modules) return false;
+ return true;
+ },
+ dependentModules: OFF_FOR_TO_STRING,
+ chunkOrigins: OFF_FOR_TO_STRING,
+ ids: OFF_FOR_TO_STRING,
+ modules: ({ all, chunks, chunkModules }, { forToString }) => {
+ if (all === false) return false;
+ if (all === true) return true;
+ if (forToString && chunks && chunkModules) return false;
+ return true;
+ },
+ nestedModules: OFF_FOR_TO_STRING,
+ groupModulesByType: ON_FOR_TO_STRING,
+ groupModulesByCacheStatus: ON_FOR_TO_STRING,
+ groupModulesByLayer: ON_FOR_TO_STRING,
+ groupModulesByAttributes: ON_FOR_TO_STRING,
+ groupModulesByPath: ON_FOR_TO_STRING,
+ groupModulesByExtension: ON_FOR_TO_STRING,
+ modulesSpace: (o, { forToString }) => (forToString ? 15 : Infinity),
+ chunkModulesSpace: (o, { forToString }) => (forToString ? 10 : Infinity),
+ nestedModulesSpace: (o, { forToString }) => (forToString ? 10 : Infinity),
+ relatedAssets: OFF_FOR_TO_STRING,
+ groupAssetsByEmitStatus: ON_FOR_TO_STRING,
+ groupAssetsByInfo: ON_FOR_TO_STRING,
+ groupAssetsByPath: ON_FOR_TO_STRING,
+ groupAssetsByExtension: ON_FOR_TO_STRING,
+ groupAssetsByChunk: ON_FOR_TO_STRING,
+ assetsSpace: (o, { forToString }) => (forToString ? 15 : Infinity),
+ orphanModules: OFF_FOR_TO_STRING,
+ runtimeModules: ({ all, runtime }, { forToString }) =>
+ runtime !== undefined
+ ? runtime
+ : forToString
+ ? all === true
+ : all !== false,
+ cachedModules: ({ all, cached }, { forToString }) =>
+ cached !== undefined ? cached : forToString ? all === true : all !== false,
+ moduleAssets: OFF_FOR_TO_STRING,
+ depth: OFF_FOR_TO_STRING,
+ cachedAssets: OFF_FOR_TO_STRING,
+ reasons: OFF_FOR_TO_STRING,
+ reasonsSpace: (o, { forToString }) => (forToString ? 15 : Infinity),
+ groupReasonsByOrigin: ON_FOR_TO_STRING,
+ usedExports: OFF_FOR_TO_STRING,
+ providedExports: OFF_FOR_TO_STRING,
+ optimizationBailout: OFF_FOR_TO_STRING,
+ children: OFF_FOR_TO_STRING,
+ source: NORMAL_OFF,
+ moduleTrace: NORMAL_ON,
+ errors: NORMAL_ON,
+ errorsCount: NORMAL_ON,
+ errorDetails: AUTO_FOR_TO_STRING,
+ errorStack: OFF_FOR_TO_STRING,
+ warnings: NORMAL_ON,
+ warningsCount: NORMAL_ON,
+ publicPath: OFF_FOR_TO_STRING,
+ logging: ({ all }, { forToString }) =>
+ forToString && all !== false ? "info" : false,
+ loggingDebug: () => [],
+ loggingTrace: OFF_FOR_TO_STRING,
+ excludeModules: () => [],
+ excludeAssets: () => [],
+ modulesSort: () => "depth",
+ chunkModulesSort: () => "name",
+ nestedModulesSort: () => false,
+ chunksSort: () => false,
+ assetsSort: () => "!size",
+ outputPath: OFF_FOR_TO_STRING,
+ colors: () => false
+};
+
+const normalizeFilter = item => {
+ if (typeof item === "string") {
+ const regExp = new RegExp(
+ `[\\\\/]${item.replace(
+ // eslint-disable-next-line no-useless-escape
+ /[-[\]{}()*+?.\\^$|]/g,
+ "\\$&"
+ )}([\\\\/]|$|!|\\?)`
+ );
+ return ident => regExp.test(ident);
+ }
+ if (item && typeof item === "object" && typeof item.test === "function") {
+ return ident => item.test(ident);
+ }
+ if (typeof item === "function") {
+ return item;
+ }
+ if (typeof item === "boolean") {
+ return () => item;
+ }
+};
+
+const NORMALIZER = {
+ excludeModules: value => {
+ if (!Array.isArray(value)) {
+ value = value ? [value] : [];
+ }
+ return value.map(normalizeFilter);
+ },
+ excludeAssets: value => {
+ if (!Array.isArray(value)) {
+ value = value ? [value] : [];
+ }
+ return value.map(normalizeFilter);
+ },
+ warningsFilter: value => {
+ if (!Array.isArray(value)) {
+ value = value ? [value] : [];
+ }
+ return value.map(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})`
+ );
+ });
+ },
+ logging: value => {
+ if (value === true) value = "log";
+ return value;
+ },
+ loggingDebug: value => {
+ if (!Array.isArray(value)) {
+ value = value ? [value] : [];
+ }
+ return value.map(normalizeFilter);
+ }
+};
+
+class DefaultStatsPresetPlugin {
+ /**
+ * Apply the plugin
+ * @param {Compiler} compiler the compiler instance
+ * @returns {void}
+ */
+ apply(compiler) {
+ compiler.hooks.compilation.tap("DefaultStatsPresetPlugin", compilation => {
+ for (const key of Object.keys(NAMED_PRESETS)) {
+ const defaults = NAMED_PRESETS[key];
+ compilation.hooks.statsPreset
+ .for(key)
+ .tap("DefaultStatsPresetPlugin", (options, context) => {
+ applyDefaults(options, defaults);
+ });
+ }
+ compilation.hooks.statsNormalize.tap(
+ "DefaultStatsPresetPlugin",
+ (options, context) => {
+ for (const key of Object.keys(DEFAULTS)) {
+ if (options[key] === undefined)
+ options[key] = DEFAULTS[key](options, context, compilation);
+ }
+ for (const key of Object.keys(NORMALIZER)) {
+ options[key] = NORMALIZER[key](options[key]);
+ }
+ }
+ );
+ });
+ }
+}
+module.exports = DefaultStatsPresetPlugin;
diff --git a/node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js b/node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js
new file mode 100644
index 00000000..20b19adc
--- /dev/null
+++ b/node_modules/webpack/lib/stats/DefaultStatsPrinterPlugin.js
@@ -0,0 +1,1423 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+/** @typedef {import("../Compiler")} Compiler */
+/** @typedef {import("./StatsPrinter")} StatsPrinter */
+/** @typedef {import("./StatsPrinter").StatsPrinterContext} StatsPrinterContext */
+
+const DATA_URI_CONTENT_LENGTH = 16;
+const MAX_MODULE_IDENTIFIER_LENGTH = 80;
+
+/**
+ * @param {number} n a number
+ * @param {string} singular singular
+ * @param {string} plural plural
+ * @returns {string} if n is 1, singular, else plural
+ */
+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
+ */
+const printSizes = (sizes, { formatSize = n => `${n}` }) => {
+ const keys = Object.keys(sizes);
+ if (keys.length > 1) {
+ return keys.map(key => `${formatSize(sizes[key])} (${key})`).join(" ");
+ } else if (keys.length === 1) {
+ return formatSize(sizes[keys[0]]);
+ }
+};
+
+/**
+ * @param {string} resource resource
+ * @returns {string} resource name for display
+ */
+const getResourceName = resource => {
+ const dataUrl = /^data:[^,]+,/.exec(resource);
+ if (!dataUrl) return resource;
+
+ const len = dataUrl[0].length + DATA_URI_CONTENT_LENGTH;
+ if (resource.length < len) return resource;
+ return `${resource.slice(
+ 0,
+ Math.min(resource.length - /* '..'.length */ 2, len)
+ )}..`;
+};
+
+/**
+ * @param {string} name module name
+ * @returns {[string,string]} prefix and module name
+ */
+const getModuleName = name => {
+ const [, prefix, resource] = /^(.*!)?([^!]*)$/.exec(name);
+
+ if (resource.length > MAX_MODULE_IDENTIFIER_LENGTH) {
+ const truncatedResource = `${resource.slice(
+ 0,
+ Math.min(
+ resource.length - /* '...(truncated)'.length */ 14,
+ MAX_MODULE_IDENTIFIER_LENGTH
+ )
+ )}...(truncated)`;
+
+ return [prefix, getResourceName(truncatedResource)];
+ }
+
+ return [prefix, getResourceName(resource)];
+};
+
+/**
+ * @param {string} str string
+ * @param {function(string): string} fn function to apply to each line
+ * @returns {string} joined string
+ */
+const mapLines = (str, fn) => str.split("\n").map(fn).join("\n");
+
+/**
+ * @param {number} n a number
+ * @returns {string} number as two digit string, leading 0
+ */
+const twoDigit = n => (n >= 10 ? `${n}` : `0${n}`);
+
+const isValidId = id => {
+ return typeof id === "number" || id;
+};
+
+/**
+ * @template T
+ * @param {Array<T>} 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}`;
+};
+
+/** @type {Record<string, (thing: any, context: StatsPrinterContext, printer: StatsPrinter) => string | void>} */
+const SIMPLE_PRINTERS = {
+ "compilation.summary!": (
+ _,
+ {
+ type,
+ bold,
+ green,
+ red,
+ yellow,
+ formatDateTime,
+ formatTime,
+ compilation: {
+ name,
+ hash,
+ version,
+ time,
+ builtAt,
+ errorsCount,
+ warningsCount
+ }
+ }
+ ) => {
+ const root = type === "compilation.summary!";
+ const warningsMessage =
+ warningsCount > 0
+ ? yellow(
+ `${warningsCount} ${plural(warningsCount, "warning", "warnings")}`
+ )
+ : "";
+ const errorsMessage =
+ errorsCount > 0
+ ? red(`${errorsCount} ${plural(errorsCount, "error", "errors")}`)
+ : "";
+ const timeMessage = root && time ? ` in ${formatTime(time)}` : "";
+ const hashMessage = hash ? ` (${hash})` : "";
+ const builtAtMessage =
+ root && builtAt ? `${formatDateTime(builtAt)}: ` : "";
+ const versionMessage = root && version ? `webpack ${version}` : "";
+ const nameMessage =
+ root && name
+ ? bold(name)
+ : name
+ ? `Child ${bold(name)}`
+ : root
+ ? ""
+ : "Child";
+ const subjectMessage =
+ nameMessage && versionMessage
+ ? `${nameMessage} (${versionMessage})`
+ : versionMessage || nameMessage || "webpack";
+ let statusMessage;
+ if (errorsMessage && warningsMessage) {
+ statusMessage = `compiled with ${errorsMessage} and ${warningsMessage}`;
+ } else if (errorsMessage) {
+ statusMessage = `compiled with ${errorsMessage}`;
+ } else if (warningsMessage) {
+ statusMessage = `compiled with ${warningsMessage}`;
+ } else if (errorsCount === 0 && warningsCount === 0) {
+ statusMessage = `compiled ${green("successfully")}`;
+ } else {
+ statusMessage = `compiled`;
+ }
+ if (
+ builtAtMessage ||
+ versionMessage ||
+ errorsMessage ||
+ warningsMessage ||
+ (errorsCount === 0 && warningsCount === 0) ||
+ timeMessage ||
+ hashMessage
+ )
+ return `${builtAtMessage}${subjectMessage} ${statusMessage}${timeMessage}${hashMessage}`;
+ },
+ "compilation.filteredWarningDetailsCount": count =>
+ count
+ ? `${count} ${plural(
+ count,
+ "warning has",
+ "warnings have"
+ )} detailed information that is not shown.\nUse 'stats.errorDetails: true' resp. '--stats-error-details' to show it.`
+ : undefined,
+ "compilation.filteredErrorDetailsCount": (count, { yellow }) =>
+ count
+ ? yellow(
+ `${count} ${plural(
+ count,
+ "error has",
+ "errors have"
+ )} detailed information that is not shown.\nUse 'stats.errorDetails: true' resp. '--stats-error-details' to show it.`
+ )
+ : undefined,
+ "compilation.env": (env, { bold }) =>
+ env
+ ? `Environment (--env): ${bold(JSON.stringify(env, null, 2))}`
+ : undefined,
+ "compilation.publicPath": (publicPath, { bold }) =>
+ `PublicPath: ${bold(publicPath || "(none)")}`,
+ "compilation.entrypoints": (entrypoints, context, printer) =>
+ Array.isArray(entrypoints)
+ ? undefined
+ : printer.print(context.type, Object.values(entrypoints), {
+ ...context,
+ chunkGroupKind: "Entrypoint"
+ }),
+ "compilation.namedChunkGroups": (namedChunkGroups, context, printer) => {
+ if (!Array.isArray(namedChunkGroups)) {
+ const {
+ compilation: { entrypoints }
+ } = context;
+ let chunkGroups = Object.values(namedChunkGroups);
+ if (entrypoints) {
+ chunkGroups = chunkGroups.filter(
+ group =>
+ !Object.prototype.hasOwnProperty.call(entrypoints, group.name)
+ );
+ }
+ return printer.print(context.type, chunkGroups, {
+ ...context,
+ chunkGroupKind: "Chunk Group"
+ });
+ }
+ },
+ "compilation.assetsByChunkName": () => "",
+
+ "compilation.filteredModules": (
+ filteredModules,
+ { compilation: { modules } }
+ ) =>
+ filteredModules > 0
+ ? `${moreCount(modules, filteredModules)} ${plural(
+ filteredModules,
+ "module",
+ "modules"
+ )}`
+ : undefined,
+ "compilation.filteredAssets": (filteredAssets, { compilation: { assets } }) =>
+ filteredAssets > 0
+ ? `${moreCount(assets, filteredAssets)} ${plural(
+ filteredAssets,
+ "asset",
+ "assets"
+ )}`
+ : undefined,
+ "compilation.logging": (logging, context, printer) =>
+ Array.isArray(logging)
+ ? undefined
+ : printer.print(
+ context.type,
+ Object.entries(logging).map(([name, value]) => ({ ...value, name })),
+ context
+ ),
+ "compilation.warningsInChildren!": (_, { yellow, compilation }) => {
+ if (
+ !compilation.children &&
+ compilation.warningsCount > 0 &&
+ compilation.warnings
+ ) {
+ const childWarnings =
+ compilation.warningsCount - compilation.warnings.length;
+ if (childWarnings > 0) {
+ return yellow(
+ `${childWarnings} ${plural(
+ childWarnings,
+ "WARNING",
+ "WARNINGS"
+ )} in child compilations${
+ compilation.children
+ ? ""
+ : " (Use 'stats.children: true' resp. '--stats-children' for more details)"
+ }`
+ );
+ }
+ }
+ },
+ "compilation.errorsInChildren!": (_, { red, compilation }) => {
+ if (
+ !compilation.children &&
+ compilation.errorsCount > 0 &&
+ compilation.errors
+ ) {
+ const childErrors = compilation.errorsCount - compilation.errors.length;
+ if (childErrors > 0) {
+ return red(
+ `${childErrors} ${plural(
+ childErrors,
+ "ERROR",
+ "ERRORS"
+ )} in child compilations${
+ compilation.children
+ ? ""
+ : " (Use 'stats.children: true' resp. '--stats-children' for more details)"
+ }`
+ );
+ }
+ }
+ },
+
+ "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.emitted": (emitted, { green, formatFlag }) =>
+ emitted ? green(formatFlag("emitted")) : undefined,
+ "asset.comparedForEmit": (comparedForEmit, { yellow, formatFlag }) =>
+ comparedForEmit ? yellow(formatFlag("compared for emit")) : undefined,
+ "asset.cached": (cached, { green, formatFlag }) =>
+ cached ? green(formatFlag("cached")) : undefined,
+ "asset.isOverSizeLimit": (isOverSizeLimit, { yellow, formatFlag }) =>
+ isOverSizeLimit ? yellow(formatFlag("big")) : undefined,
+
+ "asset.info.immutable": (immutable, { green, formatFlag }) =>
+ immutable ? green(formatFlag("immutable")) : undefined,
+ "asset.info.javascriptModule": (javascriptModule, { formatFlag }) =>
+ javascriptModule ? formatFlag("javascript module") : undefined,
+ "asset.info.sourceFilename": (sourceFilename, { formatFlag }) =>
+ sourceFilename
+ ? formatFlag(
+ sourceFilename === true
+ ? "from source file"
+ : `from: ${sourceFilename}`
+ )
+ : undefined,
+ "asset.info.development": (development, { green, formatFlag }) =>
+ development ? green(formatFlag("dev")) : undefined,
+ "asset.info.hotModuleReplacement": (
+ hotModuleReplacement,
+ { green, formatFlag }
+ ) => (hotModuleReplacement ? green(formatFlag("hmr")) : undefined),
+ "asset.separator!": () => "\n",
+ "asset.filteredRelated": (filteredRelated, { asset: { related } }) =>
+ filteredRelated > 0
+ ? `${moreCount(related, filteredRelated)} related ${plural(
+ filteredRelated,
+ "asset",
+ "assets"
+ )}`
+ : undefined,
+ "asset.filteredChildren": (filteredChildren, { asset: { children } }) =>
+ filteredChildren > 0
+ ? `${moreCount(children, filteredChildren)} ${plural(
+ filteredChildren,
+ "asset",
+ "assets"
+ )}`
+ : undefined,
+
+ assetChunk: (id, { formatChunkId }) => formatChunkId(id),
+
+ assetChunkName: name => name,
+ assetChunkIdHint: name => name,
+
+ "module.type": type => (type !== "module" ? type : undefined),
+ "module.id": (id, { formatModuleId }) =>
+ isValidId(id) ? formatModuleId(id) : undefined,
+ "module.name": (name, { bold }) => {
+ const [prefix, resource] = getModuleName(name);
+ return `${prefix || ""}${bold(resource || "")}`;
+ },
+ "module.identifier": identifier => undefined,
+ "module.layer": (layer, { formatLayer }) =>
+ layer ? formatLayer(layer) : undefined,
+ "module.sizes": printSizes,
+ "module.chunks[]": (id, { formatChunkId }) => formatChunkId(id),
+ "module.depth": (depth, { formatFlag }) =>
+ depth !== null ? formatFlag(`depth ${depth}`) : undefined,
+ "module.cacheable": (cacheable, { formatFlag, red }) =>
+ cacheable === false ? red(formatFlag("not cacheable")) : undefined,
+ "module.orphan": (orphan, { formatFlag, yellow }) =>
+ orphan ? yellow(formatFlag("orphan")) : undefined,
+ "module.runtime": (runtime, { formatFlag, yellow }) =>
+ runtime ? yellow(formatFlag("runtime")) : undefined,
+ "module.optional": (optional, { formatFlag, yellow }) =>
+ optional ? yellow(formatFlag("optional")) : undefined,
+ "module.dependent": (dependent, { formatFlag, cyan }) =>
+ dependent ? cyan(formatFlag("dependent")) : undefined,
+ "module.built": (built, { formatFlag, yellow }) =>
+ built ? yellow(formatFlag("built")) : undefined,
+ "module.codeGenerated": (codeGenerated, { formatFlag, yellow }) =>
+ codeGenerated ? yellow(formatFlag("code generated")) : undefined,
+ "module.buildTimeExecuted": (buildTimeExecuted, { formatFlag, green }) =>
+ buildTimeExecuted ? green(formatFlag("build time executed")) : undefined,
+ "module.cached": (cached, { formatFlag, green }) =>
+ cached ? green(formatFlag("cached")) : undefined,
+ "module.assets": (assets, { formatFlag, magenta }) =>
+ assets && assets.length
+ ? magenta(
+ formatFlag(
+ `${assets.length} ${plural(assets.length, "asset", "assets")}`
+ )
+ )
+ : undefined,
+ "module.warnings": (warnings, { formatFlag, yellow }) =>
+ warnings === true
+ ? yellow(formatFlag("warnings"))
+ : warnings
+ ? yellow(
+ formatFlag(`${warnings} ${plural(warnings, "warning", "warnings")}`)
+ )
+ : undefined,
+ "module.errors": (errors, { formatFlag, red }) =>
+ errors === true
+ ? red(formatFlag("errors"))
+ : errors
+ ? red(formatFlag(`${errors} ${plural(errors, "error", "errors")}`))
+ : undefined,
+ "module.providedExports": (providedExports, { formatFlag, cyan }) => {
+ if (Array.isArray(providedExports)) {
+ if (providedExports.length === 0) return cyan(formatFlag("no exports"));
+ return cyan(formatFlag(`exports: ${providedExports.join(", ")}`));
+ }
+ },
+ "module.usedExports": (usedExports, { formatFlag, cyan, module }) => {
+ if (usedExports !== true) {
+ if (usedExports === null) return cyan(formatFlag("used exports unknown"));
+ if (usedExports === false) return cyan(formatFlag("module unused"));
+ if (Array.isArray(usedExports)) {
+ if (usedExports.length === 0)
+ return cyan(formatFlag("no exports used"));
+ const providedExportsCount = Array.isArray(module.providedExports)
+ ? module.providedExports.length
+ : null;
+ if (
+ providedExportsCount !== null &&
+ providedExportsCount === usedExports.length
+ ) {
+ return cyan(formatFlag("all exports used"));
+ } else {
+ return cyan(
+ formatFlag(`only some exports used: ${usedExports.join(", ")}`)
+ );
+ }
+ }
+ }
+ },
+ "module.optimizationBailout[]": (optimizationBailout, { yellow }) =>
+ yellow(optimizationBailout),
+ "module.issuerPath": (issuerPath, { module }) =>
+ module.profile ? undefined : "",
+ "module.profile": profile => undefined,
+ "module.filteredModules": (filteredModules, { module: { modules } }) =>
+ filteredModules > 0
+ ? `${moreCount(modules, filteredModules)} nested ${plural(
+ filteredModules,
+ "module",
+ "modules"
+ )}`
+ : undefined,
+ "module.filteredReasons": (filteredReasons, { module: { reasons } }) =>
+ filteredReasons > 0
+ ? `${moreCount(reasons, filteredReasons)} ${plural(
+ filteredReasons,
+ "reason",
+ "reasons"
+ )}`
+ : undefined,
+ "module.filteredChildren": (filteredChildren, { module: { children } }) =>
+ filteredChildren > 0
+ ? `${moreCount(children, filteredChildren)} ${plural(
+ filteredChildren,
+ "module",
+ "modules"
+ )}`
+ : undefined,
+ "module.separator!": () => "\n",
+
+ "moduleIssuer.id": (id, { formatModuleId }) => formatModuleId(id),
+ "moduleIssuer.profile.total": (value, { formatTime }) => formatTime(value),
+
+ "moduleReason.type": type => type,
+ "moduleReason.userRequest": (userRequest, { cyan }) =>
+ cyan(getResourceName(userRequest)),
+ "moduleReason.moduleId": (moduleId, { formatModuleId }) =>
+ isValidId(moduleId) ? formatModuleId(moduleId) : undefined,
+ "moduleReason.module": (module, { magenta }) => magenta(module),
+ "moduleReason.loc": loc => loc,
+ "moduleReason.explanation": (explanation, { cyan }) => cyan(explanation),
+ "moduleReason.active": (active, { formatFlag }) =>
+ active ? undefined : formatFlag("inactive"),
+ "moduleReason.resolvedModule": (module, { magenta }) => magenta(module),
+ "moduleReason.filteredChildren": (
+ filteredChildren,
+ { moduleReason: { children } }
+ ) =>
+ filteredChildren > 0
+ ? `${moreCount(children, filteredChildren)} ${plural(
+ filteredChildren,
+ "reason",
+ "reasons"
+ )}`
+ : undefined,
+
+ "module.profile.total": (value, { formatTime }) => formatTime(value),
+ "module.profile.resolving": (value, { formatTime }) =>
+ `resolving: ${formatTime(value)}`,
+ "module.profile.restoring": (value, { formatTime }) =>
+ `restoring: ${formatTime(value)}`,
+ "module.profile.integration": (value, { formatTime }) =>
+ `integration: ${formatTime(value)}`,
+ "module.profile.building": (value, { formatTime }) =>
+ `building: ${formatTime(value)}`,
+ "module.profile.storing": (value, { formatTime }) =>
+ `storing: ${formatTime(value)}`,
+ "module.profile.additionalResolving": (value, { formatTime }) =>
+ value ? `additional resolving: ${formatTime(value)}` : undefined,
+ "module.profile.additionalIntegration": (value, { formatTime }) =>
+ value ? `additional integration: ${formatTime(value)}` : undefined,
+
+ "chunkGroup.kind!": (_, { chunkGroupKind }) => chunkGroupKind,
+ "chunkGroup.separator!": () => "\n",
+ "chunkGroup.name": (name, { bold }) => bold(name),
+ "chunkGroup.isOverSizeLimit": (isOverSizeLimit, { formatFlag, yellow }) =>
+ isOverSizeLimit ? yellow(formatFlag("big")) : undefined,
+ "chunkGroup.assetsSize": (size, { formatSize }) =>
+ size ? formatSize(size) : undefined,
+ "chunkGroup.auxiliaryAssetsSize": (size, { formatSize }) =>
+ size ? `(${formatSize(size)})` : undefined,
+ "chunkGroup.filteredAssets": (n, { chunkGroup: { assets } }) =>
+ n > 0
+ ? `${moreCount(assets, n)} ${plural(n, "asset", "assets")}`
+ : undefined,
+ "chunkGroup.filteredAuxiliaryAssets": (
+ n,
+ { chunkGroup: { auxiliaryAssets } }
+ ) =>
+ n > 0
+ ? `${moreCount(auxiliaryAssets, n)} auxiliary ${plural(
+ n,
+ "asset",
+ "assets"
+ )}`
+ : undefined,
+ "chunkGroup.is!": () => "=",
+ "chunkGroupAsset.name": (asset, { green }) => green(asset),
+ "chunkGroupAsset.size": (size, { formatSize, chunkGroup }) =>
+ chunkGroup.assets.length > 1 ||
+ (chunkGroup.auxiliaryAssets && chunkGroup.auxiliaryAssets.length > 0)
+ ? formatSize(size)
+ : undefined,
+ "chunkGroup.children": (children, context, printer) =>
+ Array.isArray(children)
+ ? undefined
+ : printer.print(
+ context.type,
+ Object.keys(children).map(key => ({
+ type: key,
+ children: children[key]
+ })),
+ context
+ ),
+ "chunkGroupChildGroup.type": type => `${type}:`,
+ "chunkGroupChild.assets[]": (file, { formatFilename }) =>
+ formatFilename(file),
+ "chunkGroupChild.chunks[]": (id, { formatChunkId }) => formatChunkId(id),
+ "chunkGroupChild.name": name => (name ? `(name: ${name})` : undefined),
+
+ "chunk.id": (id, { formatChunkId }) => formatChunkId(id),
+ "chunk.files[]": (file, { formatFilename }) => formatFilename(file),
+ "chunk.names[]": name => name,
+ "chunk.idHints[]": name => name,
+ "chunk.runtime[]": name => name,
+ "chunk.sizes": (sizes, context) => printSizes(sizes, context),
+ "chunk.parents[]": (parents, context) =>
+ context.formatChunkId(parents, "parent"),
+ "chunk.siblings[]": (siblings, context) =>
+ context.formatChunkId(siblings, "sibling"),
+ "chunk.children[]": (children, context) =>
+ context.formatChunkId(children, "child"),
+ "chunk.childrenByOrder": (childrenByOrder, context, printer) =>
+ Array.isArray(childrenByOrder)
+ ? undefined
+ : printer.print(
+ context.type,
+ Object.keys(childrenByOrder).map(key => ({
+ type: key,
+ children: childrenByOrder[key]
+ })),
+ context
+ ),
+ "chunk.childrenByOrder[].type": type => `${type}:`,
+ "chunk.childrenByOrder[].children[]": (id, { formatChunkId }) =>
+ isValidId(id) ? formatChunkId(id) : undefined,
+ "chunk.entry": (entry, { formatFlag, yellow }) =>
+ entry ? yellow(formatFlag("entry")) : undefined,
+ "chunk.initial": (initial, { formatFlag, yellow }) =>
+ initial ? yellow(formatFlag("initial")) : undefined,
+ "chunk.rendered": (rendered, { formatFlag, green }) =>
+ rendered ? green(formatFlag("rendered")) : undefined,
+ "chunk.recorded": (recorded, { formatFlag, green }) =>
+ recorded ? green(formatFlag("recorded")) : undefined,
+ "chunk.reason": (reason, { yellow }) => (reason ? yellow(reason) : undefined),
+ "chunk.filteredModules": (filteredModules, { chunk: { modules } }) =>
+ filteredModules > 0
+ ? `${moreCount(modules, filteredModules)} chunk ${plural(
+ filteredModules,
+ "module",
+ "modules"
+ )}`
+ : undefined,
+ "chunk.separator!": () => "\n",
+
+ "chunkOrigin.request": request => request,
+ "chunkOrigin.moduleId": (moduleId, { formatModuleId }) =>
+ isValidId(moduleId) ? formatModuleId(moduleId) : undefined,
+ "chunkOrigin.moduleName": (moduleName, { bold }) => bold(moduleName),
+ "chunkOrigin.loc": loc => loc,
+
+ "error.compilerPath": (compilerPath, { bold }) =>
+ compilerPath ? bold(`(${compilerPath})`) : undefined,
+ "error.chunkId": (chunkId, { formatChunkId }) =>
+ isValidId(chunkId) ? formatChunkId(chunkId) : undefined,
+ "error.chunkEntry": (chunkEntry, { formatFlag }) =>
+ chunkEntry ? formatFlag("entry") : undefined,
+ "error.chunkInitial": (chunkInitial, { formatFlag }) =>
+ chunkInitial ? formatFlag("initial") : undefined,
+ "error.file": (file, { bold }) => bold(file),
+ "error.moduleName": (moduleName, { bold }) => {
+ return moduleName.includes("!")
+ ? `${bold(moduleName.replace(/^(\s|\S)*!/, ""))} (${moduleName})`
+ : `${bold(moduleName)}`;
+ },
+ "error.loc": (loc, { green }) => green(loc),
+ "error.message": (message, { bold, formatError }) =>
+ 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",
+
+ "loggingEntry(error).loggingEntry.message": (message, { red }) =>
+ mapLines(message, x => `<e> ${red(x)}`),
+ "loggingEntry(warn).loggingEntry.message": (message, { yellow }) =>
+ mapLines(message, x => `<w> ${yellow(x)}`),
+ "loggingEntry(info).loggingEntry.message": (message, { green }) =>
+ mapLines(message, x => `<i> ${green(x)}`),
+ "loggingEntry(log).loggingEntry.message": (message, { bold }) =>
+ mapLines(message, x => ` ${bold(x)}`),
+ "loggingEntry(debug).loggingEntry.message": message =>
+ mapLines(message, x => ` ${x}`),
+ "loggingEntry(trace).loggingEntry.message": message =>
+ mapLines(message, x => ` ${x}`),
+ "loggingEntry(status).loggingEntry.message": (message, { magenta }) =>
+ mapLines(message, x => `<s> ${magenta(x)}`),
+ "loggingEntry(profile).loggingEntry.message": (message, { magenta }) =>
+ mapLines(message, x => `<p> ${magenta(x)}`),
+ "loggingEntry(profileEnd).loggingEntry.message": (message, { magenta }) =>
+ mapLines(message, x => `</p> ${magenta(x)}`),
+ "loggingEntry(time).loggingEntry.message": (message, { magenta }) =>
+ mapLines(message, x => `<t> ${magenta(x)}`),
+ "loggingEntry(group).loggingEntry.message": (message, { cyan }) =>
+ mapLines(message, x => `<-> ${cyan(x)}`),
+ "loggingEntry(groupCollapsed).loggingEntry.message": (message, { cyan }) =>
+ mapLines(message, x => `<+> ${cyan(x)}`),
+ "loggingEntry(clear).loggingEntry": () => " -------",
+ "loggingEntry(groupCollapsed).loggingEntry.children": () => "",
+ "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,
+
+ "moduleTraceDependency.loc": loc => loc
+};
+
+/** @type {Record<string, string | Function>} */
+const ITEM_NAMES = {
+ "compilation.assets[]": "asset",
+ "compilation.modules[]": "module",
+ "compilation.chunks[]": "chunk",
+ "compilation.entrypoints[]": "chunkGroup",
+ "compilation.namedChunkGroups[]": "chunkGroup",
+ "compilation.errors[]": "error",
+ "compilation.warnings[]": "error",
+ "compilation.logging[]": "loggingGroup",
+ "compilation.children[]": "compilation",
+ "asset.related[]": "asset",
+ "asset.children[]": "asset",
+ "asset.chunks[]": "assetChunk",
+ "asset.auxiliaryChunks[]": "assetChunk",
+ "asset.chunkNames[]": "assetChunkName",
+ "asset.chunkIdHints[]": "assetChunkIdHint",
+ "asset.auxiliaryChunkNames[]": "assetChunkName",
+ "asset.auxiliaryChunkIdHints[]": "assetChunkIdHint",
+ "chunkGroup.assets[]": "chunkGroupAsset",
+ "chunkGroup.auxiliaryAssets[]": "chunkGroupAsset",
+ "chunkGroupChild.assets[]": "chunkGroupAsset",
+ "chunkGroupChild.auxiliaryAssets[]": "chunkGroupAsset",
+ "chunkGroup.children[]": "chunkGroupChildGroup",
+ "chunkGroupChildGroup.children[]": "chunkGroupChild",
+ "module.modules[]": "module",
+ "module.children[]": "module",
+ "module.reasons[]": "moduleReason",
+ "moduleReason.children[]": "moduleReason",
+ "module.issuerPath[]": "moduleIssuer",
+ "chunk.origins[]": "chunkOrigin",
+ "chunk.modules[]": "module",
+ "loggingGroup.entries[]": logEntry =>
+ `loggingEntry(${logEntry.type}).loggingEntry`,
+ "loggingEntry.children[]": logEntry =>
+ `loggingEntry(${logEntry.type}).loggingEntry`,
+ "error.moduleTrace[]": "moduleTraceItem",
+ "moduleTraceItem.dependencies[]": "moduleTraceDependency"
+};
+
+const ERROR_PREFERRED_ORDER = [
+ "compilerPath",
+ "chunkId",
+ "chunkEntry",
+ "chunkInitial",
+ "file",
+ "separator!",
+ "moduleName",
+ "loc",
+ "separator!",
+ "message",
+ "separator!",
+ "details",
+ "separator!",
+ "filteredDetails",
+ "separator!",
+ "stack",
+ "separator!",
+ "missing",
+ "separator!",
+ "moduleTrace"
+];
+
+/** @type {Record<string, string[]>} */
+const PREFERRED_ORDERS = {
+ compilation: [
+ "name",
+ "hash",
+ "version",
+ "time",
+ "builtAt",
+ "env",
+ "publicPath",
+ "assets",
+ "filteredAssets",
+ "entrypoints",
+ "namedChunkGroups",
+ "chunks",
+ "modules",
+ "filteredModules",
+ "children",
+ "logging",
+ "warnings",
+ "warningsInChildren!",
+ "filteredWarningDetailsCount",
+ "errors",
+ "errorsInChildren!",
+ "filteredErrorDetailsCount",
+ "summary!",
+ "needAdditionalPass"
+ ],
+ asset: [
+ "type",
+ "name",
+ "size",
+ "chunks",
+ "auxiliaryChunks",
+ "emitted",
+ "comparedForEmit",
+ "cached",
+ "info",
+ "isOverSizeLimit",
+ "chunkNames",
+ "auxiliaryChunkNames",
+ "chunkIdHints",
+ "auxiliaryChunkIdHints",
+ "related",
+ "filteredRelated",
+ "children",
+ "filteredChildren"
+ ],
+ "asset.info": [
+ "immutable",
+ "sourceFilename",
+ "javascriptModule",
+ "development",
+ "hotModuleReplacement"
+ ],
+ chunkGroup: [
+ "kind!",
+ "name",
+ "isOverSizeLimit",
+ "assetsSize",
+ "auxiliaryAssetsSize",
+ "is!",
+ "assets",
+ "filteredAssets",
+ "auxiliaryAssets",
+ "filteredAuxiliaryAssets",
+ "separator!",
+ "children"
+ ],
+ chunkGroupAsset: ["name", "size"],
+ chunkGroupChildGroup: ["type", "children"],
+ chunkGroupChild: ["assets", "chunks", "name"],
+ module: [
+ "type",
+ "name",
+ "identifier",
+ "id",
+ "layer",
+ "sizes",
+ "chunks",
+ "depth",
+ "cacheable",
+ "orphan",
+ "runtime",
+ "optional",
+ "dependent",
+ "built",
+ "codeGenerated",
+ "cached",
+ "assets",
+ "failed",
+ "warnings",
+ "errors",
+ "children",
+ "filteredChildren",
+ "providedExports",
+ "usedExports",
+ "optimizationBailout",
+ "reasons",
+ "filteredReasons",
+ "issuerPath",
+ "profile",
+ "modules",
+ "filteredModules"
+ ],
+ moduleReason: [
+ "active",
+ "type",
+ "userRequest",
+ "moduleId",
+ "module",
+ "resolvedModule",
+ "loc",
+ "explanation",
+ "children",
+ "filteredChildren"
+ ],
+ "module.profile": [
+ "total",
+ "separator!",
+ "resolving",
+ "restoring",
+ "integration",
+ "building",
+ "storing",
+ "additionalResolving",
+ "additionalIntegration"
+ ],
+ chunk: [
+ "id",
+ "runtime",
+ "files",
+ "names",
+ "idHints",
+ "sizes",
+ "parents",
+ "siblings",
+ "children",
+ "childrenByOrder",
+ "entry",
+ "initial",
+ "rendered",
+ "recorded",
+ "reason",
+ "separator!",
+ "origins",
+ "separator!",
+ "modules",
+ "separator!",
+ "filteredModules"
+ ],
+ chunkOrigin: ["request", "moduleId", "moduleName", "loc"],
+ error: ERROR_PREFERRED_ORDER,
+ warning: ERROR_PREFERRED_ORDER,
+ "chunk.childrenByOrder[]": ["type", "children"],
+ loggingGroup: [
+ "debug",
+ "name",
+ "separator!",
+ "entries",
+ "separator!",
+ "filteredEntries"
+ ],
+ loggingEntry: ["message", "trace", "children"]
+};
+
+const itemsJoinOneLine = items => items.filter(Boolean).join(" ");
+const itemsJoinOneLineBrackets = items =>
+ items.length > 0 ? `(${items.filter(Boolean).join(" ")})` : undefined;
+const itemsJoinMoreSpacing = items => items.filter(Boolean).join("\n\n");
+const itemsJoinComma = items => items.filter(Boolean).join(", ");
+const itemsJoinCommaBrackets = items =>
+ items.length > 0 ? `(${items.filter(Boolean).join(", ")})` : undefined;
+const itemsJoinCommaBracketsWithName = name => items =>
+ items.length > 0
+ ? `(${name}: ${items.filter(Boolean).join(", ")})`
+ : undefined;
+
+/** @type {Record<string, (items: string[]) => string>} */
+const SIMPLE_ITEMS_JOINER = {
+ "chunk.parents": itemsJoinOneLine,
+ "chunk.siblings": itemsJoinOneLine,
+ "chunk.children": itemsJoinOneLine,
+ "chunk.names": itemsJoinCommaBrackets,
+ "chunk.idHints": itemsJoinCommaBracketsWithName("id hint"),
+ "chunk.runtime": itemsJoinCommaBracketsWithName("runtime"),
+ "chunk.files": itemsJoinComma,
+ "chunk.childrenByOrder": itemsJoinOneLine,
+ "chunk.childrenByOrder[].children": itemsJoinOneLine,
+ "chunkGroup.assets": itemsJoinOneLine,
+ "chunkGroup.auxiliaryAssets": itemsJoinOneLineBrackets,
+ "chunkGroupChildGroup.children": itemsJoinComma,
+ "chunkGroupChild.assets": itemsJoinOneLine,
+ "chunkGroupChild.auxiliaryAssets": itemsJoinOneLineBrackets,
+ "asset.chunks": itemsJoinComma,
+ "asset.auxiliaryChunks": itemsJoinCommaBrackets,
+ "asset.chunkNames": itemsJoinCommaBracketsWithName("name"),
+ "asset.auxiliaryChunkNames": itemsJoinCommaBracketsWithName("auxiliary name"),
+ "asset.chunkIdHints": itemsJoinCommaBracketsWithName("id hint"),
+ "asset.auxiliaryChunkIdHints":
+ itemsJoinCommaBracketsWithName("auxiliary id hint"),
+ "module.chunks": itemsJoinOneLine,
+ "module.issuerPath": items =>
+ items
+ .filter(Boolean)
+ .map(item => `${item} ->`)
+ .join(" "),
+ "compilation.errors": itemsJoinMoreSpacing,
+ "compilation.warnings": itemsJoinMoreSpacing,
+ "compilation.logging": itemsJoinMoreSpacing,
+ "compilation.children": items => indent(itemsJoinMoreSpacing(items), " "),
+ "moduleTraceItem.dependencies": itemsJoinOneLine,
+ "loggingEntry.children": items =>
+ indent(items.filter(Boolean).join("\n"), " ", false)
+};
+
+const joinOneLine = items =>
+ items
+ .map(item => item.content)
+ .filter(Boolean)
+ .join(" ");
+
+const joinInBrackets = items => {
+ const res = [];
+ let mode = 0;
+ for (const item of items) {
+ if (item.element === "separator!") {
+ switch (mode) {
+ case 0:
+ case 1:
+ mode += 2;
+ break;
+ case 4:
+ res.push(")");
+ mode = 3;
+ break;
+ }
+ }
+ if (!item.content) continue;
+ switch (mode) {
+ case 0:
+ mode = 1;
+ break;
+ case 1:
+ res.push(" ");
+ break;
+ case 2:
+ res.push("(");
+ mode = 4;
+ break;
+ case 3:
+ res.push(" (");
+ mode = 4;
+ break;
+ case 4:
+ res.push(", ");
+ break;
+ }
+ res.push(item.content);
+ }
+ if (mode === 4) res.push(")");
+ return res.join("");
+};
+
+const indent = (str, prefix, noPrefixInFirstLine) => {
+ const rem = str.replace(/\n([^\n])/g, "\n" + prefix + "$1");
+ if (noPrefixInFirstLine) return rem;
+ const ind = str[0] === "\n" ? "" : prefix;
+ return ind + rem;
+};
+
+const joinExplicitNewLine = (items, indenter) => {
+ let firstInLine = true;
+ let first = true;
+ return items
+ .map(item => {
+ if (!item || !item.content) return;
+ let content = indent(item.content, first ? "" : indenter, !firstInLine);
+ if (firstInLine) {
+ content = content.replace(/^\n+/, "");
+ }
+ if (!content) return;
+ first = false;
+ const noJoiner = firstInLine || content.startsWith("\n");
+ firstInLine = content.endsWith("\n");
+ return noJoiner ? content : " " + content;
+ })
+ .filter(Boolean)
+ .join("")
+ .trim();
+};
+
+const joinError =
+ error =>
+ (items, { red, yellow }) =>
+ `${error ? red("ERROR") : yellow("WARNING")} in ${joinExplicitNewLine(
+ items,
+ ""
+ )}`;
+
+/** @type {Record<string, (items: ({ element: string, content: string })[], context: StatsPrinterContext) => string>} */
+const SIMPLE_ELEMENT_JOINERS = {
+ compilation: items => {
+ const result = [];
+ let lastNeedMore = false;
+ for (const item of items) {
+ if (!item.content) continue;
+ const needMoreSpace =
+ item.element === "warnings" ||
+ item.element === "filteredWarningDetailsCount" ||
+ item.element === "errors" ||
+ item.element === "filteredErrorDetailsCount" ||
+ item.element === "logging";
+ if (result.length !== 0) {
+ result.push(needMoreSpace || lastNeedMore ? "\n\n" : "\n");
+ }
+ result.push(item.content);
+ lastNeedMore = needMoreSpace;
+ }
+ if (lastNeedMore) result.push("\n");
+ return result.join("");
+ },
+ asset: items =>
+ joinExplicitNewLine(
+ items.map(item => {
+ if (
+ (item.element === "related" || item.element === "children") &&
+ item.content
+ ) {
+ return {
+ ...item,
+ content: `\n${item.content}\n`
+ };
+ }
+ return item;
+ }),
+ " "
+ ),
+ "asset.info": joinOneLine,
+ module: (items, { module }) => {
+ let hasName = false;
+ return joinExplicitNewLine(
+ items.map(item => {
+ switch (item.element) {
+ case "id":
+ if (module.id === module.name) {
+ if (hasName) return false;
+ if (item.content) hasName = true;
+ }
+ break;
+ case "name":
+ if (hasName) return false;
+ if (item.content) hasName = true;
+ break;
+ case "providedExports":
+ case "usedExports":
+ case "optimizationBailout":
+ case "reasons":
+ case "issuerPath":
+ case "profile":
+ case "children":
+ case "modules":
+ if (item.content) {
+ return {
+ ...item,
+ content: `\n${item.content}\n`
+ };
+ }
+ break;
+ }
+ return item;
+ }),
+ " "
+ );
+ },
+ 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;
+ }),
+ " "
+ )
+ );
+ },
+ "chunk.childrenByOrder[]": items => `(${joinOneLine(items)})`,
+ chunkGroup: items => joinExplicitNewLine(items, " "),
+ chunkGroupAsset: joinOneLine,
+ chunkGroupChildGroup: joinOneLine,
+ chunkGroupChild: joinOneLine,
+ // moduleReason: (items, { moduleReason }) => {
+ // let hasName = false;
+ // return joinOneLine(
+ // items.filter(item => {
+ // switch (item.element) {
+ // case "moduleId":
+ // if (moduleReason.moduleId === moduleReason.module && item.content)
+ // hasName = true;
+ // break;
+ // case "module":
+ // if (hasName) return false;
+ // break;
+ // case "resolvedModule":
+ // return (
+ // moduleReason.module !== moduleReason.resolvedModule &&
+ // item.content
+ // );
+ // }
+ // return true;
+ // })
+ // );
+ // },
+ moduleReason: (items, { moduleReason }) => {
+ let hasName = false;
+ return joinExplicitNewLine(
+ items.map(item => {
+ switch (item.element) {
+ case "moduleId":
+ if (moduleReason.moduleId === moduleReason.module && item.content)
+ hasName = true;
+ break;
+ case "module":
+ if (hasName) return false;
+ break;
+ case "resolvedModule":
+ if (moduleReason.module === moduleReason.resolvedModule)
+ return false;
+ break;
+ case "children":
+ if (item.content) {
+ return {
+ ...item,
+ content: `\n${item.content}\n`
+ };
+ }
+ break;
+ }
+ return item;
+ }),
+ " "
+ );
+ },
+ "module.profile": joinInBrackets,
+ moduleIssuer: joinOneLine,
+ chunkOrigin: items => "> " + joinOneLine(items),
+ "errors[].error": joinError(true),
+ "warnings[].error": joinError(false),
+ loggingGroup: items => joinExplicitNewLine(items, "").trimEnd(),
+ moduleTraceItem: items => " @ " + joinOneLine(items),
+ moduleTraceDependency: joinOneLine
+};
+
+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"
+};
+
+const AVAILABLE_FORMATS = {
+ formatChunkId: (id, { yellow }, direction) => {
+ switch (direction) {
+ case "parent":
+ return `<{${yellow(id)}}>`;
+ case "sibling":
+ return `={${yellow(id)}}=`;
+ case "child":
+ return `>{${yellow(id)}}<`;
+ default:
+ return `{${yellow(id)}}`;
+ }
+ },
+ formatModuleId: id => `[${id}]`,
+ formatFilename: (filename, { green, yellow }, oversize) =>
+ (oversize ? yellow : green)(filename),
+ formatFlag: flag => `[${flag}]`,
+ formatLayer: layer => `(in ${layer})`,
+ formatSize: require("../SizeFormatHelpers").formatSize,
+ formatDateTime: (dateTime, { bold }) => {
+ const d = new Date(dateTime);
+ const x = twoDigit;
+ const date = `${d.getFullYear()}-${x(d.getMonth() + 1)}-${x(d.getDate())}`;
+ const time = `${x(d.getHours())}:${x(d.getMinutes())}:${x(d.getSeconds())}`;
+ return `${date} ${bold(time)}`;
+ },
+ formatTime: (
+ time,
+ { timeReference, bold, green, yellow, red },
+ boldQuantity
+ ) => {
+ const unit = " ms";
+ if (timeReference && time !== timeReference) {
+ const times = [
+ timeReference / 2,
+ timeReference / 4,
+ timeReference / 8,
+ timeReference / 16
+ ];
+ if (time < times[3]) return `${time}${unit}`;
+ 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}`;
+ }
+ },
+ formatError: (message, { green, yellow, red }) => {
+ if (message.includes("\u001b[")) return message;
+ const highlights = [
+ { regExp: /(Did you mean .+)/g, format: green },
+ {
+ regExp: /(Set 'mode' option to 'development' or 'production')/g,
+ format: green
+ },
+ { regExp: /(\(module has no exports\))/g, format: red },
+ { regExp: /\(possible exports: (.+)\)/g, format: green },
+ { regExp: /(?:^|\n)(.* doesn't exist)/g, format: red },
+ { regExp: /('\w+' option has not been set)/g, format: red },
+ {
+ regExp: /(Emitted value instead of an instance of Error)/g,
+ format: yellow
+ },
+ { regExp: /(Used? .+ instead)/gi, format: yellow },
+ { regExp: /\b(deprecated|must|required)\b/g, format: yellow },
+ {
+ regExp: /\b(BREAKING CHANGE)\b/gi,
+ format: red
+ },
+ {
+ regExp:
+ /\b(error|failed|unexpected|invalid|not found|not supported|not available|not possible|not implemented|doesn't support|conflict|conflicting|not existing|duplicate)\b/gi,
+ format: red
+ }
+ ];
+ for (const { regExp, format } of highlights) {
+ message = message.replace(regExp, (match, content) => {
+ return match.replace(content, format(content));
+ });
+ }
+ return message;
+ }
+};
+
+const RESULT_MODIFIER = {
+ "module.modules": result => {
+ return indent(result, "| ");
+ }
+};
+
+const createOrder = (array, preferredOrder) => {
+ const originalArray = array.slice();
+ const set = new Set(array);
+ const usedSet = new Set();
+ array.length = 0;
+ for (const element of preferredOrder) {
+ if (element.endsWith("!") || set.has(element)) {
+ array.push(element);
+ usedSet.add(element);
+ }
+ }
+ for (const element of originalArray) {
+ if (!usedSet.has(element)) {
+ array.push(element);
+ }
+ }
+ return array;
+};
+
+class DefaultStatsPrinterPlugin {
+ /**
+ * Apply the plugin
+ * @param {Compiler} compiler the compiler instance
+ * @returns {void}
+ */
+ apply(compiler) {
+ compiler.hooks.compilation.tap("DefaultStatsPrinterPlugin", compilation => {
+ compilation.hooks.statsPrinter.tap(
+ "DefaultStatsPrinterPlugin",
+ (stats, options, context) => {
+ // Put colors into context
+ stats.hooks.print
+ .for("compilation")
+ .tap("DefaultStatsPrinterPlugin", (compilation, context) => {
+ for (const color of Object.keys(AVAILABLE_COLORS)) {
+ let start;
+ if (options.colors) {
+ if (
+ typeof options.colors === "object" &&
+ typeof options.colors[color] === "string"
+ ) {
+ start = options.colors[color];
+ } else {
+ start = AVAILABLE_COLORS[color];
+ }
+ }
+ if (start) {
+ context[color] = str =>
+ `${start}${
+ typeof str === "string"
+ ? str.replace(
+ /((\u001b\[39m|\u001b\[22m|\u001b\[0m)+)/g,
+ `$1${start}`
+ )
+ : str
+ }\u001b[39m\u001b[22m`;
+ } else {
+ context[color] = str => str;
+ }
+ }
+ for (const format of Object.keys(AVAILABLE_FORMATS)) {
+ context[format] = (content, ...args) =>
+ AVAILABLE_FORMATS[format](content, context, ...args);
+ }
+ context.timeReference = compilation.time;
+ });
+
+ for (const key of Object.keys(SIMPLE_PRINTERS)) {
+ stats.hooks.print
+ .for(key)
+ .tap("DefaultStatsPrinterPlugin", (obj, ctx) =>
+ SIMPLE_PRINTERS[key](obj, ctx, stats)
+ );
+ }
+
+ for (const key of Object.keys(PREFERRED_ORDERS)) {
+ const preferredOrder = PREFERRED_ORDERS[key];
+ stats.hooks.sortElements
+ .for(key)
+ .tap("DefaultStatsPrinterPlugin", (elements, context) => {
+ createOrder(elements, preferredOrder);
+ });
+ }
+
+ for (const key of Object.keys(ITEM_NAMES)) {
+ const itemName = ITEM_NAMES[key];
+ stats.hooks.getItemName
+ .for(key)
+ .tap(
+ "DefaultStatsPrinterPlugin",
+ typeof itemName === "string" ? () => itemName : itemName
+ );
+ }
+
+ for (const key of Object.keys(SIMPLE_ITEMS_JOINER)) {
+ const joiner = SIMPLE_ITEMS_JOINER[key];
+ stats.hooks.printItems
+ .for(key)
+ .tap("DefaultStatsPrinterPlugin", joiner);
+ }
+
+ for (const key of Object.keys(SIMPLE_ELEMENT_JOINERS)) {
+ const joiner = SIMPLE_ELEMENT_JOINERS[key];
+ stats.hooks.printElements
+ .for(key)
+ .tap("DefaultStatsPrinterPlugin", joiner);
+ }
+
+ for (const key of Object.keys(RESULT_MODIFIER)) {
+ const modifier = RESULT_MODIFIER[key];
+ stats.hooks.result
+ .for(key)
+ .tap("DefaultStatsPrinterPlugin", modifier);
+ }
+ }
+ );
+ });
+ }
+}
+module.exports = DefaultStatsPrinterPlugin;
diff --git a/node_modules/webpack/lib/stats/StatsFactory.js b/node_modules/webpack/lib/stats/StatsFactory.js
new file mode 100644
index 00000000..4ba7063b
--- /dev/null
+++ b/node_modules/webpack/lib/stats/StatsFactory.js
@@ -0,0 +1,292 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { HookMap, SyncBailHook, SyncWaterfallHook } = require("tapable");
+const { concatComparators, keepOriginalOrder } = require("../util/comparators");
+const smartGrouping = require("../util/smartGrouping");
+
+/** @typedef {import("../Chunk")} Chunk */
+/** @typedef {import("../Compilation")} Compilation */
+/** @typedef {import("../Module")} Module */
+/** @typedef {import("../WebpackError")} WebpackError */
+/** @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
+ */
+
+/** @typedef {KnownStatsFactoryContext & Record<string, any>} StatsFactoryContext */
+
+class StatsFactory {
+ constructor() {
+ 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]>[]>>} */ ({});
+ for (const key of Object.keys(hooks)) {
+ this._caches[key] = new Map();
+ }
+ this._inCreate = false;
+ }
+
+ _getAllLevelHooks(hookMap, cache, type) {
+ const cacheEntry = cache.get(type);
+ if (cacheEntry !== undefined) {
+ return cacheEntry;
+ }
+ const hooks = [];
+ const typeParts = type.split(".");
+ for (let i = 0; i < typeParts.length; i++) {
+ const hook = hookMap.get(typeParts.slice(i).join("."));
+ if (hook) {
+ hooks.push(hook);
+ }
+ }
+ cache.set(type, hooks);
+ return hooks;
+ }
+
+ _forEachLevel(hookMap, cache, type, fn) {
+ for (const hook of this._getAllLevelHooks(hookMap, cache, type)) {
+ const result = fn(hook);
+ if (result !== undefined) return result;
+ }
+ }
+
+ _forEachLevelWaterfall(hookMap, cache, type, data, fn) {
+ for (const hook of this._getAllLevelHooks(hookMap, cache, type)) {
+ data = fn(hook, data);
+ }
+ return data;
+ }
+
+ _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);
+ if (r !== undefined) {
+ if (r) i++;
+ return r;
+ }
+ }
+ i++;
+ return true;
+ });
+ }
+
+ /**
+ * @param {string} type type
+ * @param {any} data factory data
+ * @param {Omit<StatsFactoryContext, "type">} baseContext context used as base
+ * @returns {any} 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;
+ }
+ }
+ }
+
+ _create(type, data, baseContext) {
+ const context = {
+ ...baseContext,
+ type,
+ [type]: data
+ };
+ if (Array.isArray(data)) {
+ // run filter on unsorted items
+ const items = this._forEachLevelFilter(
+ this.hooks.filter,
+ this._caches.filter,
+ type,
+ data,
+ (h, r, idx, i) => h.call(r, context, idx, i),
+ true
+ );
+
+ // sort items
+ const comparators = [];
+ this._forEachLevel(this.hooks.sort, this._caches.sort, type, h =>
+ h.call(comparators, context)
+ );
+ if (comparators.length > 0) {
+ items.sort(
+ // @ts-expect-error number of arguments is correct
+ concatComparators(...comparators, keepOriginalOrder(items))
+ );
+ }
+
+ // run filter on sorted items
+ const items2 = this._forEachLevelFilter(
+ this.hooks.filterSorted,
+ this._caches.filterSorted,
+ type,
+ items,
+ (h, r, idx, i) => h.call(r, context, idx, i),
+ false
+ );
+
+ // for each item
+ let resultItems = items2.map((item, i) => {
+ const itemContext = {
+ ...context,
+ _index: i
+ };
+
+ // run getItemName
+ const itemName = this._forEachLevel(
+ this.hooks.getItemName,
+ this._caches.getItemName,
+ `${type}[]`,
+ h => h.call(item, itemContext)
+ );
+ if (itemName) itemContext[itemName] = item;
+ const innerType = itemName ? `${type}[].${itemName}` : `${type}[]`;
+
+ // run getItemFactory
+ const itemFactory =
+ this._forEachLevel(
+ this.hooks.getItemFactory,
+ this._caches.getItemFactory,
+ innerType,
+ h => h.call(item, itemContext)
+ ) || this;
+
+ // run item factory
+ return itemFactory.create(innerType, item, itemContext);
+ });
+
+ // sort result items
+ const comparators2 = [];
+ this._forEachLevel(
+ this.hooks.sortResults,
+ this._caches.sortResults,
+ type,
+ h => h.call(comparators2, context)
+ );
+ if (comparators2.length > 0) {
+ resultItems.sort(
+ // @ts-expect-error number of arguments is correct
+ concatComparators(...comparators2, keepOriginalOrder(resultItems))
+ );
+ }
+
+ // group result items
+ const groupConfigs = [];
+ this._forEachLevel(
+ this.hooks.groupResults,
+ this._caches.groupResults,
+ type,
+ h => h.call(groupConfigs, context)
+ );
+ if (groupConfigs.length > 0) {
+ resultItems = smartGrouping(resultItems, groupConfigs);
+ }
+
+ // run filter on sorted result items
+ const finalResultItems = this._forEachLevelFilter(
+ this.hooks.filterResults,
+ this._caches.filterResults,
+ type,
+ resultItems,
+ (h, r, idx, i) => h.call(r, context, idx, i),
+ false
+ );
+
+ // run merge on mapped items
+ let result = this._forEachLevel(
+ this.hooks.merge,
+ this._caches.merge,
+ type,
+ h => h.call(finalResultItems, context)
+ );
+ if (result === undefined) result = finalResultItems;
+
+ // run result on merged items
+ return this._forEachLevelWaterfall(
+ this.hooks.result,
+ this._caches.result,
+ type,
+ 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)
+ );
+ }
+ }
+}
+module.exports = StatsFactory;
diff --git a/node_modules/webpack/lib/stats/StatsPrinter.js b/node_modules/webpack/lib/stats/StatsPrinter.js
new file mode 100644
index 00000000..228b81db
--- /dev/null
+++ b/node_modules/webpack/lib/stats/StatsPrinter.js
@@ -0,0 +1,249 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+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").StatsModule} StatsModule */
+/** @typedef {import("./DefaultStatsFactoryPlugin").StatsModuleReason} StatsModuleReason */
+
+/**
+ * @typedef {Object} PrintedElement
+ * @property {string} element
+ * @property {string} content
+ */
+
+/**
+ * @typedef {Object} KnownStatsPrinterContext
+ * @property {string=} type
+ * @property {StatsCompilation=} compilation
+ * @property {StatsChunkGroup=} chunkGroup
+ * @property {StatsAsset=} asset
+ * @property {StatsModule=} module
+ * @property {StatsChunk=} chunk
+ * @property {StatsModuleReason=} moduleReason
+ * @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
+ * @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 {(dateTime: number) => string=} formatDateTime
+ * @property {(flag: string) => string=} formatFlag
+ * @property {(time: number, boldQuantity?: boolean) => string=} formatTime
+ * @property {string=} chunkGroupKind
+ */
+
+/** @typedef {KnownStatsPrinterContext & Record<string, any>} StatsPrinterContext */
+
+class StatsPrinter {
+ constructor() {
+ 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[]>>} */
+ this._levelHookCache = new Map();
+ this._inPrint = false;
+ }
+
+ /**
+ * get all level hooks
+ * @private
+ * @template {Hook} T
+ * @param {HookMap<T>} hookMap HookMap
+ * @param {string} type type
+ * @returns {T[]} hooks
+ */
+ _getAllLevelHooks(hookMap, type) {
+ let cache = /** @type {Map<string, T[]>} */ (
+ this._levelHookCache.get(hookMap)
+ );
+ if (cache === undefined) {
+ cache = new Map();
+ this._levelHookCache.set(hookMap, cache);
+ }
+ const cacheEntry = cache.get(type);
+ if (cacheEntry !== undefined) {
+ return cacheEntry;
+ }
+ /** @type {T[]} */
+ const hooks = [];
+ const typeParts = type.split(".");
+ for (let i = 0; i < typeParts.length; i++) {
+ const hook = hookMap.get(typeParts.slice(i).join("."));
+ if (hook) {
+ hooks.push(hook);
+ }
+ }
+ cache.set(type, hooks);
+ return hooks;
+ }
+
+ /**
+ * Run `fn` for each level
+ * @private
+ * @template T
+ * @template R
+ * @param {HookMap<SyncBailHook<T, R>>} hookMap HookMap
+ * @param {string} type type
+ * @param {(hook: SyncBailHook<T, R>) => R} fn function
+ * @returns {R} result of `fn`
+ */
+ _forEachLevel(hookMap, type, fn) {
+ for (const hook of this._getAllLevelHooks(hookMap, type)) {
+ const result = fn(hook);
+ if (result !== undefined) return result;
+ }
+ }
+
+ /**
+ * Run `fn` for each level
+ * @private
+ * @template T
+ * @param {HookMap<SyncWaterfallHook<T>>} hookMap HookMap
+ * @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`
+ */
+ _forEachLevelWaterfall(hookMap, type, data, fn) {
+ for (const hook of this._getAllLevelHooks(hookMap, type)) {
+ data = fn(hook, data);
+ }
+ return data;
+ }
+
+ /**
+ * @param {string} type The type
+ * @param {Object} object Object to print
+ * @param {Object=} 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;
+ }
+ }
+ }
+
+ /**
+ * @private
+ * @param {string} type type
+ * @param {Object} object object
+ * @param {Object=} baseContext context
+ * @returns {string} printed result
+ */
+ _print(type, object, baseContext) {
+ const context = {
+ ...baseContext,
+ type,
+ [type]: object
+ };
+
+ let printResult = this._forEachLevel(this.hooks.print, type, hook =>
+ hook.call(object, context)
+ );
+ if (printResult === undefined) {
+ if (Array.isArray(object)) {
+ const sortedItems = object.slice();
+ this._forEachLevel(this.hooks.sortItems, type, h =>
+ h.call(sortedItems, context)
+ );
+ const printedItems = sortedItems.map((item, i) => {
+ const itemContext = {
+ ...context,
+ _index: i
+ };
+ const itemName = this._forEachLevel(
+ this.hooks.getItemName,
+ `${type}[]`,
+ h => h.call(item, itemContext)
+ );
+ if (itemName) itemContext[itemName] = item;
+ return this.print(
+ itemName ? `${type}[].${itemName}` : `${type}[]`,
+ item,
+ itemContext
+ );
+ });
+ printResult = this._forEachLevel(this.hooks.printItems, type, h =>
+ h.call(printedItems, context)
+ );
+ if (printResult === undefined) {
+ const result = printedItems.filter(Boolean);
+ if (result.length > 0) printResult = result.join("\n");
+ }
+ } else if (object !== null && typeof object === "object") {
+ const elements = Object.keys(object).filter(
+ key => object[key] !== undefined
+ );
+ this._forEachLevel(this.hooks.sortElements, type, h =>
+ h.call(elements, context)
+ );
+ const printedElements = elements.map(element => {
+ const content = this.print(`${type}.${element}`, object[element], {
+ ...context,
+ _parent: object,
+ _element: element,
+ [element]: object[element]
+ });
+ return { element, content };
+ });
+ printResult = this._forEachLevel(this.hooks.printElements, type, h =>
+ h.call(printedElements, context)
+ );
+ if (printResult === undefined) {
+ const result = printedElements.map(e => e.content).filter(Boolean);
+ if (result.length > 0) printResult = result.join("\n");
+ }
+ }
+ }
+
+ return this._forEachLevelWaterfall(
+ this.hooks.result,
+ type,
+ printResult,
+ (h, r) => h.call(r, context)
+ );
+ }
+}
+module.exports = StatsPrinter;