refactor: reduce duplication and name magic constants across lib, speed up AggressiveMergingPlugin - #21525
Conversation
The entrypoint-hint and HTML-hint collection paths each re-implemented the same 4-level chunk × module × dependency walk with the same triple-`instanceof` guard. Extract one `iterateHintedUrlAssets` generator (with a typed `isUrlAssetDep` guard) that both consume, add an `isCssOrHtmlUrlAssetDep` guard plus early-exit for the runtime-requirement pass, name the JS-chunk-file regexp, and spell out the loop variables. No behavior change.
Behavior-preserving cleanups across four modules: - RuntimePlugin: table-drive the ~15 mechanical `runtimeRequirementInTree` taps that only attach a zero-arg runtime module, and use PLUGIN_NAME for the two hardcoded tap names. - DefaultStatsPrinterPlugin: collapse the 12 identical `*_SIMPLE_PRINTERS` registration loops into one loop over the printer maps. - FileSystemInfo: name the Snapshot `_flags` bits (a serialized-cache format contract) instead of inline `0x10`..`0x1000` masks. - ModuleConcatenationPlugin: extract the 8 repeated failure-cache bail tails in `_tryToAdd` into a module-level helper (off the hot success path).
- HoistContainerReferencesPlugin: share one callback across the two federation dependency hooks and extract the duplicated runtime-chunk hoist loop into `hoistReferencedModules`. - IdHelpers: name the char-code and length literals in `avoidNumber` / `shortenLongString`. Byte-identical.
…che tables - AggressiveMergingPlugin only merges the single best chunk pair per pass (the hook re-runs after each merge), so track the max pair with a strict `>` scan instead of building and sorting the full O(chunks²) pair list every pass. Same pair chosen (a stable descending sort's `[0]` is the first-encountered max); no per-pass array allocation. ~20% faster on many-chunk builds using this plugin. - Compilation: clear `_restoredUnsafeCacheModuleEntries` / `_restoredUnsafeCacheEntries` in seal's finalCallback, next to the other make-phase bookkeeping already released there — they are only read during make.
PR SummaryMedium Risk Overview
Patch changeset only; no public API changes. Reviewed by Cursor Bugbot for commit b35dc23. Bugbot is set up for automated code reviews on this repo. Configure here. |
🦋 Changeset detectedLatest commit: b35dc23 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
This PR is packaged and the instant preview is available (e28262e). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@e28262e
yarn add -D webpack@https://pkg.pr.new/webpack@e28262e
pnpm add -D webpack@https://pkg.pr.new/webpack@e28262e |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1956798. Configure here.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #21525 +/- ##
========================================
Coverage 93.79% 93.79%
========================================
Files 620 620
Lines 73761 73276 -485
Branches 21289 21181 -108
========================================
- Hits 69183 68732 -451
+ Misses 4578 4544 -34
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Merging this PR will degrade performance by 20.09%
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing |
Types CoverageCoverage after merging refactor/lib-dedupe-and-constants into main will be
Coverage Report |
|
Regarding the CodSpeed memory report — I believe the flagged regression is measurement noise, not a real effect:
None of the changes here plausibly increase asset-module rebuild memory ( Generated by Claude Code |
|
The Root cause: the test crafts a payload via Everything else is green (full integration matrix across all OS/Node versions, Codecov patch + project). Will re-run once the base branch's Bun lane is fixed. Generated by Claude Code |

Summary
Behavior-preserving cleanups across several
lib/modules: deduplicate repeated logic, replace magic numbers / char-codes with named constants, and flatten nested conditionals into guard clauses — inResourceHintPlugin,RuntimePlugin,DefaultStatsPrinterPlugin,FileSystemInfo,ModuleConcatenationPlugin,HoistContainerReferencesPlugin, andIdHelpers.Also includes two measured optimizations:
AggressiveMergingPluginnow tracks the best chunk pair with a single scan instead of building and sorting the full O(chunks squared) pair list every pass (~20% faster on many-chunk builds using that plugin; the merged pair is identical, since a stable descending sort's first element is the first-encountered max), andCompilationreleases its unsafe-cache restore tables in seal'sfinalCallback, next to the other make-phase bookkeeping already cleared there (they are only read during make).No behavior change — the optimizations produce identical output.
What kind of change does this PR introduce?
refactor (primary); also a
perfoptimization (AggressiveMergingPlugin) and a memory release (Compilation).Did you add tests for your changes?
No new tests — every change is behavior-preserving and already exercised by the existing suite. The full
ConfigTestCases(8668 tests) andStatsTestCases(134 snapshots) pass unchanged, including the AggressiveMerging and splitChunks cases whose output is byte-identical.Does this PR introduce a breaking change?
No.
If relevant, what needs to be documented once your changes are merged or what have you already documented?
n/a
Use of AI
Yes. Claude (via Claude Code) was used to survey
lib/for refactor candidates, implement the changes, and run the test suites plus CPU/memory benchmarks. Each change was reviewed for behavior preservation; the two optimizations were validated with before/after measurements (the ~20% AggressiveMerging figure came from strict-alternation benchmarking), and candidate changes that did not measure as wins were discarded rather than shipped.🤖 Generated with Claude Code
https://claude.ai/code/session_01E6F4p5bU9iwDAcS23t4XjZ
Generated by Claude Code