Skip to content

test(css): add named-exports-mangling matrix coverage#20884

Merged
alexander-akait merged 8 commits intomainfrom
claude/test-named-exports-mangling-7b1sU
Apr 28, 2026
Merged

test(css): add named-exports-mangling matrix coverage#20884
alexander-akait merged 8 commits intomainfrom
claude/test-named-exports-mangling-7b1sU

Conversation

@alexander-akait
Copy link
Copy Markdown
Member

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

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
Copilot AI review requested due to automatic review settings April 27, 2026 19:55
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 27, 2026

⚠️ No Changeset found

Latest commit: f71a434

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented Apr 27, 2026

CLA Not Signed

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

This PR is packaged and the instant preview is available (ffbf36f).

Install it locally:

  • npm
npm i -D webpack@https://pkg.pr.new/webpack@ffbf36f
  • yarn
yarn add -D webpack@https://pkg.pr.new/webpack@ffbf36f
  • pnpm
pnpm add -D webpack@https://pkg.pr.new/webpack@ffbf36f

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.93%. Comparing base (d6e5881) to head (f71a434).
⚠️ Report is 2 commits behind head on main.

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     
Flag Coverage Δ
integration 75.95% <ø> (-5.01%) ⬇️
test262 45.96% <ø> (-0.04%) ⬇️
unit 36.20% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 multiple exportsConvention modes.
  • 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.js bundle discovery for the additional emitted convention-specific chunks (including .mjs when outputModule is 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.

Comment thread test/configCases/css/named-exports-mangling/index.js Outdated
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 27, 2026

Merging this PR will degrade performance by 89.48%

⚡ 2 improved benchmarks
❌ 7 regressed benchmarks
✅ 135 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Memory benchmark "many-chunks-commonjs", scenario '{"name":"mode-production","mode":"production"}' 7.5 MB 9.8 MB -24.07%
Memory benchmark "many-chunks-esm", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' 136.8 KB 890.4 KB -84.64%
Memory benchmark "css-modules", scenario '{"name":"mode-production","mode":"production"}' 7 MB 9.5 MB -25.56%
Memory benchmark "many-modules-esm", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' 167.6 KB 1,593.7 KB -89.48%
Memory benchmark "wasm-modules-sync", scenario '{"name":"mode-production","mode":"production"}' 5.3 MB 6.9 MB -23.61%
Memory benchmark "side-effects-reexport", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' 848.5 KB 1,372.6 KB -38.18%
Memory benchmark "many-modules-esm", scenario '{"name":"mode-production","mode":"production"}' 8.9 MB 7.1 MB +24.96%
Memory benchmark "many-modules-commonjs", scenario '{"name":"mode-development","mode":"development"}' 1,140.5 KB 850.6 KB +34.09%
Memory benchmark "react", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' 171.1 KB 237.4 KB -27.93%

Comparing claude/test-named-exports-mangling-7b1sU (f71a434) with main (1674988)

Open in CodSpeed

claude and others added 4 commits April 27, 2026 20:43
…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
Comment thread test/configCases/css/named-exports-mangling/index-named.js Fixed
@github-actions
Copy link
Copy Markdown
Contributor

Types Coverage

Coverage after merging claude/test-named-exports-mangling-7b1sU into main will be
98.93%
Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
bin
   webpack.js98.77%100%100%98.77%91
examples
   build-common.js100%100%100%100%
   buildAll.js100%100%100%100%
   examples.js100%100%100%100%
   template-common.js98.21%100%100%98.21%72
examples/custom-javascript-parser
   test.filter.js100%100%100%100%
examples/custom-javascript-parser/internals
   acorn-parse.js100%100%100%100%
   meriyah-parse.js100%100%100%100%
   oxc-parse.js91.30%100%100%91.30%140, 142–143, 145, 147, 153–154, 161, 168, 90
examples/markdown
   webpack.config.mjs100%100%100%100%
examples/typescript
   test.filter.js50%100%100%50%5
examples/virtual-modules
   test.filter.js100%100%100%100%
examples/wasm-bindgen-esm
   test.filter.js100%100%100%100%
examples/wasm-complex
   test.filter.js100%100%100%100%
examples/wasm-simple
   test.filter.js100%100%100%100%
examples/wasm-simple-source-phase
   test.filter.js100%100%100%100%
lib
   APIPlugin.js100%100%100%100%
   AsyncDependenciesBlock.js100%100%100%100%
   AutomaticPrefetchPlugin.js100%100%100%100%
   BannerPlugin.js100%100%100%100%
   Cache.js98.21%100%100%98.21%101
   CacheFacade.js100%100%100%100%
   Chunk.js99.72%100%100%99.72%37
   ChunkGraph.js100%100%100%100%
   ChunkGroup.js100%100%100%100%
   ChunkTemplate.js100%100%100%100%
   CleanPlugin.js98.72%100%100%98.72%206, 226, 382
   CodeGenerationResults.js100%100%100%100%
   CompatibilityPlugin.js100%100%100%100%
   Compilation.js98.55%100%100%98.55%1554, 1850, 1857, 1865, 1887, 2783, 3208, 3870, 3899, 3952–3953, 3957, 3962, 3978–3979, 3993–3994, 3999–4000, 4477, 4503, 493, 498, 5211, 5292, 5307, 5332–5333, 5335, 5659, 5664, 5670, 5673, 5685, 5687, 5691, 5707, 5722, 5754, 5808, 5832, 5946, 712–713
   Compiler.js99.55%100%100%99.55%1116–1117, 1125
   ConcatenationScope.js98.59%100%100%98.59%189
   ConditionalInitFragment.js100%100%100%100%
   ConstPlugin.js100%100%100%100%
   ContextExclusionPlugin.js100%100%100%100%
   ContextModule.js100%100%100%100%
   ContextModuleFactory.js97.75%100%100%97.75%258, 393, 418, 443, 447, 458
   ContextReplacementPlugin.js100%100%100%100%
   DefinePlugin.js98.92%100%100%98.92%158–159, 175, 194, 268
   DependenciesBlock.js100%100%100%100%
   Dependency.js98.13%100%100%98.13%371, 404
   DependencyTemplate.js100%100%100%100%
   DependencyTemplates.js100%100%100%100%
   DotenvPlugin.js97.88%100%100%97.88%237, 378, 391–392
   DynamicEntryPlugin.js100%100%100%100%
   EntryOptionPlugin.js100%100%100%100%
   EntryPlugin.js100%100%100%100%
   Entrypoint.js100%100%100%100%
   EnvironmentPlugin.js97.14%100%100%97.14%49
   ErrorHelpers.js100%100%100%100%
   EvalDevToolModulePlugin.js100%100%100%100%
   EvalSourceMapDevToolPlugin.js100%100%100%100%
   ExportsInfo.js100%100%100%100%
   ExportsInfoApiPlugin.js100%100%100%100%
   ExternalModule.js98.89%100%100%98.89%399–403, 542
   ExternalModuleFactoryPlugin.js100%100%100%100%
   ExternalsPlugin.js100%100%100%100%
   FileSystemInfo.js99.49%100%100%99.49%182, 2213–2214, 2217, 2228, 2239, 2250, 278, 3596, 3611, 3635
   FlagAllModulesAsUsedPlugin.js100%100%100%100%
   FlagDependencyExportsPlugin.js98.74%100%100%98.74%399, 401, 405
   FlagDependencyUsagePlugin.js100%100%100%100%
   FlagEntryExportAsUsedPlugin.js100%100%100%100%
   Generator.js100%100%100%100%
   HotModuleReplacementPlugin.js100%100%100%100%
   HotUpdateChunk.js100%100%100%100%
   IgnorePlugin.js100%100%100%100%
   IgnoreWarningsPlugin.js100%100%100%100%
   InitFragment.js100%100%100%100%
   JavascriptMetaInfoPlugin.js100%100%100%100%
   LibraryTemplatePlugin.js100%100%100%100%
   LoaderOptionsPlugin.js100%100%100%100%
   LoaderTargetPlugin.js100%100%100%100%
   MainTemplate.js100%100%100%100%
   ManifestPlugin.js100%100%100%100%
   Module.js98.50%100%100%98.50%1304, 1309, 1370, 1384, 1446, 1455
   ModuleFactory.js100%100%100%100%
   ModuleFilenameHelpers.js98.85%100%100%98.85%106, 108
   ModuleGraph.js99.73%100%100%99.73%1004
   ModuleGraphConnection.js100%100%100%100%
   ModuleInfoHeaderPlugin.js100%100%100%100%
   ModuleProfile.js100%100%100%100%
   ModuleSourceTypeConstants.js100%100%100%100%
   ModuleTemplate.js100%100%100%100%
   ModuleTypeConstants.js100%100%100%100%
   MultiCompiler.js99.69%100%100%99.69%645
   MultiStats.js100%100%100%100%
   MultiWatching.js100%100%100%100%
   NoEmitOnErrorsPlugin.js100%100%100%100%
   NodeStuffPlugin.js100%100%100%100%
   NormalModule.js97.78%100%100%97.78%1020, 1036, 1123, 1774, 1779–1789, 708, 711, 728, 745, 986
   NormalModuleFactory.js99.47%100%100%99.47%1067, 1376, 466, 478
   NormalModuleReplacementPlugin.js100%100%100%100%
   NullFactory.js100%100%100%100%
   OptimizationStages.js100%100%100%100%
   OptionsApply.js100%100%100%100%
   Parser.js100%100%100%100%
   PlatformPlugin.js100%100%100%100%
   PrefetchPlugin.js100%100%100%100%
   ProgressPlugin.js98.75%100%100%98.75%446–447, 452, 454, 518
   ProvidePlugin.js100%100%100%100%
   RawModule.js100%100%100%100%
   RecordIdsPlugin.js100%100%100%100%
   RequestShortener.js100%100%100%100%
   ResolverFactory.js100%100%100%100%
   RuntimeGlobals.js100%100%100%100%
   RuntimeModule.js100%100%100%100%
   RuntimePlugin.js100%100%100%100%
   RuntimeTemplate.js100%100%100%100%
   SelfModuleFactory.js100%100%100%100%
   SingleEntryPlugin.js100%100%100%100%
   SourceMapDevToolModuleOptionsPlugin.js100%100%100%100%
   SourceMapDevToolPlugin.js99.16%100%100%99.16%267–268, 610
   Stats.js100%100%100%100%
   Template.js100%100%100%100%
   TemplatedPathPlugin.js98.86%100%100%98.86%134–135
   UseStrictPlugin.js100%100%100%100%
   WarnCaseSensitiveModulesPlugin.js100%100%100%100%
   WarnDeprecatedOptionPlugin.js100%100%100%100%
   WarnNoModeSetPlugin.js100%100%100%100%
   WatchIgnorePlugin.js100%100%100%100%
   Watching.js100%100%100%100%
   WebpackError.js100%100%100%100%
   WebpackIsIncludedPlugin.js100%100%100%100%
   WebpackOptionsApply.js100%100%100%100%
   WebpackOptionsDefaulter.js100%100%100%100%
   buildChunkGraph.js99.87%100%100%99.87%325
   cli.js98.71%100%100%98.71%117, 469, 501, 543, 813
   index.js100%100%100%100%
   validateSchema.js94.67%100%100%94.67%100, 87, 89, 98
   webpack.js97.22%100%100%97.22%196, 218, 220
lib/asset
   AssetBytesGenerator.js100%100%100%100%
   AssetBytesParser.js100%100%100%100%
   AssetGenerator.js100%100%100%100%
   AssetModulesPlugin.js97.77%100%100%97.77%285, 309, 312, 364, 40
   AssetParser.js100%100%100%100%
   AssetSourceGenerator.js100%100%100%100%
   AssetSourceParser.js100%100%100%100%
   RawDataUrlModule.js100%100%100%100%
lib/async-modules
   AsyncModuleHelpers.js100%100%100%100%
   AwaitDependenciesInitFragment.js100%100%100%100%
   InferAsyncModulesPlugin.js100%100%100%100%
lib/cache
   AddBuildDependenciesPlugin.js100%100%100%100%
   AddManagedPathsPlugin.js100%100%100%100%
   IdleFileCachePlugin.js97.92%100%100%97.92%71, 83, 91
   MemoryCachePlugin.js95.83%100%100%95.83%33
   MemoryWithGcCachePlugin.js93.15%100%100%93.15%106, 113–114, 122, 89
   PackFileCacheStrategy.js96.40%100%100%96.40%1250, 1350, 1354, 1416, 628, 647, 657–659, 661, 677–678, 683, 686, 688, 693, 698, 722, 728, 762, 768, 774, 779, 790, 799, 804–805, 807, 824, 830–831, 833
   ResolverCachePlugin.js100%100%100%100%
   getLazyHashedEtag.js100%100%100%100%
   mergeEtags.js100%100%100%100%
lib/config
   browserslistTargetHandler.js100%100%100%100%
   defaults.js99.13%100%100%99.13%1291–1293, 1301, 270, 273, 278, 282, 467
   normalization.js99%100%100%99%191–192, 258, 273
   target.js100%100%100%100%
lib/container
   ContainerEntryDependency.js100%100%100%100%
   ContainerEntryModule.js100%100%100%100%
   ContainerEntryModuleFactory.js100%100%100%100%
   ContainerExposedDependency.js100%100%100%100%
   ContainerPlugin.js100%100%100%100%
   ContainerReferencePlugin.js100%100%100%100%
   FallbackDependency.js100%100%100%100%
   FallbackItemDependency.js100%100%100%100%
   FallbackModule.js100%100%100%100%
   FallbackModuleFactory.js100%100%100%100%
   HoistContainerReferencesPlugin.js100%100%100%100%
   ModuleFederationPlugin.js100%100%100%100%
   RemoteModule.js100%100%100%100%
   RemoteRuntimeModule.js100%100%100%100%
   

@alexander-akait alexander-akait merged commit ffbf36f into main Apr 28, 2026
58 of 61 checks passed
@alexander-akait alexander-akait deleted the claude/test-named-exports-mangling-7b1sU branch April 28, 2026 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants