diff --git a/src/postcss.ts b/src/postcss.ts index 1af6ca9..fe1f2ff 100644 --- a/src/postcss.ts +++ b/src/postcss.ts @@ -17,9 +17,16 @@ const injectTailwindThemePlugin: PluginCreator = ( if (!themePath) { return; } + + const file = root.source?.input.file || ''; + + // Use @reference for CSS modules to avoid duplicating theme variables in every module. + // Use @import for global CSS and regular CSS files to ensure theme variables are emitted. + const isCssModule = /\.module\.(css|scss|sass|less|styl)$/i.test(file); + root.prepend( new AtRule({ - name: 'import', + name: isCssModule ? 'reference' : 'import', params: JSON.stringify(themePath), }), ); diff --git a/test/css-modules-dedup-color/index.test.ts b/test/css-modules-dedup-color/index.test.ts new file mode 100644 index 0000000..a280f0d --- /dev/null +++ b/test/css-modules-dedup-color/index.test.ts @@ -0,0 +1,26 @@ +import fs from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { expect, test } from '@playwright/test'; +import { createRsbuild } from '@rsbuild/core'; +import { pluginTailwindCSS } from '../../src'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +test('deduplicates theme color variables', async () => { + const rsbuild = await createRsbuild({ + cwd: __dirname, + rsbuildConfig: { + plugins: [pluginTailwindCSS()], + }, + }); + await rsbuild.build(); + + const cssDir = join(__dirname, 'dist/static/css'); + const cssFiles = fs.readdirSync(cssDir).filter((f) => f.endsWith('.css')); + const cssContent = fs.readFileSync(join(cssDir, cssFiles[0]), 'utf-8'); + + // Find how many times --color-red-500 is defined + const matches = cssContent.match(/--color-red-500:/g) || []; + expect(matches.length).toBeLessThan(5); +}); diff --git a/test/css-modules-dedup-color/src/a.css b/test/css-modules-dedup-color/src/a.css new file mode 100644 index 0000000..644ab42 --- /dev/null +++ b/test/css-modules-dedup-color/src/a.css @@ -0,0 +1,3 @@ +.a { + @apply text-red-500; +} diff --git a/test/css-modules-dedup-color/src/b.css b/test/css-modules-dedup-color/src/b.css new file mode 100644 index 0000000..183d52f --- /dev/null +++ b/test/css-modules-dedup-color/src/b.css @@ -0,0 +1,3 @@ +.b { + @apply text-red-500; +} diff --git a/test/css-modules-dedup-color/src/index.js b/test/css-modules-dedup-color/src/index.js new file mode 100644 index 0000000..a0ec795 --- /dev/null +++ b/test/css-modules-dedup-color/src/index.js @@ -0,0 +1,2 @@ +import './a.css'; +import './b.css'; diff --git a/test/css-modules-dedup/index.test.ts b/test/css-modules-dedup/index.test.ts new file mode 100644 index 0000000..7520e9f --- /dev/null +++ b/test/css-modules-dedup/index.test.ts @@ -0,0 +1,28 @@ +import fs from 'node:fs'; +import { dirname, join } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { expect, test } from '@playwright/test'; +import { createRsbuild } from '@rsbuild/core'; +import { pluginTailwindCSS } from '../../src'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +test('deduplicates theme variables in multiple CSS modules', async () => { + const rsbuild = await createRsbuild({ + cwd: __dirname, + rsbuildConfig: { + plugins: [pluginTailwindCSS()], + }, + }); + + await rsbuild.build(); + + const cssDir = join(__dirname, 'dist/static/css'); + const cssFiles = fs.readdirSync(cssDir).filter((f) => f.endsWith('.css')); + const cssContent = fs.readFileSync(join(cssDir, cssFiles[0]), 'utf-8'); + + // If theme was injected via @import, does it result in duplicated variables? + // We'll count the number of times `--spacing` or some known theme variable appears. + const rootMatches = cssContent.match(/:root/g) || []; + expect(rootMatches.length).toBeLessThan(2); +}); diff --git a/test/css-modules-dedup/src/a.css b/test/css-modules-dedup/src/a.css new file mode 100644 index 0000000..939da27 --- /dev/null +++ b/test/css-modules-dedup/src/a.css @@ -0,0 +1,3 @@ +.a { + @apply flex; +} diff --git a/test/css-modules-dedup/src/b.css b/test/css-modules-dedup/src/b.css new file mode 100644 index 0000000..5f0d71e --- /dev/null +++ b/test/css-modules-dedup/src/b.css @@ -0,0 +1,3 @@ +.b { + @apply flex; +} diff --git a/test/css-modules-dedup/src/index.js b/test/css-modules-dedup/src/index.js new file mode 100644 index 0000000..a0ec795 --- /dev/null +++ b/test/css-modules-dedup/src/index.js @@ -0,0 +1,2 @@ +import './a.css'; +import './b.css';