diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 51b30d7e6..bc3a2330e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -417,6 +417,9 @@ importers:
'@rsbuild/plugin-sass':
specifier: ^1.2.2
version: 1.2.2(@rsbuild/core@1.2.19)
+ '@rsbuild/plugin-typed-css-modules':
+ specifier: ^1.0.2
+ version: 1.0.2(@rsbuild/core@1.2.19)
'@rslib/core':
specifier: workspace:*
version: link:../packages/core
@@ -862,6 +865,10 @@ importers:
tests/integration/style/asset: {}
+ tests/integration/style/css-modules-named/bundle: {}
+
+ tests/integration/style/css-modules-named/bundle-false: {}
+
tests/integration/style/css-modules/bundle: {}
tests/integration/style/css-modules/bundle-false: {}
@@ -2231,6 +2238,14 @@ packages:
'@rsbuild/core':
optional: true
+ '@rsbuild/plugin-typed-css-modules@1.0.2':
+ resolution: {integrity: sha512-QX376pBXWeBrZBvYLP2HGGrHiWA5O0SDHwRoBNto5BqYDXhi6y+Eol2Hb/cY+h2ARKZVanMfUiJRABULOJ/FCQ==}
+ peerDependencies:
+ '@rsbuild/core': 1.x || ^1.0.1-beta.0
+ peerDependenciesMeta:
+ '@rsbuild/core':
+ optional: true
+
'@rsbuild/plugin-vue@1.0.7':
resolution: {integrity: sha512-VIXFIU2gcpRjDxZNR9QUZjFqWu3oPZ5a5AUe8cyv2moJBQzRPJ18VtPnIIcdlQB36Q8lm2Do0SSVqkXAuui65g==}
peerDependencies:
@@ -8282,6 +8297,10 @@ snapshots:
- '@rspack/core'
- typescript
+ '@rsbuild/plugin-typed-css-modules@1.0.2(@rsbuild/core@1.2.19)':
+ optionalDependencies:
+ '@rsbuild/core': 1.2.19
+
'@rsbuild/plugin-vue@1.0.7(@rsbuild/core@1.2.19)(vue@3.5.13(typescript@5.8.2))':
dependencies:
'@rsbuild/core': 1.2.19
diff --git a/tests/integration/style/css-modules-named/__fixtures__/.gitignore b/tests/integration/style/css-modules-named/__fixtures__/.gitignore
new file mode 100644
index 000000000..1d67a9f73
--- /dev/null
+++ b/tests/integration/style/css-modules-named/__fixtures__/.gitignore
@@ -0,0 +1,2 @@
+# ignore typed css module
+*.scss.d.ts
\ No newline at end of file
diff --git a/tests/integration/style/css-modules-named/__fixtures__/basic/src/button/index.module.scss b/tests/integration/style/css-modules-named/__fixtures__/basic/src/button/index.module.scss
new file mode 100644
index 000000000..20f5fa0c2
--- /dev/null
+++ b/tests/integration/style/css-modules-named/__fixtures__/basic/src/button/index.module.scss
@@ -0,0 +1,3 @@
+.content-wrapper {
+ background-color: #fff;
+}
diff --git a/tests/integration/style/css-modules-named/__fixtures__/basic/src/button/index.tsx b/tests/integration/style/css-modules-named/__fixtures__/basic/src/button/index.tsx
new file mode 100644
index 000000000..77d06fadd
--- /dev/null
+++ b/tests/integration/style/css-modules-named/__fixtures__/basic/src/button/index.tsx
@@ -0,0 +1,3 @@
+import { contentWrapper } from './index.module.scss';
+
+export default contentWrapper;
diff --git a/tests/integration/style/css-modules-named/__fixtures__/basic/src/env.d.ts b/tests/integration/style/css-modules-named/__fixtures__/basic/src/env.d.ts
new file mode 100644
index 000000000..ce107c108
--- /dev/null
+++ b/tests/integration/style/css-modules-named/__fixtures__/basic/src/env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/tests/integration/style/css-modules-named/__fixtures__/basic/src/index.ts b/tests/integration/style/css-modules-named/__fixtures__/basic/src/index.ts
new file mode 100644
index 000000000..84e744a7e
--- /dev/null
+++ b/tests/integration/style/css-modules-named/__fixtures__/basic/src/index.ts
@@ -0,0 +1,3 @@
+import button from './button/index';
+
+export { button };
diff --git a/tests/integration/style/css-modules-named/__fixtures__/basic/tsconfig.json b/tests/integration/style/css-modules-named/__fixtures__/basic/tsconfig.json
new file mode 100644
index 000000000..888d3e460
--- /dev/null
+++ b/tests/integration/style/css-modules-named/__fixtures__/basic/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "@rslib/tsconfig/base",
+ "compilerOptions": {
+ "baseUrl": "./"
+ },
+ "include": ["src"]
+}
diff --git a/tests/integration/style/css-modules-named/bundle-false/package.json b/tests/integration/style/css-modules-named/bundle-false/package.json
new file mode 100644
index 000000000..b931411db
--- /dev/null
+++ b/tests/integration/style/css-modules-named/bundle-false/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "css-modules-named-bundle-false-test",
+ "version": "1.0.0",
+ "private": true,
+ "type": "module"
+}
diff --git a/tests/integration/style/css-modules-named/bundle-false/rslib.config.ts b/tests/integration/style/css-modules-named/bundle-false/rslib.config.ts
new file mode 100644
index 000000000..bde262d23
--- /dev/null
+++ b/tests/integration/style/css-modules-named/bundle-false/rslib.config.ts
@@ -0,0 +1,31 @@
+import { pluginSass } from '@rsbuild/plugin-sass';
+import { pluginTypedCSSModules } from '@rsbuild/plugin-typed-css-modules';
+import { defineConfig } from '@rslib/core';
+import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper';
+
+export default defineConfig({
+ lib: [
+ generateBundleEsmConfig({ bundle: false }),
+ generateBundleCjsConfig({ bundle: false }),
+ ],
+ source: {
+ entry: {
+ index: ['../__fixtures__/basic/src/**'],
+ },
+ },
+ output: {
+ target: 'web',
+ cssModules: {
+ namedExport: true,
+ exportLocalsConvention: 'camelCaseOnly',
+ },
+ },
+ plugins: [
+ pluginSass({
+ sassLoaderOptions: {
+ additionalData: '$base-color: #c6538c;',
+ },
+ }),
+ pluginTypedCSSModules(),
+ ],
+});
diff --git a/tests/integration/style/css-modules-named/bundle/package.json b/tests/integration/style/css-modules-named/bundle/package.json
new file mode 100644
index 000000000..650b4843b
--- /dev/null
+++ b/tests/integration/style/css-modules-named/bundle/package.json
@@ -0,0 +1,6 @@
+{
+ "name": "css-modules-named-bundle-test",
+ "version": "1.0.0",
+ "private": true,
+ "type": "module"
+}
diff --git a/tests/integration/style/css-modules-named/bundle/rslib.config.ts b/tests/integration/style/css-modules-named/bundle/rslib.config.ts
new file mode 100644
index 000000000..eb339b13a
--- /dev/null
+++ b/tests/integration/style/css-modules-named/bundle/rslib.config.ts
@@ -0,0 +1,28 @@
+import { pluginSass } from '@rsbuild/plugin-sass';
+import { pluginTypedCSSModules } from '@rsbuild/plugin-typed-css-modules';
+import { defineConfig } from '@rslib/core';
+import { generateBundleCjsConfig, generateBundleEsmConfig } from 'test-helper';
+
+export default defineConfig({
+ lib: [generateBundleEsmConfig(), generateBundleCjsConfig()],
+ source: {
+ entry: {
+ index: ['../__fixtures__/basic/src/index.ts'],
+ },
+ },
+ output: {
+ target: 'web',
+ cssModules: {
+ namedExport: true,
+ exportLocalsConvention: 'camelCaseOnly',
+ },
+ },
+ plugins: [
+ pluginSass({
+ sassLoaderOptions: {
+ additionalData: '$base-color: #c6538c;',
+ },
+ }),
+ pluginTypedCSSModules(),
+ ],
+});
diff --git a/tests/integration/style/css-modules/__fixtures__/basic/src/env.d.ts b/tests/integration/style/css-modules/__fixtures__/basic/src/env.d.ts
index b0ac762b0..ce107c108 100644
--- a/tests/integration/style/css-modules/__fixtures__/basic/src/env.d.ts
+++ b/tests/integration/style/css-modules/__fixtures__/basic/src/env.d.ts
@@ -1 +1 @@
-///
+///
diff --git a/tests/package.json b/tests/package.json
index f6d315703..0d08c4a40 100644
--- a/tests/package.json
+++ b/tests/package.json
@@ -19,6 +19,7 @@
"@rsbuild/plugin-less": "^1.1.1",
"@rsbuild/plugin-react": "^1.1.1",
"@rsbuild/plugin-sass": "^1.2.2",
+ "@rsbuild/plugin-typed-css-modules": "^1.0.2",
"@rslib/core": "workspace:*",
"@rslib/tsconfig": "workspace:*",
"@types/fs-extra": "^11.0.4",