statoscope: Chunks which are not used in an entry point are appearing in the Assets list for it and are being included in the entry-download-size-limits validation
Describe the bug I recently added the Statoscope CLI to my project to perform validation in bundle sizes. It’s awesome and I am enjoying the tool, however, upon optimizing some of my entry points I noticed weird behavior.
When changing imports to dynamic imports within one entry point, the module I’m importing gets added to the list of Assets for every other entry point which doesn’t use or import the module. This throws off my entry-download-size-limits validation rule and is visible within the Statoscope HTML report. However, when checking the stats file for some of the other entry points, I don’t see the asset there, nor is it loaded when actually running the application.
I am not sure if this is a bug or if something is up with my configuration but I haven’t been able to figure this out on my end so any discussion around this could be helpful!
To Reproduce Steps to reproduce the behavior:
- Setup multiple entry points
- Have one with no imports
- Have another with multiple imports, including dynamic imports to generate async chunks
- Observe that async chunks are included in the
entry-download-size-limitsvalidation rule and as Assets for the entry point with no imports
Expected behavior For my use case, I would expect only the chunks or assets that are required for a particular entry point to be included in the calculations and lists in the UI.
Screenshots If applicable, add screenshots to help explain your problem.
Stats file:

Statoscope UI:
This entry point actually only requires two of the chunks shown here, Statoscope seems to be pulling in the other initial and async chunks incorrectly.

Statoscope CLI validation:

Versions:
- Node (for non-browser bug):
- Browser (for browser-bug):
- Webpack: 5.73.0
- Statoscope: 5.22.0
Addition information: Looking at the entry-download-size-limits source it appears the default is to include all the children of each chunk with an entry point. I was able to find that my runtime chunk had a lot of children which aren’t used in the entry point in question. I wonder if this is included because the runtime chunk could technically fetch any of these at some point in time.
I am currently using optimization.runtimeChunk = "single" in my Webpack config. Setting optimization.runtimeChunk = false removes the runtime chunks and their children from appearing within all entry points, but the CLI validation errors persist.
I did some testing by modifying the source for entry-download-size-limits and I think that adding an exclusion option for chunks would help me work around this, without trying to modify the internals of Webpack on how it reports async chunks in the runtime. This is my first time using jora, so it’s pretty ugly, but it is serviceable.
diff --git a/packages/stats-validator-plugin-webpack/src/rules/entry-download-size-limits/index.ts b/packages/stats-validator-plugin-webpack/src/rules/entry-download-size-limits/index.ts
index 476b200..901c5fc 100644
--- a/packages/stats-validator-plugin-webpack/src/rules/entry-download-size-limits/index.ts
+++ b/packages/stats-validator-plugin-webpack/src/rules/entry-download-size-limits/index.ts
@@ -16,7 +16,7 @@ export type Limits = {
maxAsyncSize?: number;
};
-export type RuleExcludeItem = ExcludeItem<'compilation' | 'entry' | 'asset'>;
+export type RuleExcludeItem = ExcludeItem<'compilation' | 'entry' | 'asset' | 'chunk'>;
export type Params = {
exclude?: Array<string | RegExp | RuleExcludeItem>;
@@ -87,11 +87,12 @@ const entryDownloadSizeLimits: WebpackRule<Params> = (ruleParams, data, api): vo
$input: resolveInputFile();
$params: #.params;
$useCompressedSize: [$params.useCompressedSize, true].useNotNullish();
+ $getChunks: => $.data.chunks.exclude({ exclude: $params.exclude.[type='chunk'].name, get: <name> }).($ + $..children);
$getSizeByChunks: => files.exclude({
exclude: $params.exclude.[type='asset'].name,
get: <name>,
}).(getAssetSize($$, $useCompressedSize!=false)).reduce(=> size + $$, 0);
-
+
$input.compilations
.exclude({
exclude: $params.exclude.[type='compilation'].name,
@@ -113,13 +114,13 @@ const entryDownloadSizeLimits: WebpackRule<Params> = (ruleParams, data, api): vo
maxInitialSize: [$matchedRule.maxInitialSize, $params.global.maxInitialSize].useNotNullish(),
maxAsyncSize: [$matchedRule.maxAsyncSize, $params.global.maxAsyncSize].useNotNullish(),
};
- $chunks: ($entry.data.chunks + $entry.data.chunks..children);
+ $chunks: $entry.$getChunks();
$initialChunks: $chunks.[initial];
$asyncChunks: $chunks.[not initial];
$size: $chunks.$getSizeByChunks($compilation.hash);
$initialSize: $initialChunks.$getSizeByChunks($compilation.hash);
$asyncSize: $asyncChunks.$getSizeByChunks($compilation.hash);
-
+
$entry,
$chunks,
$initialChunks,
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 17 (10 by maintainers)
@hyshka Thanks for your issue and for your help. It made Statoscope better ☺️ I’m going to publish a stable version with chunk relations fix
@smelukov Thanks for taking a look at that, this covers everything within Statoscope for me than! Thanks so much for your help in resolving this, it is really appreciated. I am really enjoying Statoscope.
Both of my modules where this chunk is used load it async, so it seems like Webpack should not be marking chunk 144 as initial. I can confirm that chunk 144 is not loaded except for the pages which pull it in asynchronously. I will investigate this separately or report the bug to Webpack.
@hyshka Could you try 5.22.1-alpha.0 please? If it’ll fix your issue then I’ll publish a stable version
@hyshka Hello! Would you provide some stats-file (obviously without source code) that reproduces this behaviour? 😃 I can’t reproduce this with the steps you specified 😦