test: add missing CSS test cases inspired by css-loader and mini-css-extract-plugin#20914
Conversation
…extract-plugin Add the following missing test cases under test/configCases/css/: css-loader: - empty.module.css: ensure importing an empty CSS module works (issue-1033 in css-loader) - component-name.module.css: cover PascalCase / mixed-case / UPPER class names - composes-chain.module.css: verify composes resolution across more than two levels mini-css-extract-plugin: - local-at-import-with-media.css and friends: cover local @import combined with media query, supports() and chained imports
…xtract-plugin Port additional regression / edge-case fixtures that exist in webpack-contrib/css-loader and webpack-contrib/mini-css-extract-plugin but were not yet covered by webpack core's built-in CSS support. css-loader: - file.with.many.dots.in.name.module.css (issue-980): file name with multiple dots produces a valid local ident - composes-duplicate.module.css: same imported class composed in multiple selectors of the same module - keyframes-leak-scope.module.css: @Keyframes with default :local, :global(...), :local(...) and animation/animation-name interaction - path-placeholder.module.css (issue-967): selectors with escaped filesystem-reserved chars mini-css-extract-plugin: - at-import-in-the-entry: external @import in an entry CSS that is imported after another entry CSS - at-import-chain: deep chain of local @imports - content-entries-with-same-import: two async chunks importing the same CSS files in different orders
Mini-css-extract-plugin's insert option is replaced in webpack core by the createStylesheet compilation hook on CssLoadingRuntimeModule, which lets a plugin patch the link element creation code. Add a test that demonstrates this and verifies the customization reaches the runtime. Also port two HMR cases from mini-css-extract-plugin that webpack core did not yet exercise: - imported-css-chain: HMR through @import a.css <- c.css <- index.css with a sibling b.css, mirrors mini-css-extract-plugin's hmr fixture - composes: HMR for a CSS module that composes from a sibling module, asserting both the link sheet content and the composed locals stay consistent across the update
… ignoreWarnings css-loader directory: - localIdentHashSalt alone, localIdentHashDigest = "hex"/"base64", localIdentHashFunction = "md4" + "base64url", and a combined salt + sha256 + hex + custom length variant. These exercise the rename of css-loader's hashSalt option to localIdentHashSalt and cover digest variants the existing fixture didn't reach. - at-value-extra.module.css: missing @value scenarios that aren't in css-modules/at-rule-value.module.css — @value composing imported values, @value inside func() positions, @value imported from a node_modules package (raw and via tilde alias), and a multi-step identifier chain. ignore-conflicting-order: - Same CSS chunk-merge that conflicting-order produces a warning for, but with ignoreWarnings: [/Conflicting order/] in the config. Verifies the warning is suppressed (no warnings.js fixture to match against).
…ests Lets the generator.exportsConvention function form return an array of names so a single class is exported under every alias in the array, mirroring css-loader's exportLocalsConvention function behaviour. Single-string returns continue to work unchanged. Tests: - exports-convention-function-array: function returning [name, name.toUpperCase()] exports both lower- and upper-case keys for the same class - createStylesheet-attributes: covers mini-css-extract-plugin's `attributes` and `linkType` plugin options by tapping CssLoadingRuntimeModule's createStylesheet hook to set id/data-* attributes and link.type - sync-class-names-between-targets: uses [file]__[local] localIdentName so web and node compilations produce identical class names with no getJSON-style cross-target sync needed - hotCases/css/hmr-extra-links: ports the unrelated-link scenarios from mini-css-extract-plugin's HMR.test.js (data:, # anchor, link without href, external stylesheet) so CSS HMR is shown to leave them alone across multiple sequential updates
🦋 Changeset detectedLatest commit: 609bd46 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 (959e210). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@959e210
yarn add -D webpack@https://pkg.pr.new/webpack@959e210
pnpm add -D webpack@https://pkg.pr.new/webpack@959e210 |
Codecov Report❌ Patch coverage is
❌ Your patch status has failed because the patch coverage (60.00%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #20914 +/- ##
==========================================
- Coverage 91.35% 91.34% -0.01%
==========================================
Files 562 563 +1
Lines 55736 55874 +138
Branches 14764 14815 +51
==========================================
+ Hits 50916 51039 +123
- Misses 4820 4835 +15
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
This PR expands webpack’s CSS-related test coverage across configCases and hotCases, and introduces a small enhancement to CSS Modules name exporting by allowing generator.exportsConvention (function form) to return multiple export names for a single local.
Changes:
- Add new CSS test cases covering additional CSS Modules behaviors (empty modules, mixed-case class names, deep
composeschains, hashing options, etc.). - Add new CSS runtime/HMR test cases to validate update behavior and link handling in the browser environment.
- Extend CSS Modules
generator.exportsConventionfunction form to acceptstring[](multiple aliases), update typings, and add a changeset + dedicated test coverage.
Reviewed changes
Copilot reviewed 84 out of 86 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| types.d.ts | Update generated typings to allow exportsConvention function to return string[]. |
| test/hotCases/css/imported-css-chain/webpack.config.js | Add hot-case webpack config for chained @import HMR scenario. |
| test/hotCases/css/imported-css-chain/test.filter.js | Restrict hot-case execution to target === "web". |
| test/hotCases/css/imported-css-chain/test.config.js | Configure jsdom environment for the hot-case. |
| test/hotCases/css/imported-css-chain/index.js | Add HMR test validating chained @import updates. |
| test/hotCases/css/imported-css-chain/index.css | CSS fixture with HMR update sections for chained imports. |
| test/hotCases/css/imported-css-chain/c.css | CSS import chain fixture (imports a.css). |
| test/hotCases/css/imported-css-chain/b.css | CSS fixture used by chained import case. |
| test/hotCases/css/imported-css-chain/a.css | CSS fixture with HMR update sections for background changes. |
| test/hotCases/css/hmr-extra-links/webpack.config.js | Add hot-case webpack config for link-preservation scenario. |
| test/hotCases/css/hmr-extra-links/test.filter.js | Restrict hot-case execution to target === "web". |
| test/hotCases/css/hmr-extra-links/test.config.js | Configure jsdom environment for the hot-case. |
| test/hotCases/css/hmr-extra-links/index.js | Add HMR test ensuring CSS HMR doesn’t touch unrelated <link> tags. |
| test/hotCases/css/hmr-extra-links/index.css | CSS fixture with multiple HMR updates. |
| test/hotCases/css/composes/webpack.config.js | Add hot-case webpack config for CSS Modules composes HMR scenario. |
| test/hotCases/css/composes/test.filter.js | Restrict hot-case execution to target === "web". |
| test/hotCases/css/composes/test.config.js | Configure jsdom environment for the hot-case. |
| test/hotCases/css/composes/style.module.css | CSS Modules fixture using composes, with HMR update sections. |
| test/hotCases/css/composes/shared.module.css | Shared composed CSS Modules fixture. |
| test/hotCases/css/composes/index.js | Add HMR test validating CSS Modules composes behavior across updates. |
| test/configCases/css/sync-class-names-between-targets/webpack.config.js | Add multi-target (web/node) config to verify deterministic classnames via [file]. |
| test/configCases/css/sync-class-names-between-targets/style.module.css | CSS Modules fixture including composed + mixed naming styles. |
| test/configCases/css/sync-class-names-between-targets/index.js | Assertion that web/node produce identical exported classnames. |
| test/configCases/css/mini-css-extract-plugin/test.config.js | Extend expected bundle list for additional mini-css-extract-plugin-inspired cases. |
| test/configCases/css/mini-css-extract-plugin/local-at-import-with-media.css | Add local @import fixture with media + supports conditions. |
| test/configCases/css/mini-css-extract-plugin/local-at-import-supports.css | Supports-condition import target fixture. |
| test/configCases/css/mini-css-extract-plugin/local-at-import-media-screen.css | Screen media import target fixture. |
| test/configCases/css/mini-css-extract-plugin/local-at-import-media-print.css | Print media import target fixture. |
| test/configCases/css/mini-css-extract-plugin/index.js | Add new mini-css-extract-plugin-inspired runtime tests + snapshots. |
| test/configCases/css/mini-css-extract-plugin/content-entries-two.js | Add async chunk entry importing shared CSS in a different order (two). |
| test/configCases/css/mini-css-extract-plugin/content-entries-style2.css | Shared CSS fixture (style2). |
| test/configCases/css/mini-css-extract-plugin/content-entries-style1.css | Shared CSS fixture (style1). |
| test/configCases/css/mini-css-extract-plugin/content-entries-one.js | Add async chunk entry importing shared CSS in a different order (one). |
| test/configCases/css/mini-css-extract-plugin/at-import-in-the-entry.js | JS entry that imports CSS files to test @import behavior at entry. |
| test/configCases/css/mini-css-extract-plugin/at-import-in-the-entry-b.css | CSS fixture containing an external @import url(...). |
| test/configCases/css/mini-css-extract-plugin/at-import-in-the-entry-a.css | CSS fixture for entry import case. |
| test/configCases/css/mini-css-extract-plugin/at-import-chain.js | JS entry for deep chained local @import test. |
| test/configCases/css/mini-css-extract-plugin/at-import-chain-bb.css | Deep chained import fixture (bb). |
| test/configCases/css/mini-css-extract-plugin/at-import-chain-ba.css | Deep chained import fixture (ba). |
| test/configCases/css/mini-css-extract-plugin/at-import-chain-b.css | Chained import fixture (b) that imports ba/bb. |
| test/configCases/css/mini-css-extract-plugin/at-import-chain-ae.css | Deep chained import fixture (ae). |
| test/configCases/css/mini-css-extract-plugin/at-import-chain-ad.css | Deep chained import fixture (ad). |
| test/configCases/css/mini-css-extract-plugin/at-import-chain-ac.css | Deep chained import fixture (ac). |
| test/configCases/css/mini-css-extract-plugin/at-import-chain-ab.css | Deep chained import fixture (ab). |
| test/configCases/css/mini-css-extract-plugin/at-import-chain-aa.css | Deep chained import fixture (aa). |
| test/configCases/css/mini-css-extract-plugin/at-import-chain-a.css | Chained import fixture (a) that imports aa–ae. |
| test/configCases/css/mini-css-extract-plugin/snapshots/ConfigTest.snap | Add snapshots for new mini-css-extract-plugin cases. |
| test/configCases/css/mini-css-extract-plugin/snapshots/ConfigCacheTest.snap | Add cache snapshots for new mini-css-extract-plugin cases. |
| test/configCases/css/insert-plugin/webpack.config.js | Add config case validating createStylesheet hook customization. |
| test/configCases/css/insert-plugin/test.config.js | Configure expected bundle outputs for insert-plugin test case. |
| test/configCases/css/insert-plugin/style.css | CSS fixture for insert-plugin test. |
| test/configCases/css/insert-plugin/index.js | Runtime assertion that createStylesheet hook modified the link element. |
| test/configCases/css/ignore-conflicting-order/webpack.config.js | Add config case ensuring ignoreWarnings can silence CSS conflicting-order warnings. |
| test/configCases/css/ignore-conflicting-order/test.config.js | Configure expected bundle outputs for ignore-conflicting-order case. |
| test/configCases/css/ignore-conflicting-order/lazy2.css | CSS fixture generating conflicting order (variant 2). |
| test/configCases/css/ignore-conflicting-order/lazy1.css | CSS fixture generating conflicting order (variant 1). |
| test/configCases/css/ignore-conflicting-order/index.js | Trigger compilation/runtime by importing both conflicting-order CSS entries. |
| test/configCases/css/ignore-conflicting-order/c.css | Conflicting-order shared import fixture (c). |
| test/configCases/css/ignore-conflicting-order/b.css | Conflicting-order shared import fixture (b). |
| test/configCases/css/ignore-conflicting-order/a.css | Conflicting-order shared import fixture (a). |
| test/configCases/css/exports-convention-function-array/webpack.config.js | Add config case enabling exportsConvention function returning string[]. |
| test/configCases/css/exports-convention-function-array/style.module.css | CSS Modules fixture with representative class names for alias exporting. |
| test/configCases/css/exports-convention-function-array/index.js | Assert both original and uppercase aliases export to the same local ident. |
| test/configCases/css/exports-convention-function-array/snapshots/ConfigTest.snap | Snapshot for exportsConvention array behavior (non-cache). |
| test/configCases/css/exports-convention-function-array/snapshots/ConfigCacheTest.snap | Snapshot for exportsConvention array behavior (cache). |
| test/configCases/css/css-loader/webpack.config.js | Extend css-loader-aligned config cases with additional local ident hash options. |
| test/configCases/css/css-loader/path-placeholder.module.css | Add fixture covering special-character/path-like local names. |
| test/configCases/css/css-loader/keyframes-leak-scope.module.css | Add fixture covering keyframes scoping/leak scenarios. |
| test/configCases/css/css-loader/index.js | Import and snapshot additional css-loader-aligned fixtures. |
| test/configCases/css/css-loader/imported-simple.module.css | Add fixture used for composes duplication tests. |
| test/configCases/css/css-loader/file.with.many.dots.in.name.module.css | Add fixture covering filenames with many dots. |
| test/configCases/css/css-loader/empty.module.css | Add empty CSS module fixture. |
| test/configCases/css/css-loader/composes-duplicate.module.css | Add fixture covering multiple composes from same source. |
| test/configCases/css/css-loader/composes-chain.module.css | Add fixture covering multi-level composes chains. |
| test/configCases/css/css-loader/component-name.module.css | Add fixture covering PascalCase/mixed-case/UPPER class names. |
| test/configCases/css/css-loader/colors.module.css | Add fixture supporting additional @value import tests. |
| test/configCases/css/css-loader/at-value-extra.module.css | Add fixture covering additional @value patterns and imports. |
| test/configCases/css/css-loader/snapshots/ConfigTest.snap | Update snapshots for expanded css-loader-aligned cases. |
| test/configCases/css/css-loader/snapshots/ConfigCacheTest.snap | Update cache snapshots for expanded css-loader-aligned cases. |
| test/configCases/css/createStylesheet-attributes/webpack.config.js | Add config case mirroring mini-css-extract-plugin link attribute behavior via hook. |
| test/configCases/css/createStylesheet-attributes/test.config.js | Configure expected bundle outputs for createStylesheet-attributes case. |
| test/configCases/css/createStylesheet-attributes/style.css | CSS fixture for createStylesheet-attributes case. |
| test/configCases/css/createStylesheet-attributes/index.js | Runtime assertions for link attributes/type set by createStylesheet hook. |
| lib/util/conventions.js | Enhance cssExportConvention to accept array returns from function conventions. |
| lib/dependencies/CssIcssExportDependency.js | Update ExportsConventionFn typedef to allow string[] return type. |
| .changeset/css-exports-convention-array.md | Add changeset documenting the minor feature for exportsConvention arrays. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| it("should work with local `@import` with media query, supports and layer", async () => { | ||
| await import("./local-at-import-with-media.css"); | ||
|
|
||
| const links = [...document.getElementsByTagName("link")]; | ||
|
|
||
| expect(links.find((item) => /local-at-import-with-media/.test(item.href)).sheet.css).toMatchSnapshot(); | ||
| }); |
| --- | ||
| "webpack": minor | ||
| --- | ||
|
|
||
| The `generator.exportsConvention` function form for CSS modules now accepts `string[]` in addition to `string`. Returning an array exports the local under every name in the array, matching `css-loader`'s behaviour and letting consumers expose multiple aliases (e.g. `[name, name.toUpperCase()]`) for a single class. |
| if (typeof convention === "function") { | ||
| set.add(convention(input)); | ||
| const result = convention(input); | ||
| if (Array.isArray(result)) { | ||
| for (const name of result) { | ||
| set.add(name); | ||
| } | ||
| } else { | ||
| set.add(result); | ||
| } |
| const findOurLink = () => | ||
| [...window.document.getElementsByTagName("link")].find( | ||
| (link) => | ||
| link.rel === "stylesheet" && | ||
| link.href && | ||
| link.href.includes("bundle.css") | ||
| ); | ||
|
|
||
| it("should not touch non-stylesheet, data:, anchor or external links during CSS HMR", (done) => { | ||
| const head = window.document.head; | ||
|
|
||
| expect(findOurLink().sheet.css).toContain("color: red;"); | ||
|
|
- mini-css-extract-plugin/local-at-import-with-media.css: add an @import "..." layer(layer-name) entry so the test name (which mentions "layer") now reflects the fixture coverage - lib/util/conventions.js: validate that exportsConvention function results are non-empty strings (or non-empty arrays of non-empty strings) and throw a clear error otherwise, so misconfigured conventions surface at compile time instead of crashing later - test/hotCases/css/hmr-extra-links: assert findOurLink() returns a link before dereferencing .sheet.css so a missing match fails with a readable expectation instead of "Cannot read properties of undefined"
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 85 out of 87 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const result = convention(input); | ||
| const validate = (name) => { | ||
| if (typeof name !== "string" || name.length === 0) { | ||
| throw new Error( | ||
| `exportsConvention function must return a non-empty string or an array of non-empty strings, got ${JSON.stringify(result)}` | ||
| ); | ||
| } |
- Fix tsc error: add a string type annotation on the validate callback parameter so noImplicitAny is satisfied. - Address Copilot review: JSON.stringify can throw for BigInt / circular values, masking the intended validation error. Wrap it in a safeStringify helper that falls back to String(...) and finally to a placeholder, so an invalid exportsConvention return type always surfaces the webpack error rather than a TypeError.
Types CoverageCoverage after merging claude/add-css-loader-tests-2jl6G into main will be
Coverage Report
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 85 out of 87 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| --- | ||
| "webpack": minor | ||
| --- | ||
|
|
||
| The `generator.exportsConvention` function form for CSS modules now accepts `string[]` in addition to `string`. Returning an array exports the local under every name in the array, matching `css-loader`'s behaviour and letting consumers expose multiple aliases (e.g. `[name, name.toUpperCase()]`) for a single class. |
Webpack 5.107 lets the generator.exportsConvention function for CSS modules return either a string or a string[]. Returning an array exports the local class under every name in the array, matching css-loader's behavior. Updates the type comments in the module.generator example and adds a dedicated subsection with a worked example. Refs: webpack/webpack#20914
…8240) Webpack 5.107 lets the generator.exportsConvention function for CSS modules return either a string or a string[]. Returning an array exports the local class under every name in the array, matching css-loader's behavior. Updates the type comments in the module.generator example and adds a dedicated subsection with a worked example. Refs: webpack/webpack#20914
Add the following missing test cases under test/configCases/css/:
css-loader:
mini-css-extract-plugin:
with media query, supports() and chained imports