add grouping of assets

This commit is contained in:
Tobias Koppers 2020-08-27 09:59:12 +02:00
parent bdeea6ec2f
commit 3ea9400505
12 changed files with 903 additions and 152 deletions

View File

@ -1861,6 +1861,10 @@ export interface StatsOptions {
* Sort the assets by that field.
*/
assetsSort?: string;
/**
* Space to display assets (groups will be collapsed to fit this space).
*/
assetsSpace?: number;
/**
* Add built at time information.
*/
@ -1976,6 +1980,26 @@ export interface StatsOptions {
* Suppress modules that match the specified filters. Filters can be Strings, RegExps, Booleans or Functions.
*/
excludeModules?: boolean | FilterTypes;
/**
* Group assets by how their are related to chunks.
*/
groupAssetsByChunk?: boolean;
/**
* Group assets by their extension.
*/
groupAssetsByExtension?: boolean;
/**
* Group assets by their asset info (immutable, development, hotModuleReplacement, etc).
*/
groupAssetsByInfo?: boolean;
/**
* Group assets by their path.
*/
groupAssetsByPath?: boolean;
/**
* Group assets by their status (emitted, compared for emit or cached).
*/
groupAssetsByStatus?: boolean;
/**
* Add the hash of the compilation.
*/

View File

@ -38,6 +38,7 @@ const identifierUtils = require("../util/identifier");
/** @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 {Asset & { type: string, related: ExtendedAsset[] }} ExtendedAsset */
@ -63,6 +64,11 @@ const identifierUtils = require("../util/identifier");
* @property {string} chunkModulesSort
* @property {string} nestedModulesSort
* @property {string} assetsSort
* @property {boolean} cachedAssets
* @property {boolean} groupAssetsByStatus
* @property {boolean} groupAssetsByPath
* @property {boolean} groupAssetsByExtension
* @property {number} assetsSpace
* @property {Function[]} excludeAssets
* @property {Function[]} excludeModules
* @property {Function[]} warningsFilter
@ -311,15 +317,12 @@ const SIMPLE_EXTRACTORS = {
}
}
}
object.assets = factory.create(`${type}.assets`, Array.from(assets), {
...context,
compilationFileToChunks,
compilationAuxiliaryFileToChunks
});
object.filteredAssets = assets.size - object.assets.length;
object.assetsByChunkName = {};
for (const asset of object.assets) {
for (const name of asset.chunkNames) {
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,
@ -328,9 +331,22 @@ const SIMPLE_EXTRACTORS = {
) {
object.assetsByChunkName[name] = [];
}
object.assetsByChunkName[name].push(asset.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;
@ -560,6 +576,7 @@ const SIMPLE_EXTRACTORS = {
object.comparedForEmit = compilation.comparedForEmitAssets.has(
asset.name
);
object.cached = !object.emitted && !object.comparedForEmit;
object.info = asset.info;
object.filteredRelated = asset.related ? asset.related.length : undefined;
},
@ -1033,26 +1050,8 @@ const BASE_MODULES_FILTER = {
}
};
const ASSETS_FILTER = {
excludeAssets: (asset, context, { excludeAssets }) => {
const ident = asset.name;
const excluded = excludeAssets.some(fn => fn(ident, asset));
if (excluded) return false;
},
"!cachedAssets": (asset, { compilation }) => {
if (
!compilation.emittedAssets.has(asset.name) &&
!compilation.comparedForEmitAssets.has(asset.name)
) {
return false;
}
}
};
/** @type {Record<string, Record<string, (thing: any, context: UsualContext, options: UsualOptions) => boolean | undefined>>} */
const FILTER = {
"compilation.assets": ASSETS_FILTER,
"asset.related": ASSETS_FILTER,
"compilation.modules": {
excludeModules: EXCLUDE_MODULES_FILTER("module"),
"!orphanModules": (module, { compilation: { chunkGraph } }) => {
@ -1195,6 +1194,271 @@ const SORTERS = {
}
};
const getTotalSize = children => {
let size = 0;
for (const child of children) {
size++;
if (child.children) size += getTotalSize(child.children);
}
return size;
};
const getTotalItems = children => {
let count = 0;
for (const child of children) {
if (child.children) count += getTotalItems(child.children);
else if (child.filteredChildren) count += child.filteredChildren;
else count++;
}
return count;
};
const collapse = children => {
const newChildren = [];
for (const child of children) {
let filteredChildren = child.filteredChildren || 0;
if (child.children) {
filteredChildren += getTotalItems(child.children);
}
newChildren.push(
filteredChildren
? {
...child,
children: undefined,
filteredChildren
}
: child
);
}
return newChildren;
};
const spaceLimited = (children, max) => {
const groups = children.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);
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) {
// collapse some groups, keep items
while (groupsSize + items.length > max) {
const oversize = items.length + groupsSize - max;
const maxGroupSize = Math.max(...groupSizes);
for (let i = 0; i < groups.length; i++) {
if (groupSizes[i] === maxGroupSize) {
const group = groups[i];
const limited = spaceLimited(
group.children,
groupSizes[i] - 1 - oversize / groups.length
);
groups[i] = {
...group,
children: limited.children,
filteredChildren:
(group.filteredChildren || 0) + limited.filteredChildren
};
const newSize = groups[i].children
? getTotalSize(groups[i].children) + 1
: 1;
groupsSize -= groupSizes[i] - newSize;
groupSizes[i] = newSize;
break;
}
}
}
return {
children: groups.concat(items),
filteredChildren: undefined
};
} else if (children.length === max) {
// collapse all groups and keep items
return {
children: collapse(groups).concat(items),
filteredChildren: undefined
};
} else if (groups.length + 1 <= max) {
// collapse all groups and items
return {
children: collapse(groups),
filteredChildren: items.length
};
} else {
// collapse complete group
return {
children: undefined,
filteredChildren: getTotalItems(children)
};
}
};
const assetGroup = assets => {
let size = 0;
for (const asset of assets) {
size += asset.size;
}
return {
size
};
};
/** @type {Record<string, (groupConfigs: GroupConfig[], context: UsualContext, options: UsualOptions) => void>} */
const ASSETS_GROUPERS = {
_: (groupConfigs, context, options) => {
const groupByFlag = (name, exclude, greedy) => {
groupConfigs.push({
getKeys: asset => {
return asset[name] ? ["1"] : undefined;
},
getOptions: () => {
return {
groupChildren: !exclude,
force: exclude,
greedy
};
},
createGroup: (key, children, assets) => {
return exclude
? {
type: "assets by status",
[name]: !!key,
filteredChildren: assets.length,
...assetGroup(assets)
}
: {
type: "assets by status",
[name]: !!key,
children, //...spaceLimited(children, options.assetsSpace),
...assetGroup(assets)
};
}
});
};
const {
groupAssetsByStatus,
groupAssetsByPath,
groupAssetsByExtension
} = options;
if (groupAssetsByStatus) {
groupByFlag("emitted", false, true);
groupByFlag("comparedForEmit", false, true);
groupByFlag("isOverSizeLimit", false, true);
}
if (groupAssetsByStatus || !options.cachedAssets) {
groupByFlag("cached", !options.cachedAssets, true);
}
if (groupAssetsByPath || groupAssetsByExtension) {
groupConfigs.push({
getKeys: asset => {
const extensionMatch =
groupAssetsByExtension && /(\.[^.]+)(?:\?.*|$)/.exec(asset.name);
const extension = extensionMatch ? extensionMatch[1] : "";
const pathMatch =
groupAssetsByPath && /(.+)[/\\][^/\\]+(?:\?.*|$)/.exec(asset.name);
const path = pathMatch ? pathMatch[1].split(/[/\\]/) : ["."];
const keys = [];
if (groupAssetsByPath) {
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();
}
if (extension) keys.push(`**/*${extension}`);
} else {
if (extension) keys.push(`*${extension}`);
}
return keys;
},
createGroup: (key, children, assets) => {
return {
type: "assets by path",
name: key,
children, //...spaceLimited(children, options.assetsSpace),
...assetGroup(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, //...spaceLimited(children, options.assetsSpace),
...assetGroup(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, //...spaceLimited(children, options.assetsSpace),
...assetGroup(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,
greedy: true
}),
createGroup: (key, assets) => ({
type: "excluded assets",
filteredChildren: assets.length,
...assetGroup(assets)
})
});
}
};
/** @type {Record<string, Record<string, (groupConfigs: GroupConfig[], context: UsualContext, options: UsualOptions) => void>>} */
const RESULT_GROUPERS = {
"compilation.assets": ASSETS_GROUPERS,
"asset.related": ASSETS_GROUPERS
};
// remove a prefixed "!" that can be specified to reverse sort order
const normalizeFieldKey = field => {
if (field[0] === "!") {
@ -1394,6 +1658,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)
);
});
iterateConfig(RESULT_SORTERS, options, (hookFor, fn) => {
stats.hooks.sortResults
.for(hookFor)

View File

@ -94,6 +94,8 @@ const NAMED_PRESETS = {
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;
@ -136,6 +138,12 @@ const DEFAULTS = {
},
nestedModules: OFF_FOR_TO_STRING,
relatedAssets: OFF_FOR_TO_STRING,
groupAssetsByStatus: 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: NORMAL_OFF,
moduleAssets: OFF_FOR_TO_STRING,
depth: OFF_FOR_TO_STRING,

View File

@ -127,11 +127,7 @@ const SIMPLE_PRINTERS = {
: undefined,
"compilation.filteredAssets": (filteredAssets, { compilation: { assets } }) =>
filteredAssets > 0
? `${
assets && assets.length > 0
? ` + ${filteredAssets} hidden`
: filteredAssets
} ${plural(filteredAssets, "asset", "assets")}`
? `${filteredAssets} ${plural(filteredAssets, "asset", "assets")}`
: undefined,
"compilation.logging": (logging, context, printer) =>
Array.isArray(logging)
@ -155,6 +151,8 @@ const SIMPLE_PRINTERS = {
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,
@ -169,11 +167,15 @@ const SIMPLE_PRINTERS = {
"asset.separator!": () => "\n",
"asset.filteredRelated": (filteredRelated, { asset: { related } }) =>
filteredRelated > 0
? `${
related && related.length > 0
? ` + ${filteredRelated} hidden`
: filteredRelated
} ${plural(filteredRelated, "related asset", "related assets")}`
? `${filteredRelated} related ${plural(
filteredRelated,
"asset",
"assets"
)}`
: undefined,
"asset.filteredChildren": (filteredChildren, { asset: { children } }) =>
filteredChildren > 0
? `${filteredChildren} ${plural(filteredChildren, "asset", "assets")}`
: undefined,
assetChunk: (id, { formatChunkId }) => formatChunkId(id),
@ -490,6 +492,7 @@ const ITEM_NAMES = {
"compilation.logging[]": "loggingGroup",
"compilation.children[]": "compilation",
"asset.related[]": "asset",
"asset.children[]": "asset",
"asset.chunks[]": "assetChunk",
"asset.auxiliaryChunks[]": "assetChunk",
"asset.chunkNames[]": "assetChunkName",
@ -562,6 +565,7 @@ const PREFERRED_ORDERS = {
"auxiliaryChunks",
"emitted",
"comparedForEmit",
"cached",
"info",
"isOverSizeLimit",
"chunkNames",
@ -569,6 +573,8 @@ const PREFERRED_ORDERS = {
"chunkIdHints",
"auxiliaryChunkIdHints",
"related",
"filteredRelated",
"children",
"filteredChildren"
],
"asset.info": ["immutable", "development", "hotModuleReplacement"],
@ -833,7 +839,10 @@ const SIMPLE_ELEMENT_JOINERS = {
asset: items =>
joinExplicitNewLine(
items.map(item => {
if (item.element === "related" && item.content) {
if (
(item.element === "related" || item.element === "children") &&
item.content
) {
return {
content: `\n${item.content}\n`
};

View File

@ -7,6 +7,9 @@
const { HookMap, SyncBailHook, SyncWaterfallHook } = require("tapable");
const { concatComparators, keepOriginalOrder } = require("../util/comparators");
const smartGrouping = require("../util/smartGrouping");
/** @typedef {import("../util/smartGrouping").GroupConfig<any, object>} GroupConfig */
class StatsFactory {
constructor() {
@ -25,6 +28,10 @@ class StatsFactory {
filterSorted: new HookMap(
() => new SyncBailHook(["item", "context", "index", "unfilteredIndex"])
),
/** @type {HookMap<SyncBailHook<[GroupConfig[], Object]>>} */
groupResults: new HookMap(
() => new SyncBailHook(["groupConfigs", "context"])
),
/** @type {HookMap<SyncBailHook<[(function(any, any): number)[], Object]>>} */
sortResults: new HookMap(
() => new SyncBailHook(["comparators", "context"])
@ -151,7 +158,7 @@ class StatsFactory {
);
// for each item
const resultItems = items2.map((item, i) => {
let resultItems = items2.map((item, i) => {
const itemContext = {
...context,
_index: i
@ -176,6 +183,15 @@ 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 =>

161
lib/util/smartGrouping.js Normal file
View File

@ -0,0 +1,161 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/**
* @typedef {Object} GroupOptions
* @property {boolean=} groupChildren
* @property {boolean=} force
* @property {boolean=} greedy
*/
/**
* @template T
* @template R
* @typedef {Object} GroupConfig
* @property {function(T): string[]} getKeys
* @property {function(string, (R | T)[], T[]): R} createGroup
* @property {function(string, T[]): GroupOptions=} getOptions
*/
/**
* @template T
* @typedef {Object} ItemWithGroups
* @property {T} item
* @property {Set<string>} groups
*/
/**
* @template T
* @template R
* @param {T[]} items the list of items
* @param {GroupConfig<T, R>[]} groupConfigs configuration
* @returns {(R | T)[]} grouped items
*/
const smartGrouping = (items, groupConfigs) => {
/** @type {Set<ItemWithGroups<T>>} */
const itemsWithGroups = new Set();
/** @type {Map<string, [GroupConfig<T, R>, string]>} */
const groupConfigMap = new Map();
for (const item of items) {
const groups = new Set();
for (let i = 0; i < groupConfigs.length; i++) {
const groupConfig = groupConfigs[i];
const keys = groupConfig.getKeys(item);
if (keys) {
for (const group of keys) {
const fullGroup = `${i}:${group}`;
if (!groupConfigMap.has(fullGroup)) {
groupConfigMap.set(fullGroup, [groupConfig, group]);
}
groups.add(fullGroup);
}
}
}
itemsWithGroups.add({
item,
groups
});
}
const alreadyGrouped = new Set();
/**
* @param {Set<ItemWithGroups<T>>} itemsWithGroups input items with groups
* @returns {(T | R)[]} groups items
*/
const runGrouping = itemsWithGroups => {
const totalSize = itemsWithGroups.size;
/** @type {Map<string, Set<ItemWithGroups<T>>>} */
const groupMap = new Map();
for (const entry of itemsWithGroups) {
for (const group of entry.groups) {
if (alreadyGrouped.has(group)) continue;
const list = groupMap.get(group);
if (list === undefined) {
groupMap.set(group, new Set([entry]));
} else {
list.add(entry);
}
}
}
/** @type {Set<string>} */
const usedGroups = new Set();
/** @type {(T | R)[]} */
const results = [];
for (;;) {
let bestGroup = undefined;
let bestGroupSize = -1;
let bestGroupItems = undefined;
let bestGroupOptions = undefined;
for (const [group, items] of groupMap) {
const [groupConfig, groupKey] = groupConfigMap.get(group);
const options =
groupConfig.getOptions &&
groupConfig.getOptions(
groupKey,
Array.from(items, ({ item }) => item)
);
if (items.size === 0) continue;
const force = options && options.force;
if (!force) {
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) {
bestGroup = group;
bestGroupSize = sizeValue;
bestGroupItems = items;
bestGroupOptions = options;
}
}
if (bestGroup === undefined) {
break;
}
const items = new Set(bestGroupItems);
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);
usedGroups.add(group);
}
}
const idx = bestGroup.indexOf(":");
const configKey = bestGroup.slice(0, idx);
const key = bestGroup.slice(idx + 1);
const groupConfig = groupConfigs[+configKey];
const options = bestGroupOptions;
alreadyGrouped.add(bestGroup);
const children =
options && options.groupChildren === false
? Array.from(items, ({ item }) => item)
: runGrouping(items);
alreadyGrouped.delete(bestGroup);
results.push(
groupConfig.createGroup(
key,
children,
Array.from(items, ({ item }) => item)
)
);
}
for (const { item } of itemsWithGroups) {
results.push(item);
}
return results;
};
return runGrouping(itemsWithGroups);
};
module.exports = smartGrouping;

View File

@ -2964,6 +2964,10 @@
"description": "Sort the assets by that field.",
"type": "string"
},
"assetsSpace": {
"description": "Space to display assets (groups will be collapsed to fit this space).",
"type": "number"
},
"builtAt": {
"description": "Add built at time information.",
"type": "boolean"
@ -3109,6 +3113,26 @@
}
]
},
"groupAssetsByChunk": {
"description": "Group assets by how their are related to chunks.",
"type": "boolean"
},
"groupAssetsByExtension": {
"description": "Group assets by their extension.",
"type": "boolean"
},
"groupAssetsByInfo": {
"description": "Group assets by their asset info (immutable, development, hotModuleReplacement, etc).",
"type": "boolean"
},
"groupAssetsByPath": {
"description": "Group assets by their path.",
"type": "boolean"
},
"groupAssetsByStatus": {
"description": "Group assets by their status (emitted, compared for emit or cached).",
"type": "boolean"
},
"hash": {
"description": "Add the hash of the compilation.",
"type": "boolean"

View File

@ -180,6 +180,7 @@ describe("Stats", () => {
Object {
"auxiliaryChunkIdHints": Array [],
"auxiliaryChunkNames": Array [],
"cached": false,
"chunkIdHints": Array [],
"chunkNames": Array [
"chunkB",
@ -198,6 +199,7 @@ describe("Stats", () => {
Object {
"auxiliaryChunkIdHints": Array [],
"auxiliaryChunkNames": Array [],
"cached": false,
"chunkIdHints": Array [],
"chunkNames": Array [
"entryA",
@ -216,6 +218,7 @@ describe("Stats", () => {
Object {
"auxiliaryChunkIdHints": Array [],
"auxiliaryChunkNames": Array [],
"cached": false,
"chunkIdHints": Array [],
"chunkNames": Array [
"entryB",
@ -243,7 +246,7 @@ describe("Stats", () => {
"entryB.js",
],
},
"filteredAssets": 0,
"filteredAssets": undefined,
}
`);
});

View File

@ -3889,6 +3889,19 @@ Object {
"multiple": false,
"simpleType": "string",
},
"stats-assets-space": Object {
"configs": Array [
Object {
"description": "Space to display assets (groups will be collapsed to fit this space).",
"multiple": false,
"path": "stats.assetsSpace",
"type": "number",
},
],
"description": "Space to display assets (groups will be collapsed to fit this space).",
"multiple": false,
"simpleType": "number",
},
"stats-built-at": Object {
"configs": Array [
Object {
@ -4284,6 +4297,71 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"stats-group-assets-by-chunk": Object {
"configs": Array [
Object {
"description": "Group assets by how their are related to chunks.",
"multiple": false,
"path": "stats.groupAssetsByChunk",
"type": "boolean",
},
],
"description": "Group assets by how their are related to chunks.",
"multiple": false,
"simpleType": "boolean",
},
"stats-group-assets-by-extension": Object {
"configs": Array [
Object {
"description": "Group assets by their extension.",
"multiple": false,
"path": "stats.groupAssetsByExtension",
"type": "boolean",
},
],
"description": "Group assets by their extension.",
"multiple": false,
"simpleType": "boolean",
},
"stats-group-assets-by-info": Object {
"configs": Array [
Object {
"description": "Group assets by their asset info (immutable, development, hotModuleReplacement, etc).",
"multiple": false,
"path": "stats.groupAssetsByInfo",
"type": "boolean",
},
],
"description": "Group assets by their asset info (immutable, development, hotModuleReplacement, etc).",
"multiple": false,
"simpleType": "boolean",
},
"stats-group-assets-by-path": Object {
"configs": Array [
Object {
"description": "Group assets by their path.",
"multiple": false,
"path": "stats.groupAssetsByPath",
"type": "boolean",
},
],
"description": "Group assets by their path.",
"multiple": false,
"simpleType": "boolean",
},
"stats-group-assets-by-status": Object {
"configs": Array [
Object {
"description": "Group assets by their status (emitted, compared for emit or cached).",
"multiple": false,
"path": "stats.groupAssetsByStatus",
"type": "boolean",
},
],
"description": "Group assets by their status (emitted, compared for emit or cached).",
"multiple": false,
"simpleType": "boolean",
},
"stats-hash": Object {
"configs": Array [
Object {

View File

@ -787,7 +787,7 @@ exports[`StatsTestCases should print correct stats for dll-reference-plugin-issu
"Hash: b838deba915153e63f86
Time: X ms
Built at: 1970-04-20 12:42:42
1 asset
assets by status 83 bytes [cached] 1 asset
Entrypoint main = bundle.js
./entry.js 29 bytes [built]
@ -823,8 +823,8 @@ exports[`StatsTestCases should print correct stats for exclude-with-loader 1`] =
"Hash: 0f9eb63e65113c4a3960
Time: X ms
Built at: 1970-04-20 12:42:42
excluded assets 34 bytes 1 asset
asset bundle.js 3.73 KiB [emitted] (name: main)
+ 1 hidden asset
Entrypoint main = bundle.js (89245aae14d2d745f85a29195aa6ffc1.json)
./index.js 77 bytes [built]
./a.txt 42 bytes [built]
@ -1020,8 +1020,9 @@ Child
Hash: 79ce0ce957b373f01199
Time: X ms
Built at: 1970-04-20 12:42:42
asset c-all-b_js-5d2ee8f74cbe1c7c24e8.js 502 bytes [emitted] [immutable] (id hint: all)
asset c-all-c_js-3f22b3dd1aa1ecb5f45e.js 393 bytes [emitted] [immutable] (id hint: all)
assets by chunk 895 bytes (id hint: all)
asset c-all-c_js-3f22b3dd1aa1ecb5f45e.js 393 bytes [emitted] [immutable] (id hint: all)
asset c-all-b_js-5d2ee8f74cbe1c7c24e8.js 502 bytes [emitted] [immutable] (id hint: all)
asset c-main-3737497cd09f5bd99fe3.js 603 bytes [emitted] [immutable] (name: main)
asset c-runtime~main-2769e1f5da93c44c8a70.js 12.4 KiB [emitted] [immutable] (name: runtime~main)
asset c-vendors-node_modules_vendor_js-93fc2ac2d261c82b4448.js 185 bytes [emitted] [immutable] (id hint: vendors)
@ -1228,11 +1229,13 @@ exports[`StatsTestCases should print correct stats for module-assets 1`] = `
"Hash: 7ef32e0d65af21479a68
Time: X ms
Built at: 1970-04-20 12:42:42
asset 1.png 21 KiB [emitted] (auxiliary name: a)
asset 2.png 21 KiB [emitted] (auxiliary name: a, b)
asset a.js 749 bytes [emitted] (name: a)
asset b.js 567 bytes [emitted] (name: b)
asset main.js 8.92 KiB [emitted] (name: main)
assets by path ./*.js 10.2 KiB
asset main.js 8.92 KiB [emitted] (name: main)
asset a.js 749 bytes [emitted] (name: a)
asset b.js 567 bytes [emitted] (name: b)
assets by path ./*.png 42 KiB
asset 1.png 21 KiB [emitted] (auxiliary name: a)
asset 2.png 21 KiB [emitted] (auxiliary name: a, b)
Entrypoint main = main.js
Chunk Group a = a.js (1.png 2.png)
Chunk Group b = b.js (2.png)
@ -1387,7 +1390,7 @@ Entrypoint main = main.js
exports[`StatsTestCases should print correct stats for module-trace-disabled-in-error 1`] = `
"Time: X ms
Built at: 1970-04-20 12:42:42
1 asset
assets by status 1.83 KiB [cached] 1 asset
Entrypoint main = main.js
./index.js 19 bytes [built]
./inner.js 53 bytes [built]
@ -1411,7 +1414,7 @@ You may need an appropriate loader to handle this file type, currently no loader
exports[`StatsTestCases should print correct stats for module-trace-enabled-in-error 1`] = `
"Time: X ms
Built at: 1970-04-20 12:42:42
1 asset
assets by status 1.83 KiB [cached] 1 asset
Entrypoint main = main.js
./index.js 19 bytes [built]
./inner.js 53 bytes [built]
@ -1523,7 +1526,7 @@ exports[`StatsTestCases should print correct stats for no-emit-on-errors-plugin-
"Hash: f140966bfd98188578d5
Time: X ms
Built at: 1970-04-20 12:42:42
2 assets
assets by status 108 bytes [cached] 2 assets
Entrypoint main = bundle.js
./index.js 1 bytes [built]
@ -1582,7 +1585,7 @@ chunk {753} (runtime: main) ac in ab.js (ac in ab) 1 bytes <{90}> >{284}< [rende
`;
exports[`StatsTestCases should print correct stats for parse-error 1`] = `
"1 asset
"assets by status 1.53 KiB [cached] 1 asset
Entrypoint main = main.js
./index.js + 1 modules 30 bytes [built]
./b.js 55 bytes [built] [failed] [1 error]
@ -2323,11 +2326,12 @@ Child a-normal:
Hash: dc13e801b7da230b06ce
Time: X ms
Built at: 1970-04-20 12:42:42
asset 3cc8faad16137711c07e-3cc8fa.js 210 bytes [emitted] [immutable] [minimized] (name: main)
asset 603191853c81e758567a-603191.js 2.09 KiB [emitted] [immutable] [minimized] (name: runtime~main)
assets by path ./*.js 2.48 KiB
asset 3cc8faad16137711c07e-3cc8fa.js 210 bytes [emitted] [immutable] [minimized] (name: main)
asset 603191853c81e758567a-603191.js 2.09 KiB [emitted] [immutable] [minimized] (name: runtime~main)
asset b6f77787a670e97d47b5-b6f777.js 193 bytes [emitted] [immutable] [minimized] (name: lazy)
asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] (auxiliary name: main)
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] (auxiliary name: lazy)
asset b6f77787a670e97d47b5-b6f777.js 193 bytes [emitted] [immutable] [minimized] (name: lazy)
Entrypoint main = 603191853c81e758567a-603191.js 3cc8faad16137711c07e-3cc8fa.js (7382fad5b015914e0811.jpg)
./a/index.js 150 bytes [built]
./a/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built]
@ -2338,11 +2342,12 @@ Child b-normal:
Hash: 5782ba854a23a6c889d0
Time: X ms
Built at: 1970-04-20 12:42:42
asset 3cc8faad16137711c07e-3cc8fa.js 210 bytes [emitted] [immutable] [minimized] (name: main)
asset 724d7409f0fb4e0b3145-724d74.js 2.09 KiB [emitted] [immutable] [minimized] (name: runtime~main)
assets by path ./*.js 2.48 KiB
asset 3cc8faad16137711c07e-3cc8fa.js 210 bytes [emitted] [immutable] [minimized] (name: main)
asset 724d7409f0fb4e0b3145-724d74.js 2.09 KiB [emitted] [immutable] [minimized] (name: runtime~main)
asset b6f77787a670e97d47b5-b6f777.js 193 bytes [emitted] [immutable] [minimized] (name: lazy)
asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] (auxiliary name: main)
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] (auxiliary name: lazy)
asset b6f77787a670e97d47b5-b6f777.js 193 bytes [emitted] [immutable] [minimized] (name: lazy)
Entrypoint main = 724d7409f0fb4e0b3145-724d74.js 3cc8faad16137711c07e-3cc8fa.js (7382fad5b015914e0811.jpg)
./b/index.js 109 bytes [built]
./b/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built]
@ -2353,14 +2358,15 @@ Child a-source-map:
Hash: dc13e801b7da230b06ce
Time: X ms
Built at: 1970-04-20 12:42:42
asset 2d2b84d5cc58d8742e65-2d2b84.js 2.14 KiB [emitted] [immutable] [minimized] (name: runtime~main)
sourceMap 2d2b84d5cc58d8742e65-2d2b84.js.map 12.6 KiB [emitted] [dev]
assets by path ./*.js 2.65 KiB
asset b8bfcec62cdd15c9a840-b8bfce.js 266 bytes [emitted] [immutable] [minimized] (name: main)
sourceMap b8bfcec62cdd15c9a840-b8bfce.js.map 366 bytes [emitted] [dev]
asset 2d2b84d5cc58d8742e65-2d2b84.js 2.14 KiB [emitted] [immutable] [minimized] (name: runtime~main)
sourceMap 2d2b84d5cc58d8742e65-2d2b84.js.map 12.6 KiB [emitted] [dev]
asset c7c0f8bb2e61b59a89f5-c7c0f8.js 249 bytes [emitted] [immutable] [minimized] (name: lazy)
sourceMap c7c0f8bb2e61b59a89f5-c7c0f8.js.map 331 bytes [emitted] [dev]
asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] (auxiliary name: main)
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] (auxiliary name: lazy)
asset b8bfcec62cdd15c9a840-b8bfce.js 266 bytes [emitted] [immutable] [minimized] (name: main)
sourceMap b8bfcec62cdd15c9a840-b8bfce.js.map 366 bytes [emitted] [dev]
asset c7c0f8bb2e61b59a89f5-c7c0f8.js 249 bytes [emitted] [immutable] [minimized] (name: lazy)
sourceMap c7c0f8bb2e61b59a89f5-c7c0f8.js.map 331 bytes [emitted] [dev]
Entrypoint main = 2d2b84d5cc58d8742e65-2d2b84.js b8bfcec62cdd15c9a840-b8bfce.js (608a3931b5c0c7b2c21f-608a39.js.map 7382fad5b015914e0811.jpg aff11f17e02d24be34cc-aff11f.js.map)
./a/index.js 150 bytes [built]
./a/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built]
@ -2371,14 +2377,15 @@ Child b-source-map:
Hash: 5782ba854a23a6c889d0
Time: X ms
Built at: 1970-04-20 12:42:42
assets by path ./*.js 2.65 KiB
asset b8bfcec62cdd15c9a840-b8bfce.js 266 bytes [emitted] [immutable] [minimized] (name: main)
sourceMap b8bfcec62cdd15c9a840-b8bfce.js.map 323 bytes [emitted] [dev]
asset ffe92bc2786746a99419-ffe92b.js 2.14 KiB [emitted] [immutable] [minimized] (name: runtime~main)
sourceMap ffe92bc2786746a99419-ffe92b.js.map 12.6 KiB [emitted] [dev]
asset c7c0f8bb2e61b59a89f5-c7c0f8.js 249 bytes [emitted] [immutable] [minimized] (name: lazy)
sourceMap c7c0f8bb2e61b59a89f5-c7c0f8.js.map 327 bytes [emitted] [dev]
asset 7382fad5b015914e0811.jpg 5.89 KiB [emitted] [immutable] (auxiliary name: main)
asset 89a353e9c515885abd8e.png 14.6 KiB [emitted] [immutable] (auxiliary name: lazy)
asset b8bfcec62cdd15c9a840-b8bfce.js 266 bytes [emitted] [immutable] [minimized] (name: main)
sourceMap b8bfcec62cdd15c9a840-b8bfce.js.map 323 bytes [emitted] [dev]
asset c7c0f8bb2e61b59a89f5-c7c0f8.js 249 bytes [emitted] [immutable] [minimized] (name: lazy)
sourceMap c7c0f8bb2e61b59a89f5-c7c0f8.js.map 327 bytes [emitted] [dev]
asset ffe92bc2786746a99419-ffe92b.js 2.14 KiB [emitted] [immutable] [minimized] (name: runtime~main)
sourceMap ffe92bc2786746a99419-ffe92b.js.map 12.6 KiB [emitted] [dev]
Entrypoint main = ffe92bc2786746a99419-ffe92b.js b8bfcec62cdd15c9a840-b8bfce.js (342ff4b0850c24f24b15-342ff4.js.map 6625d7a5b3c0dfc493c6-6625d7.js.map 7382fad5b015914e0811.jpg)
./b/index.js 109 bytes [built]
./b/file.jpg 42 bytes (javascript) 5.89 KiB (asset) [built]
@ -2389,79 +2396,102 @@ Child b-source-map:
exports[`StatsTestCases should print correct stats for related-assets 1`] = `
"Child default:
asset default-chunk_js.css 73 bytes [emitted] 3 related assets
asset default-chunk_js.js 1.11 KiB [emitted] 3 related assets
asset default-main.css 69 bytes [emitted] (name: main) 3 related assets
asset default-main.js 13.3 KiB [emitted] (name: main) 3 related assets
assets by path ./*.css 142 bytes
asset default-main.css 69 bytes [emitted] (name: main) 3 related assets
asset default-chunk_js.css 73 bytes [emitted] 3 related assets
assets by path ./*.js 14.4 KiB
asset default-main.js 13.3 KiB [emitted] (name: main) 3 related assets
asset default-chunk_js.js 1.11 KiB [emitted] 3 related assets
Child relatedAssets:
asset relatedAssets-chunk_js.css 79 bytes [emitted]
compressed relatedAssets-chunk_js.css.br 79 bytes [emitted]
compressed relatedAssets-chunk_js.css.gz 79 bytes [emitted]
sourceMap relatedAssets-chunk_js.css.map 197 bytes [emitted] [dev]
compressed relatedAssets-chunk_js.css.map.br 197 bytes [emitted]
compressed relatedAssets-chunk_js.css.map.gz 197 bytes [emitted]
asset relatedAssets-chunk_js.js 1.12 KiB [emitted]
compressed relatedAssets-chunk_js.js.br 1.12 KiB [emitted]
compressed relatedAssets-chunk_js.js.gz 1.12 KiB [emitted]
sourceMap relatedAssets-chunk_js.js.map 295 bytes [emitted] [dev]
compressed relatedAssets-chunk_js.js.map.br 295 bytes [emitted]
compressed relatedAssets-chunk_js.js.map.gz 295 bytes [emitted]
asset relatedAssets-main.css 75 bytes [emitted] (name: main)
compressed relatedAssets-main.css.br 75 bytes [emitted]
compressed relatedAssets-main.css.gz 75 bytes [emitted]
sourceMap relatedAssets-main.css.map 187 bytes [emitted] [dev] (auxiliary name: main)
compressed relatedAssets-main.css.map.br 187 bytes [emitted]
compressed relatedAssets-main.css.map.gz 187 bytes [emitted]
asset relatedAssets-main.js 13.3 KiB [emitted] (name: main)
compressed relatedAssets-main.js.br 13.3 KiB [emitted]
compressed relatedAssets-main.js.gz 13.3 KiB [emitted]
sourceMap relatedAssets-main.js.map 11.3 KiB [emitted] [dev] (auxiliary name: main)
compressed relatedAssets-main.js.map.br 11.3 KiB [emitted]
compressed relatedAssets-main.js.map.gz 11.3 KiB [emitted]
assets by path ./*.css 154 bytes
asset relatedAssets-main.css 75 bytes [emitted] (name: main)
compressed relatedAssets-main.css.br 75 bytes [emitted]
compressed relatedAssets-main.css.gz 75 bytes [emitted]
sourceMap relatedAssets-main.css.map 187 bytes [emitted] [dev] (auxiliary name: main)
compressed relatedAssets-main.css.map.br 187 bytes [emitted]
compressed relatedAssets-main.css.map.gz 187 bytes [emitted]
asset relatedAssets-chunk_js.css 79 bytes [emitted]
compressed relatedAssets-chunk_js.css.br 79 bytes [emitted]
compressed relatedAssets-chunk_js.css.gz 79 bytes [emitted]
sourceMap relatedAssets-chunk_js.css.map 197 bytes [emitted] [dev]
compressed relatedAssets-chunk_js.css.map.br 197 bytes [emitted]
compressed relatedAssets-chunk_js.css.map.gz 197 bytes [emitted]
assets by path ./*.js 14.4 KiB
asset relatedAssets-main.js 13.3 KiB [emitted] (name: main)
compressed relatedAssets-main.js.br 13.3 KiB [emitted]
compressed relatedAssets-main.js.gz 13.3 KiB [emitted]
sourceMap relatedAssets-main.js.map 11.3 KiB [emitted] [dev] (auxiliary name: main)
compressed relatedAssets-main.js.map.br 11.3 KiB [emitted]
compressed relatedAssets-main.js.map.gz 11.3 KiB [emitted]
asset relatedAssets-chunk_js.js 1.12 KiB [emitted]
compressed relatedAssets-chunk_js.js.br 1.12 KiB [emitted]
compressed relatedAssets-chunk_js.js.gz 1.12 KiB [emitted]
sourceMap relatedAssets-chunk_js.js.map 295 bytes [emitted] [dev]
compressed relatedAssets-chunk_js.js.map.br 295 bytes [emitted]
compressed relatedAssets-chunk_js.js.map.gz 295 bytes [emitted]
Child exclude1:
asset exclude1-chunk_js.css 74 bytes [emitted]
sourceMap exclude1-chunk_js.css.map 192 bytes [emitted] [dev] 2 related assets
+ 2 hidden related assets
asset exclude1-chunk_js.js 1.11 KiB [emitted]
sourceMap exclude1-chunk_js.js.map 290 bytes [emitted] [dev] 2 related assets
+ 2 hidden related assets
asset exclude1-main.css 70 bytes [emitted] (name: main)
sourceMap exclude1-main.css.map 182 bytes [emitted] [dev] (auxiliary name: main) 2 related assets
+ 2 hidden related assets
asset exclude1-main.js 13.3 KiB [emitted] (name: main)
sourceMap exclude1-main.js.map 11.3 KiB [emitted] [dev] (auxiliary name: main) 2 related assets
+ 2 hidden related assets
assets by path ./*.css 144 bytes
asset exclude1-main.css 70 bytes [emitted] (name: main)
sourceMap exclude1-main.css.map 182 bytes [emitted] [dev] (auxiliary name: main)
excluded assets 364 bytes 2 assets
1 related asset
excluded assets 140 bytes 2 assets
1 related asset
asset exclude1-chunk_js.css 74 bytes [emitted]
sourceMap exclude1-chunk_js.css.map 192 bytes [emitted] [dev]
excluded assets 384 bytes 2 assets
1 related asset
excluded assets 148 bytes 2 assets
1 related asset
assets by path ./*.js 14.4 KiB
asset exclude1-main.js 13.3 KiB [emitted] (name: main)
sourceMap exclude1-main.js.map 11.3 KiB [emitted] [dev] (auxiliary name: main)
excluded assets 22.7 KiB 2 assets
1 related asset
excluded assets 26.6 KiB 2 assets
1 related asset
asset exclude1-chunk_js.js 1.11 KiB [emitted]
sourceMap exclude1-chunk_js.js.map 290 bytes [emitted] [dev]
excluded assets 580 bytes 2 assets
1 related asset
excluded assets 2.22 KiB 2 assets
1 related asset
Child exclude2:
asset exclude2-chunk_js.css 74 bytes [emitted]
compressed exclude2-chunk_js.css.br 74 bytes [emitted]
compressed exclude2-chunk_js.css.gz 74 bytes [emitted]
+ 1 hidden related asset
asset exclude2-chunk_js.js 1.11 KiB [emitted]
compressed exclude2-chunk_js.js.br 1.11 KiB [emitted]
compressed exclude2-chunk_js.js.gz 1.11 KiB [emitted]
+ 1 hidden related asset
asset exclude2-main.css 70 bytes [emitted] (name: main)
compressed exclude2-main.css.br 70 bytes [emitted]
compressed exclude2-main.css.gz 70 bytes [emitted]
+ 1 hidden related asset
asset exclude2-main.js 13.3 KiB [emitted] (name: main)
compressed exclude2-main.js.br 13.3 KiB [emitted]
compressed exclude2-main.js.gz 13.3 KiB [emitted]
+ 1 hidden related asset
assets by path ./*.css 144 bytes
asset exclude2-main.css 70 bytes [emitted] (name: main)
compressed exclude2-main.css.br 70 bytes [emitted]
compressed exclude2-main.css.gz 70 bytes [emitted]
excluded assets 182 bytes 1 asset
asset exclude2-chunk_js.css 74 bytes [emitted]
compressed exclude2-chunk_js.css.br 74 bytes [emitted]
compressed exclude2-chunk_js.css.gz 74 bytes [emitted]
excluded assets 192 bytes 1 asset
assets by path ./*.js 14.4 KiB
asset exclude2-main.js 13.3 KiB [emitted] (name: main)
compressed exclude2-main.js.br 13.3 KiB [emitted]
compressed exclude2-main.js.gz 13.3 KiB [emitted]
excluded assets 11.3 KiB 1 asset
asset exclude2-chunk_js.js 1.11 KiB [emitted]
compressed exclude2-chunk_js.js.br 1.11 KiB [emitted]
compressed exclude2-chunk_js.js.gz 1.11 KiB [emitted]
excluded assets 290 bytes 1 asset
Child exclude3:
asset exclude3-main.css 70 bytes [emitted] (name: main)
compressed exclude3-main.css.br 70 bytes [emitted]
compressed exclude3-main.css.gz 70 bytes [emitted]
sourceMap exclude3-main.css.map 182 bytes [emitted] [dev] (auxiliary name: main)
compressed exclude3-main.css.map.br 182 bytes [emitted]
compressed exclude3-main.css.map.gz 182 bytes [emitted]
asset exclude3-main.js 13.3 KiB [emitted] (name: main)
compressed exclude3-main.js.br 13.3 KiB [emitted]
compressed exclude3-main.js.gz 13.3 KiB [emitted]
sourceMap exclude3-main.js.map 11.3 KiB [emitted] [dev] (auxiliary name: main)
compressed exclude3-main.js.map.br 11.3 KiB [emitted]
compressed exclude3-main.js.map.gz 11.3 KiB [emitted]
+ 2 hidden assets"
assets by path ./*.css 70 bytes
excluded assets 74 bytes 1 asset
asset exclude3-main.css 70 bytes [emitted] (name: main)
compressed exclude3-main.css.br 70 bytes [emitted]
compressed exclude3-main.css.gz 70 bytes [emitted]
sourceMap exclude3-main.css.map 182 bytes [emitted] [dev] (auxiliary name: main)
compressed exclude3-main.css.map.br 182 bytes [emitted]
compressed exclude3-main.css.map.gz 182 bytes [emitted]
assets by path ./*.js 13.3 KiB
excluded assets 1.11 KiB 1 asset
asset exclude3-main.js 13.3 KiB [emitted] (name: main)
compressed exclude3-main.js.br 13.3 KiB [emitted]
compressed exclude3-main.js.gz 13.3 KiB [emitted]
sourceMap exclude3-main.js.map 11.3 KiB [emitted] [dev] (auxiliary name: main)
compressed exclude3-main.js.map.br 11.3 KiB [emitted]
compressed exclude3-main.js.map.gz 11.3 KiB [emitted]"
`;
exports[`StatsTestCases should print correct stats for resolve-plugin-context 1`] = `
@ -4204,18 +4234,20 @@ exports[`StatsTestCases should print correct stats for wasm-explorer-examples-sy
"Hash: c96673e79f37716c681c
Time: X ms
Built at: 1970-04-20 12:42:42
asset 230.bundle.js 242 bytes [emitted]
asset 325.bundle.js 3.78 KiB [emitted]
asset 32796a220f44b00723d7.module.wasm 156 bytes [emitted] [immutable]
asset 526.bundle.js 364 bytes [emitted] (id hint: vendors)
asset 52ce624dd5de9c91cd19.module.wasm 531 bytes [emitted] [immutable]
asset 71ba3c2b7af4ee0e4b5c.module.wasm 120 bytes [emitted] [immutable]
asset 780.bundle.js 569 bytes [emitted]
asset 86f222634054d2a3b20f.module.wasm 154 bytes [emitted] [immutable]
asset 986b1b3cbdd7749989ee.module.wasm 290 bytes [emitted] [immutable]
asset 99.bundle.js 240 bytes [emitted]
asset a938d40645ba21696ec8.module.wasm 154 bytes [emitted] [immutable]
asset bundle.js 11.7 KiB [emitted] (name: main)
assets by path ./*.js 16.8 KiB
asset bundle.js 11.7 KiB [emitted] (name: main)
asset 325.bundle.js 3.78 KiB [emitted]
asset 526.bundle.js 364 bytes [emitted] (id hint: vendors)
asset 230.bundle.js 242 bytes [emitted]
asset 99.bundle.js 240 bytes [emitted]
asset 780.bundle.js 569 bytes [emitted]
assets by path ./*.wasm 1.37 KiB
asset 71ba3c2b7af4ee0e4b5c.module.wasm 120 bytes [emitted] [immutable]
asset a938d40645ba21696ec8.module.wasm 154 bytes [emitted] [immutable]
asset 32796a220f44b00723d7.module.wasm 156 bytes [emitted] [immutable]
asset 52ce624dd5de9c91cd19.module.wasm 531 bytes [emitted] [immutable]
asset 86f222634054d2a3b20f.module.wasm 154 bytes [emitted] [immutable]
asset 986b1b3cbdd7749989ee.module.wasm 290 bytes [emitted] [immutable]
Entrypoint main = bundle.js
chunk (runtime: main) 99.bundle.js 50 bytes (javascript) 531 bytes (webassembly) [rendered]
./duff.wasm 50 bytes (javascript) 531 bytes (webassembly) [built]

View File

@ -0,0 +1,84 @@
"use strict";
const smartGrouping = require("../lib/util/smartGrouping");
describe("util/smartGrouping", () => {
it("should group correctly", () => {
const groupConfigs = [
{
getKeys(item) {
return item.match(/\d+/g);
},
createGroup(key, items) {
return {
name: `has number ${key}`,
items
};
}
},
{
getKeys(item) {
return item.match(/\w+/g);
},
createGroup(key, items) {
return {
name: `has word ${key}`,
items
};
}
}
];
expect(
smartGrouping(
[
"hello world a",
"hello world b 2",
"hello world c",
"hello world d",
"hello test",
"hello more test",
"more test",
"more tests",
"1 2 3",
"2 3 4",
"3 4 5"
],
groupConfigs
)
).toMatchInlineSnapshot(`
Array [
Object {
"items": Array [
Object {
"items": Array [
"hello world a",
"hello world b 2",
"hello world c",
"hello world d",
],
"name": "has word world",
},
Object {
"items": Array [
"hello test",
"hello more test",
],
"name": "has word test",
},
],
"name": "has word hello",
},
Object {
"items": Array [
"1 2 3",
"2 3 4",
"3 4 5",
],
"name": "has number 3",
},
"more test",
"more tests",
]
`);
});
});

41
types.d.ts vendored
View File

@ -3195,6 +3195,16 @@ declare class Generator {
updateHash(hash: Hash, __1: UpdateHashContextGenerator): void;
static byType(map?: any): ByTypeGenerator;
}
declare interface GroupConfig<T, R> {
getKeys: (arg0: T) => string[];
createGroup: (arg0: string, arg1: (T | R)[], arg2: T[]) => R;
getOptions?: (arg0: string, arg1: T[]) => GroupOptions;
}
declare interface GroupOptions {
groupChildren?: boolean;
force?: boolean;
greedy?: boolean;
}
declare interface HMRJavascriptParserHooks {
hotAcceptCallback: SyncBailHook<[any, string[]], void>;
hotAcceptWithoutCallback: SyncBailHook<[any, string[]], void>;
@ -8227,6 +8237,7 @@ declare abstract class StatsFactory {
SyncBailHook<[((arg0?: any, arg1?: any) => number)[], any], any>
>;
filterSorted: HookMap<SyncBailHook<[any, any, number, number], any>>;
groupResults: HookMap<SyncBailHook<[GroupConfig<any, any>[], any], any>>;
sortResults: HookMap<
SyncBailHook<[((arg0?: any, arg1?: any) => number)[], any], any>
>;
@ -8258,6 +8269,11 @@ declare interface StatsOptions {
*/
assetsSort?: string;
/**
* Space to display assets (groups will be collapsed to fit this space).
*/
assetsSpace?: number;
/**
* Add built at time information.
*/
@ -8405,6 +8421,31 @@ declare interface StatsOptions {
| FilterItemTypes[]
| ((value: string) => boolean);
/**
* Group assets by how their are related to chunks.
*/
groupAssetsByChunk?: boolean;
/**
* Group assets by their extension.
*/
groupAssetsByExtension?: boolean;
/**
* Group assets by their asset info (immutable, development, hotModuleReplacement, etc).
*/
groupAssetsByInfo?: boolean;
/**
* Group assets by their path.
*/
groupAssetsByPath?: boolean;
/**
* Group assets by their status (emitted, compared for emit or cached).
*/
groupAssetsByStatus?: boolean;
/**
* Add the hash of the compilation.
*/