update webpack-sources for performance problem in hashing

add `stats.reasonsSpace` and `stats.groupReasonsByOrigin` to control large set of reasons
`detailed` preset limites all spaces to 1000 by default

fixes #13825
This commit is contained in:
Tobias Koppers 2021-07-20 11:52:46 +02:00
parent a87dba421a
commit d3f8e16810
17 changed files with 219 additions and 51 deletions

View File

@ -2481,6 +2481,10 @@ export interface StatsOptions {
* Group modules by their type.
*/
groupModulesByType?: boolean;
/**
* Group reasons by their origin module.
*/
groupReasonsByOrigin?: boolean;
/**
* Add the hash of the compilation.
*/
@ -2561,6 +2565,10 @@ export interface StatsOptions {
* Add information about the reasons why modules are included.
*/
reasons?: boolean;
/**
* Space to display reasons (groups will be collapsed to fit this space).
*/
reasonsSpace?: number;
/**
* Add information about assets that are related to other assets (like SourceMaps for assets).
*/

View File

@ -1182,11 +1182,14 @@ const SIMPLE_EXTRACTORS = {
type,
compilation: { moduleGraph }
} = context;
object.reasons = factory.create(
const groupsReasons = factory.create(
`${type.slice(0, -8)}.reasons`,
Array.from(moduleGraph.getIncomingConnections(module)),
context
);
const limited = spaceLimited(groupsReasons, options.reasonsSpace);
object.reasons = limited.children;
object.filteredReasons = limited.filteredChildren;
},
usedExports: (
object,
@ -1764,6 +1767,16 @@ const moduleGroup = (children, modules) => {
};
};
const reasonGroup = (children, reasons) => {
let active = false;
for (const reason of children) {
active = active || reason.active;
}
return {
active
};
};
/** @type {Record<string, (groupConfigs: GroupConfig[], context: StatsFactoryContext, options: NormalizedStatsOptions) => void>} */
const ASSETS_GROUPERS = {
_: (groupConfigs, context, options) => {
@ -2074,7 +2087,24 @@ const RESULT_GROUPERS = {
"compilation.modules": MODULES_GROUPERS("module"),
"chunk.modules": MODULES_GROUPERS("chunk"),
"chunk.rootModules": MODULES_GROUPERS("root-of-chunk"),
"module.modules": MODULES_GROUPERS("nested")
"module.modules": MODULES_GROUPERS("nested"),
"module.reasons": {
groupReasonsByOrigin: groupConfigs => {
groupConfigs.push({
getKeys: reason => {
return [reason.module];
},
createGroup: (key, children, reasons) => {
return {
type: "from origin",
module: key,
children,
...reasonGroup(children, reasons)
};
}
});
}
}
};
// remove a prefixed "!" that can be specified to reverse sort order

View File

@ -50,6 +50,7 @@ const NAMED_PRESETS = {
modulesSpace: Infinity,
chunkModulesSpace: Infinity,
assetsSpace: Infinity,
reasonsSpace: Infinity,
children: true
},
detailed: {
@ -72,8 +73,9 @@ const NAMED_PRESETS = {
logging: true,
runtimeModules: true,
exclude: false,
modulesSpace: Infinity,
assetsSpace: Infinity
modulesSpace: 1000,
assetsSpace: 1000,
reasonsSpace: 1000
},
minimal: {
all: false,
@ -194,6 +196,8 @@ const DEFAULTS = {
depth: OFF_FOR_TO_STRING,
cachedAssets: OFF_FOR_TO_STRING,
reasons: OFF_FOR_TO_STRING,
reasonsSpace: (o, { forToString }) => (forToString ? 15 : Infinity),
groupReasonsByOrigin: ON_FOR_TO_STRING,
usedExports: OFF_FOR_TO_STRING,
providedExports: OFF_FOR_TO_STRING,
optimizationBailout: OFF_FOR_TO_STRING,

View File

@ -374,6 +374,10 @@ const SIMPLE_PRINTERS = {
"modules"
)}`
: undefined,
"module.filteredReasons": filteredReasons =>
filteredReasons > 0
? `${filteredReasons} ${plural(filteredReasons, "reason", "reasons")}`
: undefined,
"module.filteredChildren": filteredChildren =>
filteredChildren > 0
? `${filteredChildren} ${plural(filteredChildren, "module", "modules")}`
@ -393,6 +397,10 @@ const SIMPLE_PRINTERS = {
"moduleReason.active": (active, { formatFlag }) =>
active ? undefined : formatFlag("inactive"),
"moduleReason.resolvedModule": (module, { magenta }) => magenta(module),
"moduleReason.filteredChildren": filteredChildren =>
filteredChildren > 0
? `${filteredChildren} ${plural(filteredChildren, "reason", "reasons")}`
: undefined,
"module.profile.total": (value, { formatTime }) => formatTime(value),
"module.profile.resolving": (value, { formatTime }) =>
@ -590,6 +598,7 @@ const ITEM_NAMES = {
"module.modules[]": "module",
"module.children[]": "module",
"module.reasons[]": "moduleReason",
"moduleReason.children[]": "moduleReason",
"module.issuerPath[]": "moduleIssuer",
"chunk.origins[]": "chunkOrigin",
"chunk.modules[]": "module",
@ -721,6 +730,7 @@ const PREFERRED_ORDERS = {
"usedExports",
"optimizationBailout",
"reasons",
"filteredReasons",
"issuerPath",
"profile",
"modules",
@ -734,7 +744,9 @@ const PREFERRED_ORDERS = {
"module",
"resolvedModule",
"loc",
"explanation"
"explanation",
"children",
"filteredChildren"
],
"module.profile": [
"total",
@ -1019,10 +1031,32 @@ const SIMPLE_ELEMENT_JOINERS = {
chunkGroupAsset: joinOneLine,
chunkGroupChildGroup: joinOneLine,
chunkGroupChild: joinOneLine,
// moduleReason: (items, { moduleReason }) => {
// let hasName = false;
// return joinOneLine(
// items.filter(item => {
// switch (item.element) {
// case "moduleId":
// if (moduleReason.moduleId === moduleReason.module && item.content)
// hasName = true;
// break;
// case "module":
// if (hasName) return false;
// break;
// case "resolvedModule":
// return (
// moduleReason.module !== moduleReason.resolvedModule &&
// item.content
// );
// }
// return true;
// })
// );
// },
moduleReason: (items, { moduleReason }) => {
let hasName = false;
return joinOneLine(
items.filter(item => {
return joinExplicitNewLine(
items.map(item => {
switch (item.element) {
case "moduleId":
if (moduleReason.moduleId === moduleReason.module && item.content)
@ -1032,13 +1066,21 @@ const SIMPLE_ELEMENT_JOINERS = {
if (hasName) return false;
break;
case "resolvedModule":
return (
moduleReason.module !== moduleReason.resolvedModule &&
item.content
);
if (moduleReason.module === moduleReason.resolvedModule)
return false;
break;
case "children":
if (item.content) {
return {
...item,
content: `\n${item.content}\n`
};
}
break;
}
return true;
})
return item;
}),
" "
);
},
"module.profile": joinInBrackets,

View File

@ -27,7 +27,7 @@
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.1.3",
"watchpack": "^2.2.0",
"webpack-sources": "^2.3.0"
"webpack-sources": "^2.3.1"
},
"peerDependenciesMeta": {
"webpack-cli": {

File diff suppressed because one or more lines are too long

View File

@ -4210,6 +4210,10 @@
"description": "Group modules by their type.",
"type": "boolean"
},
"groupReasonsByOrigin": {
"description": "Group reasons by their origin module.",
"type": "boolean"
},
"hash": {
"description": "Add the hash of the compilation.",
"type": "boolean"
@ -4314,6 +4318,10 @@
"description": "Add information about the reasons why modules are included.",
"type": "boolean"
},
"reasonsSpace": {
"description": "Space to display reasons (groups will be collapsed to fit this space).",
"type": "number"
},
"relatedAssets": {
"description": "Add information about assets that are related to other assets (like SourceMaps for assets).",
"type": "boolean"

View File

@ -252,7 +252,8 @@ const describeCases = config => {
const statOptions = {
preset: "verbose",
colors: false,
modules: true
modules: true,
reasonsSpace: 1000
};
fs.mkdirSync(outputDirectory, { recursive: true });
fs.writeFileSync(

View File

@ -7753,6 +7753,19 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"stats-group-reasons-by-origin": Object {
"configs": Array [
Object {
"description": "Group reasons by their origin module.",
"multiple": false,
"path": "stats.groupReasonsByOrigin",
"type": "boolean",
},
],
"description": "Group reasons by their origin module.",
"multiple": false,
"simpleType": "boolean",
},
"stats-hash": Object {
"configs": Array [
Object {
@ -8058,6 +8071,19 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"stats-reasons-space": Object {
"configs": Array [
Object {
"description": "Space to display reasons (groups will be collapsed to fit this space).",
"multiple": false,
"path": "stats.reasonsSpace",
"type": "number",
},
],
"description": "Space to display reasons (groups will be collapsed to fit this space).",
"multiple": false,
"simpleType": "number",
},
"stats-related-assets": Object {
"configs": Array [
Object {

View File

@ -3099,26 +3099,32 @@ cacheable modules 823 bytes
[inactive] harmony export imported specifier ./CompC ./components/src/index.js 2:0-43
./components/src/index.js 84 bytes [orphan] [built]
[module unused]
[inactive] harmony side effect evaluation ./components ./foo.js 1:0-37
[inactive] harmony import specifier ./components ./foo.js 3:20-25
[inactive] harmony side effect evaluation ./components ./main.js + 1 modules ./main.js 1:0-44
[inactive] harmony import specifier ./components ./main.js + 1 modules ./main.js 3:15-20
[inactive] harmony import specifier ./components ./main.js + 1 modules ./main.js 4:15-20
[inactive] from origin ./main.js + 1 modules
[inactive] harmony side effect evaluation ./components ./main.js + 1 modules ./main.js 1:0-44
[inactive] harmony import specifier ./components ./main.js + 1 modules ./main.js 3:15-20
[inactive] harmony import specifier ./components ./main.js + 1 modules ./main.js 4:15-20
[inactive] from origin ./foo.js
[inactive] harmony side effect evaluation ./components ./foo.js 1:0-37
[inactive] harmony import specifier ./components ./foo.js 3:20-25
code generated modules 186 bytes [code generated]
./components/src/CompAB/CompA.js 89 bytes [built] [code generated]
[only some exports used: default]
[inactive] harmony side effect evaluation ./CompA ./components/src/CompAB/index.js 1:0-43
[inactive] harmony export imported specifier ./CompA ./components/src/CompAB/index.js 1:0-43
[inactive] from origin ./components/src/CompAB/index.js
[inactive] harmony side effect evaluation ./CompA ./components/src/CompAB/index.js 1:0-43
[inactive] harmony export imported specifier ./CompA ./components/src/CompAB/index.js 1:0-43
[inactive] harmony export imported specifier ./CompAB ./components/src/index.js 1:0-40 (skipped side-effect-free modules)
harmony import specifier ./components ./foo.js 3:20-25 (skipped side-effect-free modules)
harmony import specifier ./components ./main.js + 1 modules ./main.js 3:15-20 (skipped side-effect-free modules)
./components/src/CompAB/utils.js 97 bytes [built] [code generated]
[inactive] harmony side effect evaluation ./utils ./components/src/CompAB/CompA.js 1:0-35
harmony import specifier ./utils ./components/src/CompAB/CompA.js 5:5-12
[inactive] harmony side effect evaluation ./utils ./components/src/CompAB/CompB.js 1:0-30
harmony import specifier ./utils ./components/src/CompAB/CompB.js 5:2-5
[inactive] harmony side effect evaluation ./utils ./main.js + 1 modules ./components/src/CompAB/CompB.js 1:0-30
harmony import specifier ./utils ./main.js + 1 modules ./components/src/CompAB/CompB.js 5:2-5
from origin ./components/src/CompAB/CompA.js
[inactive] harmony side effect evaluation ./utils ./components/src/CompAB/CompA.js 1:0-35
harmony import specifier ./utils ./components/src/CompAB/CompA.js 5:5-12
from origin ./components/src/CompAB/CompB.js
[inactive] harmony side effect evaluation ./utils ./components/src/CompAB/CompB.js 1:0-30
harmony import specifier ./utils ./components/src/CompAB/CompB.js 5:2-5
from origin ./main.js + 1 modules
[inactive] harmony side effect evaluation ./utils ./main.js + 1 modules ./components/src/CompAB/CompB.js 1:0-30
harmony import specifier ./utils ./main.js + 1 modules ./components/src/CompAB/CompB.js 5:2-5
./main.js + 1 modules 221 bytes [built] [code generated]
[no exports used]
entry ./main.js main
@ -3126,8 +3132,9 @@ cacheable modules 823 bytes
| [no exports used]
| ./components/src/CompAB/CompB.js 77 bytes [built]
| [only some exports used: default]
| [inactive] harmony side effect evaluation ./CompB ./components/src/CompAB/index.js 2:0-43
| [inactive] harmony export imported specifier ./CompB ./components/src/CompAB/index.js 2:0-43
| [inactive] from origin ./components/src/CompAB/index.js
| [inactive] harmony side effect evaluation ./CompB ./components/src/CompAB/index.js 2:0-43
| [inactive] harmony export imported specifier ./CompB ./components/src/CompAB/index.js 2:0-43
| [inactive] harmony export imported specifier ./CompAB ./components/src/index.js 1:0-40 (skipped side-effect-free modules)
| harmony import specifier ./components ./main.js 4:15-20 (skipped side-effect-free modules)
./foo.js 101 bytes [built] [code generated]
@ -3201,9 +3208,10 @@ exports[`StatsTestCases should print correct stats for side-effects-simple-unuse
| [inactive] harmony import specifier pmodule ./index.js 3:17-18
| ./node_modules/pmodule/c.js 28 bytes [built]
| [only some exports used: z]
| [inactive] from origin ./node_modules/pmodule/b.js
| [inactive] harmony side effect evaluation ./c ./node_modules/pmodule/b.js 5:0-24
| [inactive] harmony export imported specifier ./c ./node_modules/pmodule/b.js 5:0-24
| harmony import specifier pmodule ./index.js 3:17-18 (skipped side-effect-free modules)
| [inactive] harmony side effect evaluation ./c ./node_modules/pmodule/b.js 5:0-24
| [inactive] harmony export imported specifier ./c ./node_modules/pmodule/b.js 5:0-24
| [inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 (skipped side-effect-free modules)
./node_modules/pmodule/index.js 75 bytes [orphan] [built]
[only some exports used: default]
@ -3212,26 +3220,31 @@ exports[`StatsTestCases should print correct stats for side-effects-simple-unuse
[inactive] harmony import specifier pmodule ./index.js 3:17-18
./node_modules/pmodule/c.js 28 bytes [orphan] [built]
[only some exports used: z]
[inactive] from origin ./node_modules/pmodule/b.js
[inactive] harmony side effect evaluation ./c ./node_modules/pmodule/b.js 5:0-24
[inactive] harmony export imported specifier ./c ./node_modules/pmodule/b.js 5:0-24
harmony import specifier pmodule ./index.js 3:17-18 (skipped side-effect-free modules)
[inactive] harmony side effect evaluation ./c ./node_modules/pmodule/b.js 5:0-24
[inactive] harmony export imported specifier ./c ./node_modules/pmodule/b.js 5:0-24
[inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30 (skipped side-effect-free modules)
./node_modules/pmodule/a.js 60 bytes [orphan] [built]
[module unused]
[inactive] harmony side effect evaluation ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20
[inactive] harmony export imported specifier ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20
[inactive] harmony side effect evaluation ./a ./node_modules/pmodule/index.js 1:0-20
[inactive] harmony export imported specifier ./a ./node_modules/pmodule/index.js 1:0-20
[inactive] from origin ./index.js + 2 modules
[inactive] harmony side effect evaluation ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20
[inactive] harmony export imported specifier ./a ./index.js + 2 modules ./node_modules/pmodule/index.js 1:0-20
[inactive] from origin ./node_modules/pmodule/index.js
[inactive] harmony side effect evaluation ./a ./node_modules/pmodule/index.js 1:0-20
[inactive] harmony export imported specifier ./a ./node_modules/pmodule/index.js 1:0-20
./node_modules/pmodule/b.js 69 bytes [orphan] [built]
[module unused]
[inactive] harmony side effect evaluation ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony side effect evaluation ./b ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30
[inactive] from origin ./index.js + 2 modules
[inactive] harmony side effect evaluation ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./index.js + 2 modules ./node_modules/pmodule/index.js 2:0-30
[inactive] from origin ./node_modules/pmodule/index.js
[inactive] harmony side effect evaluation ./b ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30
[inactive] harmony export imported specifier ./b ./node_modules/pmodule/index.js 2:0-30
webpack x.x.x compiled successfully in X ms"
`;

View File

@ -0,0 +1,8 @@
/** @type {import("../../../../").RawLoaderDefinition<{ count: string }>} */
module.exports = function () {
const options = this.getOptions();
return `import thing from "./module";
export default [${Array.from({ length: +options.count }, () => "thing").join(
", "
)}].reduce((a, b) => a + b);`;
};

View File

@ -0,0 +1,11 @@
import a from "./generate-many-replacements-loader?count=1000!./module";
import b from "./generate-many-replacements-loader?count=10000!./module";
import c from "./generate-many-replacements-loader?count=100000!./module";
import d from "./generate-many-replacements-loader?count=1000000!./module";
it("should compile fine", () => {
expect(a).toBe(1000);
expect(b).toBe(10000);
expect(c).toBe(100000);
expect(d).toBe(1000000);
});

View File

@ -0,0 +1 @@
export default 1;

View File

@ -0,0 +1,3 @@
module.exports = {
timeout: 120000
};

View File

@ -0,0 +1,3 @@
module.exports = function (config) {
return !process.env.CI;
};

10
types.d.ts vendored
View File

@ -10899,6 +10899,11 @@ declare interface StatsOptions {
*/
groupModulesByType?: boolean;
/**
* Group reasons by their origin module.
*/
groupReasonsByOrigin?: boolean;
/**
* Add the hash of the compilation.
*/
@ -11004,6 +11009,11 @@ declare interface StatsOptions {
*/
reasons?: boolean;
/**
* Space to display reasons (groups will be collapsed to fit this space).
*/
reasonsSpace?: number;
/**
* Add information about assets that are related to other assets (like SourceMaps for assets).
*/

View File

@ -6157,10 +6157,10 @@ webpack-sources@^1.1.0:
source-list-map "^2.0.0"
source-map "~0.6.1"
webpack-sources@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.0.tgz#9ed2de69b25143a4c18847586ad9eccb19278cfa"
integrity sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==
webpack-sources@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd"
integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA==
dependencies:
source-list-map "^2.0.1"
source-map "^0.6.1"