Skip to content

[Bug]: native css modules composes feature doesn't work with exportsConvention: 'camel-case' #11854

@ItamarGronich

Description

@ItamarGronich

System Info

  System:
    OS: macOS 14.8.1
    CPU: (10) arm64 Apple M2 Pro
    Memory: 117.78 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 24.4.1 - /Users/itamar.gronich/.nvm/versions/node/v24.4.1/bin/node
    Yarn: 1.22.22 - /Users/itamar.gronich/.nvm/versions/node/v24.4.1/bin/yarn
    npm: 11.4.2 - /Users/itamar.gronich/.nvm/versions/node/v24.4.1/bin/npm
    pnpm: 9.15.9 - /Users/itamar.gronich/.nvm/versions/node/v24.4.1/bin/pnpm
    bun: 1.2.21 - /opt/homebrew/bin/bun
  Browsers:
    Chrome: 141.0.7390.77
    Safari: 18.5
  npmPackages:
    @rspack/cli: ^1.5.8 => 1.5.8 
    @rspack/core: ^1.5.8 => 1.5.8 

Details

Rspack's css modules composes functionality doesn't work with exportConvention: 'camel-case'.

When using native css modules support in rspack and changing the exportConvention to camel-case, Rspack doesn't export the composed class name list to the camel case version, only the old class name.

Context

Rspack has experimental support for native css modules which also supports the css-modules spec

In the css-modules specification, there's a composes keyword which allows a class to inherit the styles from another class.

for example:

/* src/style.module.css */
.first-class {
  color: red;
}

.second-class {
  composes: first-class;
  background: green;
}

the way it's implemented is that when the second class name is exported into js-land, it's a space separated list of both class name identifiers.

that way when you put this on your HTML node's class property it'll get the styles from both classes.

Issue

When using the exporConvention: 'camel-case option in module.generator["css/auto"].exportsConvention, the composed class list string is not exported to the camel case version of the class name.
But it is exported to the original class name.

for example:

// src/index.js
import styles from "./style.module.css";
console.log(styles["second-class"]); // ✅ "first-class second-class"
console.log(styles.secondClass); // ❌ "first-class" (missing "second-class")

Expected Behavior

The expected behavior is that both styles["second-class"] and styles.secondClass would output the same string: "first-class second-class".

I assume this has something to do with this bug.

Maybe they even have the same root cause.

Reproduce link

https://github.com/ItamarGronich/rspack-css-compose

Reproduce Steps

  1. Clone this repository
  2. Run pnpm install
  3. Run pnpm test
  4. The test should fail the last assertion

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions