test(css): add named-exports-mangling matrix coverage#20884
test(css): add named-exports-mangling matrix coverage#20884alexander-akait merged 8 commits intomainfrom
Conversation
Cover namedExports={true,false} x output.module={set,unset} x
exportsConvention={as-is,camel-case,camel-case-only,dashes,dashes-only}
in production mode, and assert CSS export values are mangled
to short identifiers.
https://claude.ai/code/session_01Dp4wfcAdJPVdZaBpvD1QNZ
|
|
|
This PR is packaged and the instant preview is available (ffbf36f). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@ffbf36f
yarn add -D webpack@https://pkg.pr.new/webpack@ffbf36f
pnpm add -D webpack@https://pkg.pr.new/webpack@ffbf36f |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #20884 +/- ##
==========================================
- Coverage 83.18% 78.93% -4.25%
==========================================
Files 530 496 -34
Lines 53878 52043 -1835
Branches 14218 13806 -412
==========================================
- Hits 44816 41081 -3735
- Misses 9062 10962 +1900
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Adds a new config case to broaden regression coverage for CSS Modules named export generation and export-value mangling, across a matrix of parser.namedExports, experiments/output.module, and generator.exportsConvention settings (in production mode).
Changes:
- Introduce a 4-cell config matrix for
{ namedExports: true/false } × { output.module: set/unset }, each exercising multipleexportsConventionmodes. - Add a test entry that dynamically imports each convention variant and asserts exported class values are mangled while
:export {}values remain unchanged. - Add
test.config.jsbundle discovery for the additional emitted convention-specific chunks (including.mjswhenoutputModuleis enabled).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| test/configCases/css/named-exports-mangling/webpack.config.js | Adds the 2×2 matrix configs and wires namedExports + exportsConvention per resourceQuery. |
| test/configCases/css/named-exports-mangling/test.config.js | Ensures the harness loads all expected convention chunk bundles and chooses .js vs .mjs based on outputModule. |
| test/configCases/css/named-exports-mangling/style.module.css | Provides a representative set of class names and :export entries to validate conventions and mangling behavior. |
| test/configCases/css/named-exports-mangling/index.js | Adds assertions for mangled export values across conventions and validates namespace shape differences for namedExports. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…s test
Make `optimization.concatenateModules` and `mangleExports` explicit in
all matrix configs, and replace the CSS class-name value mangling
checks with JS export-identifier mangling checks driven by
`__webpack_exports_info__.<name>.canMangle`.
A new `re-exports.js` module performs named re-exports of every CSS
variant so the compile-time exports-info API can confirm webpack will
mangle each JS export identifier. With concatenation enabled, that
re-exports module is merged into the entry — its long identifier
names (e.g. `asIsSimple`, `camelCaseBtnInfoIsDisabled`) do not appear
anywhere in the bundle output, demonstrating mangling actually occurred.
For the `namedExports: false` configs, the named re-exports
legitimately warn ("Should not import the named export X from
default-exporting module"); these are whitelisted via `ignoreWarnings`.
https://claude.ai/code/session_01Dp4wfcAdJPVdZaBpvD1QNZ
- Type the `conventions` array as `ExportsConventionLiteral[]` so TypeScript narrows to the `exportsConvention` enum (fixes the lint job failure on PR #20884). - Convert the second `it()` to use `.then(...).catch(done)` instead of `.then(onFulfilled, done)` — the two-callback form does not forward assertion failures thrown inside the fulfillment callback, so failures could surface as unhandled rejections / timeouts (Copilot review feedback). https://claude.ai/code/session_01Dp4wfcAdJPVdZaBpvD1QNZ
…lly mangle
Previously the test had two latent bugs that the user caught on review:
1. CSS modules were NOT concatenated. The dynamic
`import("./style.module.css?...")` calls in `index.js` created
alternate access paths to the same modules, which webpack flags as
"EXTERNAL MODULE" and excludes from the concatenation scope. The
bundle showed every CSS module as a separate runtime module with
full-string export keys.
2. JS export identifiers were NOT actually mangled — only the
`canMangle: true` *capability* flag was asserted via
`__webpack_exports_info__`. CSS modules only emit mangled
identifiers inside the concatenation scope (CssGenerator.js
#L472–497), so without (1), no mangling could happen.
Restructure:
- Switch to `target: "node"` and drop all dynamic imports — every
reference to a CSS variant is now a static import, so all five
modules inline into the entry scope.
- Split into two entry files (`index-named.js` for `namedExports:
true`, `index-default.js` for `namedExports: false`) selected per
config. Mangling requires named imports specifically — a namespace
import marks every export as observed-by-name and disables
mangling — but named imports don't compile against a default-only
module. The split avoids that conflict.
- Drop the `re-exports.js` proxy module and the
`__webpack_exports_info__.canMangle` assertions; replace with
direct bundle-source inspection that proves:
* No `EXTERNAL MODULE: css ./style.module.css?…` markers remain.
* No `__webpack_require__("./style.module.css?…")` calls remain.
* `__webpack_modules__` carries no CSS module entries.
* Original JS export identifiers (`btnInfoIsDisabled`, `fooBar`,
`btnInfo_isDisabled`, …) never appear as `const`/`let`/`var`
declarations in the entry bundle — they have been replaced by
mangled short names like `F0`, `bQ`, `zY`.
Bundle inspection runs only on the CJS configs; mangling and
concatenation behave identically across output modes, so we don't
plumb up an `import.meta.url`-based `__dirname` polyfill for the
ESM bundles.
https://claude.ai/code/session_01Dp4wfcAdJPVdZaBpvD1QNZ
Types CoverageCoverage after merging claude/test-named-exports-mangling-7b1sU into main will be
Coverage Report
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Cover namedExports={true,false} x output.module={set,unset} x
exportsConvention={as-is,camel-case,camel-case-only,dashes,dashes-only}
in production mode, and assert CSS export values are mangled
to short identifiers.
https://claude.ai/code/session_01Dp4wfcAdJPVdZaBpvD1QNZ