Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/postcss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,16 @@ const injectTailwindThemePlugin: PluginCreator<TailwindCSSPostCSSOptions> = (
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),
}),
);
Expand Down
26 changes: 26 additions & 0 deletions test/css-modules-dedup-color/index.test.ts
Original file line number Diff line number Diff line change
@@ -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);
});
3 changes: 3 additions & 0 deletions test/css-modules-dedup-color/src/a.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.a {
@apply text-red-500;
}
3 changes: 3 additions & 0 deletions test/css-modules-dedup-color/src/b.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.b {
@apply text-red-500;
}
2 changes: 2 additions & 0 deletions test/css-modules-dedup-color/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import './a.css';
import './b.css';
28 changes: 28 additions & 0 deletions test/css-modules-dedup/index.test.ts
Original file line number Diff line number Diff line change
@@ -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);
});
3 changes: 3 additions & 0 deletions test/css-modules-dedup/src/a.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.a {
@apply flex;
}
3 changes: 3 additions & 0 deletions test/css-modules-dedup/src/b.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.b {
@apply flex;
}
2 changes: 2 additions & 0 deletions test/css-modules-dedup/src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import './a.css';
import './b.css';
Loading