add grouping of modules

This commit is contained in:
Tobias Koppers 2020-09-01 18:08:09 +02:00
parent 3ea9400505
commit be021e00f4
39 changed files with 2843 additions and 2561 deletions

View File

@ -1877,6 +1877,10 @@ export interface StatsOptions {
* Show cached assets (setting this to `false` only shows emitted files).
*/
cachedAssets?: boolean;
/**
* Add information about cached (not built) modules.
*/
cachedModules?: boolean;
/**
* Add children information.
*/
@ -1897,10 +1901,6 @@ export interface StatsOptions {
* Add information about parent, children and sibling chunks to chunk information.
*/
chunkRelations?: boolean;
/**
* Add root modules information to chunk information.
*/
chunkRootModules?: boolean;
/**
* Add chunk information.
*/
@ -1944,6 +1944,10 @@ export interface StatsOptions {
* Context directory for request shortening.
*/
context?: string;
/**
* Show chunk modules that are dependencies of other modules of the chunk.
*/
dependentModules?: boolean;
/**
* Add module depth in module graph.
*/
@ -2000,6 +2004,22 @@ export interface StatsOptions {
* Group assets by their status (emitted, compared for emit or cached).
*/
groupAssetsByStatus?: boolean;
/**
* Group modules by their attributes (errors, warnings, optional, orphan, or dependent).
*/
groupModulesByAttributes?: boolean;
/**
* Group modules by their status (cached or built and cacheable).
*/
groupModulesByCacheStatus?: boolean;
/**
* Group modules by their extension.
*/
groupModulesByExtension?: boolean;
/**
* Group modules by their path.
*/
groupModulesByPath?: boolean;
/**
* Add the hash of the compilation.
*/
@ -2020,10 +2040,6 @@ export interface StatsOptions {
* Add stack traces to logging output.
*/
loggingTrace?: boolean;
/**
* Set the maximum number of modules to be shown.
*/
maxModules?: number;
/**
* Add information about assets inside modules.
*/
@ -2040,6 +2056,10 @@ export interface StatsOptions {
* Sort the modules by that field.
*/
modulesSort?: string;
/**
* Space to display modules (groups will be collapsed to fit this space, values is in number of modules/groups).
*/
modulesSpace?: number;
/**
* Add information about modules nested in other modules (like with module concatenation).
*/

View File

@ -758,6 +758,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
this.needAdditionalPass = false;
/** @type {WeakSet<Module>} */
this.builtModules = new WeakSet();
/** @type {WeakSet<Module>} */
this.codeGeneratedModules = new WeakSet();
/** @private @type {Map<Module, Callback[]>} */
this._rebuildingModules = new Map();
/** @type {Set<string>} */
@ -2122,6 +2124,7 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
if (!cachedResult) {
statModulesGenerated++;
try {
this.codeGeneratedModules.add(module);
result = module.codeGeneration({
chunkGraph,
moduleGraph,

View File

@ -207,7 +207,7 @@ class ContextModule extends Module {
* @returns {string} a user readable identifier of the module
*/
readableIdentifier(requestShortener) {
let identifier = requestShortener.shorten(this.context);
let identifier = requestShortener.shorten(this.context) + "/";
if (this.options.resourceQuery) {
identifier += ` ${this.options.resourceQuery}`;
}

View File

@ -20,7 +20,7 @@ const {
compareSelect,
compareModulesByIdentifier
} = require("../util/comparators");
const identifierUtils = require("../util/identifier");
const { makePathsRelative, parseResource } = require("../util/identifier");
/** @typedef {import("webpack-sources").Source} Source */
/** @typedef {import("../Chunk")} Chunk */
@ -47,6 +47,7 @@ const identifierUtils = require("../util/identifier");
* @typedef {Object} UsualContext
* @property {string} type
* @property {Compilation} compilation
* @property {Set<Module>} rootModules
* @property {Map<string,Chunk[]>} compilationFileToChunks
* @property {Map<string,Chunk[]>} compilationAuxiliaryFileToChunks
* @property {number} startTime
@ -60,7 +61,6 @@ const identifierUtils = require("../util/identifier");
* @property {RequestShortener} requestShortener
* @property {string} chunksSort
* @property {string} modulesSort
* @property {string} chunkRootModulesSort
* @property {string} chunkModulesSort
* @property {string} nestedModulesSort
* @property {string} assetsSort
@ -72,7 +72,18 @@ const identifierUtils = require("../util/identifier");
* @property {Function[]} excludeAssets
* @property {Function[]} excludeModules
* @property {Function[]} warningsFilter
* @property {number} maxModules
* @property {boolean} cachedModules
* @property {boolean} orphanModules
* @property {boolean} dependentModules
* @property {boolean} runtime
* @property {boolean} groupModulesByCacheStatus
* @property {boolean} groupModulesByAttributes
* @property {boolean} groupModulesByPath
* @property {boolean} groupModulesByExtension
* @property {boolean} groupModulesByType
* @property {number} modulesSpace
* @property {number} chunkModulesSpace
* @property {number} nestedModulesSpace
* @property {false|"none"|"error"|"warn"|"info"|"log"|"verbose"} logging
* @property {Function[]} loggingDebug
* @property {boolean} loggingTrace
@ -359,8 +370,10 @@ const SIMPLE_EXTRACTORS = {
modules: (object, compilation, context, options, factory) => {
const { type } = context;
const array = Array.from(compilation.modules);
object.modules = factory.create(`${type}.modules`, array, context);
object.filteredModules = array.length - object.modules.length;
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, options, factory) => {
const { type } = context;
@ -454,7 +467,7 @@ const SIMPLE_EXTRACTORS = {
collapsedGroups = true;
break;
}
const makePathsRelative = identifierUtils.makePathsRelative.bindContextCache(
const cachedMakePathsRelative = makePathsRelative.bindContextCache(
context,
compilation.compiler.root
);
@ -516,7 +529,7 @@ const SIMPLE_EXTRACTORS = {
}
}
}
let name = makePathsRelative(origin).replace(/\|/g, " ");
let name = cachedMakePathsRelative(origin).replace(/\|/g, " ");
if (name in object.logging) {
let i = 1;
while (`${name}#${i}` in object.logging) {
@ -658,7 +671,7 @@ const SIMPLE_EXTRACTORS = {
},
module: {
_: (object, module, context, { requestShortener }, factory) => {
const { compilation, type } = context;
const { compilation, type, rootModules } = context;
const { moduleGraph } = compilation;
/** @type {Module[]} */
const path = [];
@ -679,9 +692,14 @@ const SIMPLE_EXTRACTORS = {
for (const sourceType of module.getSourceTypes()) {
sizes[sourceType] = module.size(sourceType);
}
const built = compilation.builtModules.has(module);
const codeGenerated = compilation.codeGeneratedModules.has(module);
Object.assign(object, {
type: "module",
moduleType: module.type,
identifier: module.identifier(),
name: module.readableIdentifier(requestShortener),
nameForCondition: module.nameForCondition(),
index: moduleGraph.getPreOrderIndex(module),
preOrderIndex: moduleGraph.getPreOrderIndex(module),
index2: moduleGraph.getPostOrderIndex(module),
@ -689,9 +707,14 @@ const SIMPLE_EXTRACTORS = {
size: module.size(),
sizes,
cacheable: module.buildInfo.cacheable,
built: compilation.builtModules.has(module),
built,
codeGenerated,
cached: !built && !codeGenerated,
optional: module.isOptional(moduleGraph),
runtime: module.type === "runtime",
orphan:
!type.endsWith("module.modules[].module") &&
compilation.chunkGraph.getNumberOfModuleChunks(module) === 0,
dependent: rootModules ? !rootModules.has(module) : undefined,
issuer: issuer && issuer.identifier(),
issuerName: issuer && issuer.readableIdentifier(requestShortener),
issuerPath:
@ -713,12 +736,6 @@ const SIMPLE_EXTRACTORS = {
chunk => chunk.id
);
},
orphanModules: (object, module, { compilation, type }) => {
if (!type.endsWith("module.modules[].module")) {
object.orphan =
compilation.chunkGraph.getNumberOfModuleChunks(module) === 0;
}
},
moduleAssets: (object, module) => {
object.assets = module.buildInfo.assets
? Object.keys(module.buildInfo.assets)
@ -775,8 +792,17 @@ const SIMPLE_EXTRACTORS = {
const { type } = context;
if (module instanceof ConcatenatedModule) {
const modules = module.modules;
object.modules = factory.create(`${type}.modules`, modules, context);
object.filteredModules = modules.length - object.modules.length;
const groupedModules = factory.create(
`${type}.modules`,
modules,
context
);
const limited = spaceLimited(
groupedModules,
options.nestedModulesSpace
);
object.modules = limited.children;
object.filteredModules = limited.filteredChildren;
}
},
source: (object, module) => {
@ -930,26 +956,14 @@ const SIMPLE_EXTRACTORS = {
compilation: { chunkGraph }
} = context;
const array = chunkGraph.getChunkModules(chunk);
object.modules = factory.create(`${type}.modules`, array, {
const groupedModules = factory.create(`${type}.modules`, array, {
...context,
runtime: chunk.runtime
runtime: chunk.runtime,
rootModules: new Set(chunkGraph.getChunkRootModules(chunk))
});
object.filteredModules = array.length - object.modules.length;
},
chunkRootModules: (object, chunk, context, options, factory) => {
const {
type,
compilation: { chunkGraph }
} = context;
const array = chunkGraph.getChunkRootModules(chunk);
object.rootModules = factory.create(
`${type}.rootModules`,
array,
context
);
object.filteredRootModules = array.length - object.rootModules.length;
object.nonRootModules =
chunkGraph.getNumberOfChunkModules(chunk) - array.length;
const limited = spaceLimited(groupedModules, options.chunkModulesSpace);
object.modules = limited.children;
object.filteredModules = limited.filteredChildren;
},
chunkOrigins: (object, chunk, context, options, factory) => {
const {
@ -1028,49 +1042,8 @@ const SIMPLE_EXTRACTORS = {
}
};
const EXCLUDE_MODULES_FILTER = type => (
module,
context,
{ excludeModules, requestShortener }
) => {
const name = module.nameForCondition();
if (!name) return;
const ident = requestShortener.shorten(name);
const excluded = excludeModules.some(fn => fn(ident, module, type));
if (excluded) return false;
};
/** @type {Record<string, (module: Module, context: UsualContext) => boolean | undefined>} */
const BASE_MODULES_FILTER = {
"!cached": (module, { compilation }) => {
if (!compilation.builtModules.has(module)) return false;
},
"!runtime": module => {
if (module.type === "runtime") return false;
}
};
/** @type {Record<string, Record<string, (thing: any, context: UsualContext, options: UsualOptions) => boolean | undefined>>} */
const FILTER = {
"compilation.modules": {
excludeModules: EXCLUDE_MODULES_FILTER("module"),
"!orphanModules": (module, { compilation: { chunkGraph } }) => {
if (chunkGraph.getNumberOfModuleChunks(module) === 0) return false;
},
...BASE_MODULES_FILTER
},
"module.modules": {
excludeModules: EXCLUDE_MODULES_FILTER("nested"),
...BASE_MODULES_FILTER
},
"chunk.modules": {
excludeModules: EXCLUDE_MODULES_FILTER("chunk"),
...BASE_MODULES_FILTER
},
"chunk.rootModules": {
excludeModules: EXCLUDE_MODULES_FILTER("root-of-chunk"),
...BASE_MODULES_FILTER
},
"module.reasons": {
"!orphanModules": (reason, { compilation: { chunkGraph } }) => {
if (
@ -1083,21 +1056,6 @@ const FILTER = {
}
};
/** @type {Record<string, (module: Module, context: UsualContext, options: UsualOptions, idx: number, i: number) => boolean | undefined>} */
const FILTER_SORTED_MODULES = {
maxModules: (module, context, { maxModules }, idx, i) => {
if (i >= maxModules) return false;
}
};
/** @type {Record<string, Record<string, (thing: any, context: UsualContext, options: UsualOptions, idx: number, i: number) => boolean | undefined>>} */
const FILTER_SORTED = {
"compilation.modules": FILTER_SORTED_MODULES,
"modules.modules": FILTER_SORTED_MODULES,
"chunk.modules": FILTER_SORTED_MODULES,
"chunk.rootModules": FILTER_SORTED_MODULES
};
/** @type {Record<string, Record<string, (thing: Object, context: UsualContext, options: UsualOptions) => boolean | undefined>>} */
const FILTER_RESULTS = {
"compilation.warnings": {
@ -1233,20 +1191,21 @@ const collapse = children => {
return newChildren;
};
const spaceLimited = (children, max) => {
const groups = children.filter(c => c.children || c.filteredChildren);
const spaceLimited = (itemsAndGroups, max) => {
/** @type {any[] | undefined} */
let children = undefined;
/** @type {number | undefined} */
let filteredChildren = undefined;
const groups = itemsAndGroups.filter(c => c.children || c.filteredChildren);
const groupSizes = groups.map(g =>
g.children ? getTotalSize(g.children) + 1 : 1
);
const items = children.filter(c => !c.children && !c.filteredChildren);
const items = itemsAndGroups.filter(c => !c.children && !c.filteredChildren);
let groupsSize = groupSizes.reduce((a, b) => a + b, 0);
if (groupsSize + items.length <= max) {
// keep all
return {
children: groups.concat(items),
filteredChildren: undefined
};
} else if (children.length < max) {
children = groups.concat(items);
} else if (itemsAndGroups.length < max) {
// collapse some groups, keep items
while (groupsSize + items.length > max) {
const oversize = items.length + groupsSize - max;
@ -1273,34 +1232,27 @@ const spaceLimited = (children, max) => {
}
}
}
return {
children: groups.concat(items),
filteredChildren: undefined
};
} else if (children.length === max) {
children = groups.concat(items);
} else if (itemsAndGroups.length === max) {
// collapse all groups and keep items
return {
children: collapse(groups).concat(items),
filteredChildren: undefined
};
children = collapse(groups).concat(items);
} else if (groups.length + 1 <= max) {
// collapse all groups and items
return {
children: collapse(groups),
filteredChildren: items.length
};
children = collapse(groups);
filteredChildren = items.length;
} else {
// collapse complete group
return {
children: undefined,
filteredChildren: getTotalItems(children)
};
filteredChildren = getTotalItems(itemsAndGroups);
}
return {
children,
filteredChildren
};
};
const assetGroup = assets => {
const assetGroup = (children, assets) => {
let size = 0;
for (const asset of assets) {
for (const asset of children) {
size += asset.size;
}
return {
@ -1308,10 +1260,25 @@ const assetGroup = assets => {
};
};
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
};
};
/** @type {Record<string, (groupConfigs: GroupConfig[], context: UsualContext, options: UsualOptions) => void>} */
const ASSETS_GROUPERS = {
_: (groupConfigs, context, options) => {
const groupByFlag = (name, exclude, greedy) => {
const groupByFlag = (name, exclude) => {
groupConfigs.push({
getKeys: asset => {
return asset[name] ? ["1"] : undefined;
@ -1319,8 +1286,7 @@ const ASSETS_GROUPERS = {
getOptions: () => {
return {
groupChildren: !exclude,
force: exclude,
greedy
force: exclude
};
},
createGroup: (key, children, assets) => {
@ -1329,13 +1295,13 @@ const ASSETS_GROUPERS = {
type: "assets by status",
[name]: !!key,
filteredChildren: assets.length,
...assetGroup(assets)
...assetGroup(children, assets)
}
: {
type: "assets by status",
[name]: !!key,
children, //...spaceLimited(children, options.assetsSpace),
...assetGroup(assets)
children,
...assetGroup(children, assets)
};
}
});
@ -1346,12 +1312,12 @@ const ASSETS_GROUPERS = {
groupAssetsByExtension
} = options;
if (groupAssetsByStatus) {
groupByFlag("emitted", false, true);
groupByFlag("comparedForEmit", false, true);
groupByFlag("isOverSizeLimit", false, true);
groupByFlag("emitted");
groupByFlag("comparedForEmit");
groupByFlag("isOverSizeLimit");
}
if (groupAssetsByStatus || !options.cachedAssets) {
groupByFlag("cached", !options.cachedAssets, true);
groupByFlag("cached", !options.cachedAssets);
}
if (groupAssetsByPath || groupAssetsByExtension) {
groupConfigs.push({
@ -1361,18 +1327,20 @@ const ASSETS_GROUPERS = {
const extension = extensionMatch ? extensionMatch[1] : "";
const pathMatch =
groupAssetsByPath && /(.+)[/\\][^/\\]+(?:\?.*|$)/.exec(asset.name);
const path = pathMatch ? pathMatch[1].split(/[/\\]/) : ["."];
const path = pathMatch ? pathMatch[1].split(/[/\\]/).concat("") : [];
const keys = [];
if (groupAssetsByPath) {
keys.push(`${path.join("/")}/`);
if (extension) keys.push(`${path.join("/")}/*${extension}`);
keys.push(path.join("/"));
if (extension) keys.push(`${path.join("/")}*${extension}`);
path.pop();
while (path.length > 0) {
keys.push(`${path.join("/")}/`);
if (extension) keys.push(`${path.join("/")}/**/*${extension}`);
path.pop();
path.push("");
while (path.length > 1) {
keys.push(path.join("/"));
path.pop();
path.pop();
path.push("");
}
if (extension) keys.push(`**/*${extension}`);
} else {
if (extension) keys.push(`*${extension}`);
}
@ -1380,10 +1348,10 @@ const ASSETS_GROUPERS = {
},
createGroup: (key, children, assets) => {
return {
type: "assets by path",
type: groupAssetsByPath ? "assets by path" : "assets by extension",
name: key,
children, //...spaceLimited(children, options.assetsSpace),
...assetGroup(assets)
children,
...assetGroup(children, assets)
};
}
});
@ -1401,8 +1369,8 @@ const ASSETS_GROUPERS = {
info: {
[name]: !!key
},
children, //...spaceLimited(children, options.assetsSpace),
...assetGroup(assets)
children,
...assetGroup(children, assets)
};
}
});
@ -1421,8 +1389,8 @@ const ASSETS_GROUPERS = {
return {
type: "assets by chunk",
[name]: [key],
children, //...spaceLimited(children, options.assetsSpace),
...assetGroup(assets)
children,
...assetGroup(children, assets)
};
}
});
@ -1441,22 +1409,162 @@ const ASSETS_GROUPERS = {
},
getOptions: () => ({
groupChildren: false,
force: true,
greedy: true
force: true
}),
createGroup: (key, assets) => ({
type: "excluded assets",
createGroup: (key, children, assets) => ({
type: "hidden assets",
filteredChildren: assets.length,
...assetGroup(assets)
...assetGroup(children, assets)
})
});
}
};
/** @type {function(string): Record<string, (groupConfigs: GroupConfig[], context: UsualContext, options: UsualOptions) => 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,
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.runtime) {
groupConfigs.push({
getKeys: module => {
return [module.moduleType.split("/", 1)[0]];
},
getOptions: key => {
const exclude = key === "runtime" && !options.runtime;
return {
groupChildren: !exclude,
force: exclude
};
},
createGroup: (key, children, modules) => {
const exclude = key === "runtime" && !options.runtime;
return {
type: `${key} modules`,
moduleType: key,
...(exclude ? { filteredChildren: modules.length } : { children }),
...moduleGroup(children, modules)
};
}
});
}
if (groupModulesByPath || groupModulesByExtension) {
groupConfigs.push({
getKeys: module => {
const resource = parseResource(module.name.split("!").pop()).path;
const extensionMatch =
groupModulesByExtension && /(\.[^.]+)(?:\?.*|$)/.exec(resource);
const extension = extensionMatch ? extensionMatch[1] : "";
const pathMatch =
groupModulesByPath && /(.+)[/\\][^/\\]+(?:\?.*|$)/.exec(resource);
const path = pathMatch ? pathMatch[1].split(/[/\\]/).concat("") : [];
const keys = [];
if (groupModulesByPath) {
keys.push(path.join("/"));
if (extension) keys.push(`${path.join("/")}*${extension}`);
path.pop();
path.pop();
path.push("");
while (path.length > 1) {
keys.push(path.join("/"));
path.pop();
path.pop();
path.push("");
}
} else {
if (extension) keys.push(`*${extension}`);
}
return keys;
},
createGroup: (key, children, modules) => {
return {
type: groupModulesByPath
? "modules by path"
: "modules by extension",
name: 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: UsualContext, options: UsualOptions) => void>>} */
const RESULT_GROUPERS = {
"compilation.assets": ASSETS_GROUPERS,
"asset.related": 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")
};
// remove a prefixed "!" that can be specified to reverse sort order
@ -1526,11 +1634,6 @@ const RESULT_SORTERS = {
comparators.push(sortByField(modulesSort));
}
},
"chunk.rootModules": {
chunkRootModulesSort: (comparators, context, { chunkRootModulesSort }) => {
comparators.push(sortByField(chunkRootModulesSort));
}
},
"chunk.modules": {
chunkModulesSort: (comparators, context, { chunkModulesSort }) => {
comparators.push(sortByField(chunkModulesSort));
@ -1590,6 +1693,7 @@ const ITEM_NAMES = {
"module.issuerPath[]": "moduleIssuer",
"module.reasons[]": "moduleReason",
"module.modules[]": "module",
"module.children[]": "module",
"moduleTrace[]": "moduleTraceItem",
"moduleTraceItem.dependencies[]": "moduleTraceDependency"
};
@ -1637,13 +1741,6 @@ class DefaultStatsFactoryPlugin {
fn(item, ctx, options, idx, i)
);
});
iterateConfig(FILTER_SORTED, options, (hookFor, fn) => {
stats.hooks.filterSorted
.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)
@ -1658,13 +1755,6 @@ class DefaultStatsFactoryPlugin {
fn(comparators, ctx, options)
);
});
iterateConfig(RESULT_GROUPERS, options, (hookFor, fn) => {
stats.hooks.groupResults
.for(hookFor)
.tap("DefaultStatsFactoryPlugin", (groupConfigs, ctx) =>
fn(groupConfigs, ctx, options)
);
});
iterateConfig(RESULT_SORTERS, options, (hookFor, fn) => {
stats.hooks.sortResults
.for(hookFor)
@ -1672,6 +1762,13 @@ class DefaultStatsFactoryPlugin {
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

View File

@ -28,7 +28,7 @@ const NAMED_PRESETS = {
chunks: true,
chunkRelations: true,
chunkModules: true,
chunkRootModules: false,
dependentModules: true,
chunkOrigins: true,
depth: true,
env: true,
@ -43,7 +43,8 @@ const NAMED_PRESETS = {
orphanModules: true,
runtime: true,
exclude: false,
maxModules: Infinity
modulesSpace: Infinity,
assetsSpace: Infinity
},
detailed: {
relatedAssets: true,
@ -53,7 +54,6 @@ const NAMED_PRESETS = {
chunks: true,
chunkRelations: true,
chunkModules: false,
chunkRootModules: false,
chunkOrigins: true,
depth: true,
usedExports: true,
@ -65,12 +65,15 @@ const NAMED_PRESETS = {
runtimeModules: true,
runtime: true,
exclude: false,
maxModules: Infinity
modulesSpace: Infinity,
assetsSpace: Infinity
},
minimal: {
all: false,
modules: true,
maxModules: 0,
modulesSpace: 0,
assets: true,
assetsSpace: 0,
errors: true,
warnings: true,
logging: "warn"
@ -99,7 +102,7 @@ const ON_FOR_TO_STRING = ({ all }, { forToString }) =>
const OFF_FOR_TO_STRING = ({ all }, { forToString }) =>
forToString ? all === true : all !== false;
/** @type {Record<string, (options: Object, context: { forToString: boolean }, compilation: Compilation) => any>} */
/** @type {Record<string, (options: Object, context: { forToString: boolean, cached: boolean }, compilation: Compilation) => any>} */
const DEFAULTS = {
context: (options, context, compilation) => compilation.compiler.context,
requestShortener: (options, context, compilation) =>
@ -117,26 +120,25 @@ const DEFAULTS = {
chunkGroups: OFF_FOR_TO_STRING,
chunks: OFF_FOR_TO_STRING,
chunkRelations: OFF_FOR_TO_STRING,
chunkModules: OFF_FOR_TO_STRING,
chunkRootModules: ({ all, chunkModules }, { forToString }) => {
if (all === false) return false;
if (all === true) return true;
if (forToString && chunkModules) return false;
return true;
},
chunkModules: NORMAL_ON,
dependentModules: OFF_FOR_TO_STRING,
chunkOrigins: OFF_FOR_TO_STRING,
ids: OFF_FOR_TO_STRING,
modules: (
{ all, chunks, chunkRootModules, chunkModules },
{ forToString }
) => {
modules: ({ all, chunks, chunkModules }, { forToString }) => {
if (all === false) return false;
if (all === true) return true;
if (forToString && chunks && (chunkModules || chunkRootModules))
return false;
if (forToString && chunks && chunkModules) return false;
return true;
},
nestedModules: OFF_FOR_TO_STRING,
groupModulesByType: ON_FOR_TO_STRING,
groupModulesByCacheStatus: 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,
groupAssetsByStatus: ON_FOR_TO_STRING,
groupAssetsByInfo: ON_FOR_TO_STRING,
@ -147,7 +149,8 @@ const DEFAULTS = {
orphanModules: NORMAL_OFF,
moduleAssets: OFF_FOR_TO_STRING,
depth: OFF_FOR_TO_STRING,
cached: NORMAL_ON,
cachedModules: ({ all }, { forToString, cached }) =>
cached !== undefined ? cached : forToString ? all === true : all !== false,
runtime: OFF_FOR_TO_STRING,
cachedAssets: OFF_FOR_TO_STRING,
reasons: OFF_FOR_TO_STRING,
@ -168,10 +171,8 @@ const DEFAULTS = {
loggingTrace: OFF_FOR_TO_STRING,
excludeModules: () => [],
excludeAssets: () => [],
maxModules: (o, { forToString }) => (forToString ? 15 : Infinity),
modulesSort: () => "depth",
chunkModulesSort: () => "name",
chunkRootModulesSort: () => "name",
nestedModulesSort: () => false,
chunksSort: () => false,
assetsSort: () => "name",

View File

@ -28,7 +28,6 @@
* @property {(size: number) => string} formatSize
* @property {(flag: string) => string} formatFlag
* @property {(time: number, boldQuantity?: boolean) => string} formatTime
* @property {number} maxModuleId
* @property {string} chunkGroupKind
*/
@ -105,25 +104,9 @@ const SIMPLE_PRINTERS = {
},
"compilation.assetsByChunkName": () => "",
"compilation.modules": (modules, context) => {
let maxModuleId = 0;
for (const module of modules) {
if (typeof module.id === "number") {
if (maxModuleId < module.id) maxModuleId = module.id;
}
}
context.maxModuleId = maxModuleId;
},
"compilation.filteredModules": (
filteredModules,
{ compilation: { modules } }
) =>
"compilation.filteredModules": filteredModules =>
filteredModules > 0
? ` ${
modules && modules.length > 0
? ` + ${filteredModules} hidden`
: filteredModules
} ${plural(filteredModules, "module", "modules")}`
? `${filteredModules} ${plural(filteredModules, "module", "modules")}`
: undefined,
"compilation.filteredAssets": (filteredAssets, { compilation: { assets } }) =>
filteredAssets > 0
@ -173,7 +156,7 @@ const SIMPLE_PRINTERS = {
"assets"
)}`
: undefined,
"asset.filteredChildren": (filteredChildren, { asset: { children } }) =>
"asset.filteredChildren": filteredChildren =>
filteredChildren > 0
? `${filteredChildren} ${plural(filteredChildren, "asset", "assets")}`
: undefined,
@ -183,10 +166,11 @@ const SIMPLE_PRINTERS = {
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 }) => bold(name),
"module.identifier": identifier => identifier,
"module.identifier": identifier => undefined,
"module.sizes": printSizes,
"module.chunks[]": (id, { formatChunkId }) => formatChunkId(id),
"module.depth": (depth, { formatFlag }) =>
@ -199,8 +183,14 @@ const SIMPLE_PRINTERS = {
runtime ? yellow(formatFlag("runtime")) : undefined,
"module.optional": (optional, { formatFlag, yellow }) =>
optional ? yellow(formatFlag("optional")) : undefined,
"module.built": (built, { formatFlag, green }) =>
built ? green(formatFlag("built")) : 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.cached": (cached, { formatFlag, green }) =>
cached ? green(formatFlag("cached")) : undefined,
"module.assets": (assets, { formatFlag, magenta }) =>
assets && assets.length
? magenta(
@ -209,16 +199,18 @@ const SIMPLE_PRINTERS = {
)
)
: undefined,
"module.failed": (failed, { formatFlag, red }) =>
failed ? red(formatFlag("failed")) : undefined,
"module.warnings": (warnings, { formatFlag, yellow }) =>
warnings
warnings === true
? yellow(formatFlag("warnings"))
: warnings
? yellow(
formatFlag(`${warnings} ${plural(warnings, "warning", "warnings")}`)
)
: undefined,
"module.errors": (errors, { formatFlag, red }) =>
errors
errors === true
? red(formatFlag("errors"))
: errors
? red(formatFlag(`${errors} ${plural(errors, "error", "errors")}`))
: undefined,
"module.providedExports": (providedExports, { formatFlag, cyan }) => {
@ -255,22 +247,17 @@ const SIMPLE_PRINTERS = {
"module.issuerPath": (issuerPath, { module }) =>
module.profile ? undefined : "",
"module.profile": profile => undefined,
"module.modules": (modules, context) => {
let maxModuleId = 0;
for (const module of modules) {
if (typeof module.id === "number") {
if (maxModuleId < module.id) maxModuleId = module.id;
}
}
context.maxModuleId = maxModuleId;
},
"module.filteredModules": (filteredModules, { compilation: { modules } }) =>
"module.filteredModules": filteredModules =>
filteredModules > 0
? ` ${
modules && modules.length > 0
? ` + ${filteredModules} hidden`
: filteredModules
} nested ${plural(filteredModules, "module", "modules")}`
? `${filteredModules} nested ${plural(
filteredModules,
"module",
"modules"
)}`
: undefined,
"module.filteredChildren": filteredChildren =>
filteredChildren > 0
? `${filteredChildren} ${plural(filteredChildren, "module", "modules")}`
: undefined,
"module.separator!": () => "\n",
@ -361,53 +348,13 @@ const SIMPLE_PRINTERS = {
"chunk.recorded": (recorded, { formatFlag, green }) =>
recorded ? green(formatFlag("recorded")) : undefined,
"chunk.reason": (reason, { yellow }) => (reason ? yellow(reason) : undefined),
"chunk.rootModules": (modules, context) => {
let maxModuleId = 0;
for (const module of modules) {
if (typeof module.id === "number") {
if (maxModuleId < module.id) maxModuleId = module.id;
}
}
context.maxModuleId = maxModuleId;
},
"chunk.filteredRootModules": (
filteredRootModules,
{ chunk: { rootModules } }
) =>
filteredRootModules > 0
? ` ${
rootModules && rootModules.length > 0
? ` + ${filteredRootModules} hidden`
: filteredRootModules
} root ${plural(filteredRootModules, "module", "modules")}`
: undefined,
"chunk.nonRootModules": (
nonRootModules,
{ chunk: { filteredRootModules, rootModules } }
) =>
nonRootModules > 0
? ` ${
(rootModules && rootModules.length > 0) || filteredRootModules > 0
? ` + ${nonRootModules} hidden`
: nonRootModules
} dependent ${plural(nonRootModules, "module", "modules")}`
: undefined,
"chunk.modules": (modules, context) => {
let maxModuleId = 0;
for (const module of modules) {
if (typeof module.id === "number") {
if (maxModuleId < module.id) maxModuleId = module.id;
}
}
context.maxModuleId = maxModuleId;
},
"chunk.filteredModules": (filteredModules, { chunk: { modules } }) =>
"chunk.filteredModules": filteredModules =>
filteredModules > 0
? ` ${
modules && modules.length > 0
? ` + ${filteredModules} hidden`
: filteredModules
} chunk ${plural(filteredModules, "module", "modules")}`
? `${filteredModules} chunk ${plural(
filteredModules,
"module",
"modules"
)}`
: undefined,
"chunk.separator!": () => "\n",
@ -500,10 +447,10 @@ const ITEM_NAMES = {
"asset.auxiliaryChunkNames[]": "assetChunkName",
"asset.auxiliaryChunkIdHints[]": "assetChunkIdHint",
"module.modules[]": "module",
"module.children[]": "module",
"module.reasons[]": "moduleReason",
"module.issuerPath[]": "moduleIssuer",
"chunk.origins[]": "chunkOrigin",
"chunk.rootModules[]": "module",
"chunk.modules[]": "module",
"loggingGroup.entries[]": logEntry =>
`loggingEntry(${logEntry.type}).loggingEntry`,
@ -588,9 +535,10 @@ const PREFERRED_ORDERS = {
"childAssets"
],
module: [
"id",
"type",
"name",
"identifier",
"id",
"sizes",
"chunks",
"depth",
@ -598,24 +546,24 @@ const PREFERRED_ORDERS = {
"orphan",
"runtime",
"optional",
"dependent",
"built",
"codeGenerated",
"cached",
"assets",
"failed",
"warnings",
"errors",
"separator!",
"children",
"filteredChildren",
"providedExports",
"separator!",
"usedExports",
"separator!",
"optimizationBailout",
"separator!",
"reasons",
"separator!",
"issuerPath",
"profile",
"separator!",
"modules"
"modules",
"filteredModules"
],
moduleReason: [
"active",
@ -657,12 +605,6 @@ const PREFERRED_ORDERS = {
"separator!",
"origins",
"separator!",
"rootModules",
"separator!",
"filteredRootModules",
"separator!",
"nonRootModules",
"separator!",
"modules",
"separator!",
"filteredModules"
@ -794,7 +736,7 @@ const joinExplicitNewLine = (items, indenter) => {
let first = true;
return items
.map(item => {
if (!item.content) return;
if (!item || !item.content) return;
let content = indent(item.content, first ? "" : indenter, !firstInLine);
if (firstInLine) {
content = content.replace(/^\n+/, "");
@ -844,6 +786,7 @@ const SIMPLE_ELEMENT_JOINERS = {
item.content
) {
return {
...item,
content: `\n${item.content}\n`
};
}
@ -852,40 +795,40 @@ const SIMPLE_ELEMENT_JOINERS = {
" "
),
"asset.info": joinOneLine,
module: (items, { module, maxModuleId }) => {
module: (items, { module }) => {
let hasName = false;
let indenter = " ";
if (maxModuleId >= 10) indenter += " ";
if (maxModuleId >= 100) indenter += " ";
if (maxModuleId >= 1000) indenter += " ";
let prefix = "";
if (typeof module.id === "number") {
if (module.id < 1000 && maxModuleId >= 1000) prefix += " ";
if (module.id < 100 && maxModuleId >= 100) prefix += " ";
if (module.id < 10 && maxModuleId >= 10) prefix += " ";
} else if (typeof module.id === "string" && module.id !== "") {
if (maxModuleId >= 1000) prefix += " ";
if (maxModuleId >= 100) prefix += " ";
if (maxModuleId >= 10) prefix += " ";
}
return (
prefix +
joinExplicitNewLine(
items.filter(item => {
return joinExplicitNewLine(
items.map(item => {
switch (item.element) {
case "id":
if (module.id === module.name && item.content) hasName = true;
if (module.id === module.name) {
if (hasName) return false;
if (item.content) hasName = true;
}
break;
case "name":
case "identifier":
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`
};
}
return true;
break;
}
return item;
}),
indenter
)
" "
);
},
chunk: items => {
@ -935,7 +878,7 @@ const SIMPLE_ELEMENT_JOINERS = {
},
"module.profile": joinInBrackets,
moduleIssuer: joinOneLine,
chunkOrigin: items => " > " + joinOneLine(items),
chunkOrigin: items => "> " + joinOneLine(items),
"errors[].error": joinError(true),
"warnings[].error": joinError(false),
loggingGroup: items => joinExplicitNewLine(items, "").trimRight(),

View File

@ -183,15 +183,6 @@ class StatsFactory {
return itemFactory.create(innerType, item, itemContext);
});
// group result items
const groupConfigs = [];
this._forEachLevel(this.hooks.groupResults, type, h =>
h.call(groupConfigs, context)
);
if (groupConfigs.length > 0) {
resultItems = smartGrouping(resultItems, groupConfigs);
}
// sort result items
const comparators2 = [];
this._forEachLevel(this.hooks.sortResults, type, h =>
@ -204,6 +195,15 @@ class StatsFactory {
);
}
// group result items
const groupConfigs = [];
this._forEachLevel(this.hooks.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,

View File

@ -180,7 +180,9 @@ class StatsPrinter {
if (result.length > 0) printResult = result.join("\n");
}
} else if (object !== null && typeof object === "object") {
const elements = Object.keys(object);
const elements = Object.keys(object).filter(
key => object[key] !== undefined
);
this._forEachLevel(this.hooks.sortElements, type, h =>
h.call(elements, context)
);

View File

@ -9,7 +9,7 @@
* @typedef {Object} GroupOptions
* @property {boolean=} groupChildren
* @property {boolean=} force
* @property {boolean=} greedy
* @property {number=} targetGroupCount
*/
/**
@ -90,6 +90,7 @@ const smartGrouping = (items, groupConfigs) => {
let bestGroupItems = undefined;
let bestGroupOptions = undefined;
for (const [group, items] of groupMap) {
if (items.size === 0) continue;
const [groupConfig, groupKey] = groupConfigMap.get(group);
const options =
groupConfig.getOptions &&
@ -97,19 +98,23 @@ const smartGrouping = (items, groupConfigs) => {
groupKey,
Array.from(items, ({ item }) => item)
);
if (items.size === 0) continue;
const force = options && options.force;
if (!force) {
if (bestGroupOptions && bestGroupOptions.force) continue;
if (usedGroups.has(group)) continue;
if (items.size <= 1 || totalSize - items.size <= 1) {
continue;
}
}
const greedy = options && options.greedy;
let sizeValue = greedy
? items.size
: Math.min(items.size, totalSize - items.size);
if (sizeValue > bestGroupSize) {
const targetGroupCount = (options && options.targetGroupCount) || 4;
let sizeValue = Math.min(
items.size,
(totalSize * 2) / targetGroupCount + itemsWithGroups.size - items.size
);
if (
sizeValue > bestGroupSize ||
(force && (!bestGroupOptions || !bestGroupOptions.force))
) {
bestGroup = group;
bestGroupSize = sizeValue;
bestGroupItems = items;
@ -120,35 +125,35 @@ const smartGrouping = (items, groupConfigs) => {
break;
}
const items = new Set(bestGroupItems);
const options = bestGroupOptions;
const groupChildren = !options || options.groupChildren !== false;
for (const item of items) {
itemsWithGroups.delete(item);
// Remove all groups that items have from the map to not select them again
for (const group of item.groups) {
const list = groupMap.get(group);
if (list !== undefined) list.delete(item);
if (groupChildren) {
usedGroups.add(group);
}
}
}
groupMap.delete(bestGroup);
const idx = bestGroup.indexOf(":");
const configKey = bestGroup.slice(0, idx);
const key = bestGroup.slice(idx + 1);
const groupConfig = groupConfigs[+configKey];
const options = bestGroupOptions;
const allItems = Array.from(items, ({ item }) => item);
alreadyGrouped.add(bestGroup);
const children =
options && options.groupChildren === false
? Array.from(items, ({ item }) => item)
: runGrouping(items);
const children = groupChildren ? runGrouping(items) : allItems;
alreadyGrouped.delete(bestGroup);
results.push(
groupConfig.createGroup(
key,
children,
Array.from(items, ({ item }) => item)
)
);
results.push(groupConfig.createGroup(key, children, allItems));
}
for (const { item } of itemsWithGroups) {
results.push(item);

View File

@ -28,6 +28,7 @@ const DID_YOU_MEAN = {
splitChunks: "optimization.splitChunks",
immutablePaths: "snapshot.immutablePaths",
managedPaths: "snapshot.managedPaths",
maxModules: "stats.modulesSpace",
hashedModuleIds:
'optimization.moduleIds: "hashed" (BREAKING CHANGE since webpack 5)',
namedChunks:

View File

@ -2980,6 +2980,10 @@
"description": "Show cached assets (setting this to `false` only shows emitted files).",
"type": "boolean"
},
"cachedModules": {
"description": "Add information about cached (not built) modules.",
"type": "boolean"
},
"children": {
"description": "Add children information.",
"type": "boolean"
@ -3000,10 +3004,6 @@
"description": "Add information about parent, children and sibling chunks to chunk information.",
"type": "boolean"
},
"chunkRootModules": {
"description": "Add root modules information to chunk information.",
"type": "boolean"
},
"chunks": {
"description": "Add chunk information.",
"type": "boolean"
@ -3056,6 +3056,10 @@
"type": "string",
"absolutePath": true
},
"dependentModules": {
"description": "Show chunk modules that are dependencies of other modules of the chunk.",
"type": "boolean"
},
"depth": {
"description": "Add module depth in module graph.",
"type": "boolean"
@ -3133,6 +3137,22 @@
"description": "Group assets by their status (emitted, compared for emit or cached).",
"type": "boolean"
},
"groupModulesByAttributes": {
"description": "Group modules by their attributes (errors, warnings, optional, orphan, or dependent).",
"type": "boolean"
},
"groupModulesByCacheStatus": {
"description": "Group modules by their status (cached or built and cacheable).",
"type": "boolean"
},
"groupModulesByExtension": {
"description": "Group modules by their extension.",
"type": "boolean"
},
"groupModulesByPath": {
"description": "Group modules by their path.",
"type": "boolean"
},
"hash": {
"description": "Add the hash of the compilation.",
"type": "boolean"
@ -3170,10 +3190,6 @@
"description": "Add stack traces to logging output.",
"type": "boolean"
},
"maxModules": {
"description": "Set the maximum number of modules to be shown.",
"type": "number"
},
"moduleAssets": {
"description": "Add information about assets inside modules.",
"type": "boolean"
@ -3190,6 +3206,10 @@
"description": "Sort the modules by that field.",
"type": "string"
},
"modulesSpace": {
"description": "Space to display modules (groups will be collapsed to fit this space, values is in number of modules/groups).",
"type": "number"
},
"nestedModules": {
"description": "Add information about modules nested in other modules (like with module concatenation).",
"type": "boolean"

View File

@ -3941,6 +3941,19 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"stats-cached-modules": Object {
"configs": Array [
Object {
"description": "Add information about cached (not built) modules.",
"multiple": false,
"path": "stats.cachedModules",
"type": "boolean",
},
],
"description": "Add information about cached (not built) modules.",
"multiple": false,
"simpleType": "boolean",
},
"stats-children": Object {
"configs": Array [
Object {
@ -4006,19 +4019,6 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"stats-chunk-root-modules": Object {
"configs": Array [
Object {
"description": "Add root modules information to chunk information.",
"multiple": false,
"path": "stats.chunkRootModules",
"type": "boolean",
},
],
"description": "Add root modules information to chunk information.",
"multiple": false,
"simpleType": "boolean",
},
"stats-chunks": Object {
"configs": Array [
Object {
@ -4149,6 +4149,19 @@ Object {
"multiple": false,
"simpleType": "string",
},
"stats-dependent-modules": Object {
"configs": Array [
Object {
"description": "Show chunk modules that are dependencies of other modules of the chunk.",
"multiple": false,
"path": "stats.dependentModules",
"type": "boolean",
},
],
"description": "Show chunk modules that are dependencies of other modules of the chunk.",
"multiple": false,
"simpleType": "boolean",
},
"stats-depth": Object {
"configs": Array [
Object {
@ -4362,6 +4375,58 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"stats-group-modules-by-attributes": Object {
"configs": Array [
Object {
"description": "Group modules by their attributes (errors, warnings, optional, orphan, or dependent).",
"multiple": false,
"path": "stats.groupModulesByAttributes",
"type": "boolean",
},
],
"description": "Group modules by their attributes (errors, warnings, optional, orphan, or dependent).",
"multiple": false,
"simpleType": "boolean",
},
"stats-group-modules-by-cache-status": Object {
"configs": Array [
Object {
"description": "Group modules by their status (cached or built and cacheable).",
"multiple": false,
"path": "stats.groupModulesByCacheStatus",
"type": "boolean",
},
],
"description": "Group modules by their status (cached or built and cacheable).",
"multiple": false,
"simpleType": "boolean",
},
"stats-group-modules-by-extension": Object {
"configs": Array [
Object {
"description": "Group modules by their extension.",
"multiple": false,
"path": "stats.groupModulesByExtension",
"type": "boolean",
},
],
"description": "Group modules by their extension.",
"multiple": false,
"simpleType": "boolean",
},
"stats-group-modules-by-path": Object {
"configs": Array [
Object {
"description": "Group modules by their path.",
"multiple": false,
"path": "stats.groupModulesByPath",
"type": "boolean",
},
],
"description": "Group modules by their path.",
"multiple": false,
"simpleType": "boolean",
},
"stats-hash": Object {
"configs": Array [
Object {
@ -4466,19 +4531,6 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"stats-max-modules": Object {
"configs": Array [
Object {
"description": "Set the maximum number of modules to be shown.",
"multiple": false,
"path": "stats.maxModules",
"type": "number",
},
],
"description": "Set the maximum number of modules to be shown.",
"multiple": false,
"simpleType": "number",
},
"stats-module-assets": Object {
"configs": Array [
Object {
@ -4531,6 +4583,19 @@ Object {
"multiple": false,
"simpleType": "string",
},
"stats-modules-space": Object {
"configs": Array [
Object {
"description": "Space to display modules (groups will be collapsed to fit this space, values is in number of modules/groups).",
"multiple": false,
"path": "stats.modulesSpace",
"type": "number",
},
],
"description": "Space to display modules (groups will be collapsed to fit this space, values is in number of modules/groups).",
"multiple": false,
"simpleType": "number",
},
"stats-nested-modules": Object {
"configs": Array [
Object {

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,6 @@ module.exports = [
[
/Module parse failed/,
{ moduleName: /dump-file\.txt/ },
{ moduleTrace: /templates sync/ }
{ moduleTrace: /templates\/ sync/ }
]
];

View File

@ -1,3 +1,7 @@
module.exports = [
[/Module parse failed/, {moduleName: /dump-file\.txt/}, {moduleTrace: /templates sync/}]
[
/Module parse failed/,
{ moduleName: /dump-file\.txt/ },
{ moduleTrace: /templates\/ sync/ }
]
];

View File

@ -22,6 +22,7 @@ module.exports = ["fitting", "content-change"].map(type => ({
stats: {
chunks: true,
chunkModules: true,
dependentModules: true,
chunkOrigins: true,
entrypoints: true,
modules: false,

View File

@ -19,6 +19,7 @@ module.exports = {
stats: {
chunks: true,
chunkModules: true,
dependentModules: true,
chunkOrigins: true,
entrypoints: true,
modules: false,

View File

@ -21,6 +21,7 @@ module.exports = {
stats: {
chunks: true,
chunkModules: true,
dependentModules: true,
chunkOrigins: true,
entrypoints: true,
modules: false,

View File

@ -10,6 +10,7 @@ module.exports = {
reasons: true,
chunks: true,
chunkModules: true,
dependentModules: true,
chunkRelations: true,
chunkOrigins: true,
modules: false,

View File

@ -10,6 +10,7 @@ module.exports = {
reasons: true,
chunks: true,
chunkModules: true,
dependentModules: true,
chunkRelations: true,
chunkOrigins: true,
modules: false,

View File

@ -13,6 +13,7 @@ module.exports = {
chunks: true,
chunkRelations: true,
chunkModules: true,
dependentModules: true,
modules: false
}
};

View File

@ -10,6 +10,7 @@ module.exports = {
reasons: true,
chunks: true,
chunkModules: true,
dependentModules: true,
chunkRelations: true,
chunkOrigins: true,
modules: false,

View File

@ -16,6 +16,7 @@ module.exports = {
chunks: true,
chunkRelations: true,
chunkModules: true,
dependentModules: true,
modules: false,
reasons: true
}

View File

@ -16,6 +16,7 @@ module.exports = {
chunks: true,
chunkRelations: true,
chunkModules: true,
dependentModules: true,
modules: false,
reasons: true
}

View File

@ -8,6 +8,7 @@ module.exports = {
stats: {
all: false,
chunks: true,
chunkRootModules: true
chunkModules: true,
dependentModules: false
}
};

View File

@ -14,6 +14,7 @@ module.exports = [1, 2, 3, 4].map(n => ({
],
stats: {
chunkModules: true,
dependentModules: true,
chunkRelations: true,
modules: false,
chunks: true

View File

@ -4,6 +4,6 @@ module.exports = {
entry: "./index",
performance: false,
stats: {
maxModules: 20
modulesSpace: 20
}
};

View File

@ -7,6 +7,7 @@ module.exports = {
chunkGroups: true,
chunks: true,
chunkModules: true,
dependentModules: true,
modules: true,
moduleAssets: true
},

View File

@ -15,6 +15,7 @@ module.exports = {
builtAt: false,
chunks: true,
chunkModules: true,
dependentModules: true,
modules: false
}
};

View File

@ -15,6 +15,7 @@ module.exports = {
builtAt: false,
chunks: true,
chunkModules: true,
dependentModules: true,
modules: false
}
};

View File

@ -9,6 +9,7 @@ module.exports = {
chunks: true,
chunkRelations: true,
chunkModules: true,
dependentModules: true,
chunkOrigins: true
}
};

View File

@ -4,7 +4,7 @@ module.exports = {
entry: "./index",
performance: false,
stats: {
maxModules: 20,
modulesSort: "!id"
modulesSpace: Infinity,
modulesSort: "!name"
}
};

View File

@ -8,6 +8,7 @@ const stats = {
usedExports: true,
chunks: true,
chunkModules: true,
dependentModules: true,
modules: true,
orphanModules: true,
nestedModules: true

View File

@ -3,7 +3,7 @@ const baseConfig = {
mode: "production",
entry: "./index",
stats: {
maxModules: Infinity,
modulesSpace: Infinity,
optimizationBailout: true,
nestedModules: true,
usedExports: true,

View File

@ -9,6 +9,7 @@ module.exports = {
stats: {
reasons: true,
chunkModules: true,
dependentModules: true,
chunkOrigins: true,
modules: true,
cached: true,

View File

@ -6,6 +6,7 @@ const stats = {
chunks: true,
chunkRelations: true,
chunkModules: true,
dependentModules: true,
chunkOrigins: true,
entrypoints: true,
modules: false

View File

@ -6,6 +6,7 @@ const stats = {
chunks: true,
chunkRelations: true,
chunkModules: true,
dependentModules: true,
chunkOrigins: true,
entrypoints: true,
modules: false

View File

@ -16,6 +16,7 @@ module.exports = {
stats: {
chunks: true,
chunkModules: true,
dependentModules: true,
modules: true
},
experiments: {

52
types.d.ts vendored
View File

@ -1245,6 +1245,7 @@ declare class Compilation {
usedModuleIds: Set<number>;
needAdditionalPass: boolean;
builtModules: WeakSet<Module>;
codeGeneratedModules: WeakSet<Module>;
emittedAssets: Set<string>;
comparedForEmitAssets: Set<string>;
fileDependencies: LazySet<string>;
@ -3203,7 +3204,7 @@ declare interface GroupConfig<T, R> {
declare interface GroupOptions {
groupChildren?: boolean;
force?: boolean;
greedy?: boolean;
targetGroupCount?: number;
}
declare interface HMRJavascriptParserHooks {
hotAcceptCallback: SyncBailHook<[any, string[]], void>;
@ -3414,7 +3415,8 @@ declare class JavascriptModulesPlugin {
): Source;
renderMain(
renderContext: MainRenderContext,
hooks: CompilationHooksJavascriptModulesPlugin
hooks: CompilationHooksJavascriptModulesPlugin,
compilation: Compilation
): Source;
renderBootstrap(
renderContext: RenderBootstrapContext,
@ -7395,6 +7397,7 @@ declare class RuntimeModule extends Module {
stage: number;
compilation: Compilation;
chunk: Chunk;
fullHash: boolean;
attach(compilation: Compilation, chunk: Chunk): void;
generate(): string;
getGeneratedCode(): string;
@ -8289,6 +8292,11 @@ declare interface StatsOptions {
*/
cachedAssets?: boolean;
/**
* Add information about cached (not built) modules.
*/
cachedModules?: boolean;
/**
* Add children information.
*/
@ -8314,11 +8322,6 @@ declare interface StatsOptions {
*/
chunkRelations?: boolean;
/**
* Add root modules information to chunk information.
*/
chunkRootModules?: boolean;
/**
* Add chunk information.
*/
@ -8366,6 +8369,11 @@ declare interface StatsOptions {
*/
context?: string;
/**
* Show chunk modules that are dependencies of other modules of the chunk.
*/
dependentModules?: boolean;
/**
* Add module depth in module graph.
*/
@ -8446,6 +8454,26 @@ declare interface StatsOptions {
*/
groupAssetsByStatus?: boolean;
/**
* Group modules by their attributes (errors, warnings, optional, orphan, or dependent).
*/
groupModulesByAttributes?: boolean;
/**
* Group modules by their status (cached or built and cacheable).
*/
groupModulesByCacheStatus?: boolean;
/**
* Group modules by their extension.
*/
groupModulesByExtension?: boolean;
/**
* Group modules by their path.
*/
groupModulesByPath?: boolean;
/**
* Add the hash of the compilation.
*/
@ -8476,11 +8504,6 @@ declare interface StatsOptions {
*/
loggingTrace?: boolean;
/**
* Set the maximum number of modules to be shown.
*/
maxModules?: number;
/**
* Add information about assets inside modules.
*/
@ -8501,6 +8524,11 @@ declare interface StatsOptions {
*/
modulesSort?: string;
/**
* Space to display modules (groups will be collapsed to fit this space, values is in number of modules/groups).
*/
modulesSpace?: number;
/**
* Add information about modules nested in other modules (like with module concatenation).
*/