Skip to content

Commit 93b922d

Browse files
Fix resolution of imported CSS files in Vite SSR builds (#15279)
Fixes #15237 --------- Co-authored-by: Jordan Pittman <[email protected]>
1 parent 89f291c commit 93b922d

File tree

3 files changed

+141
-1
lines changed

3 files changed

+141
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
- Ensure absolute `url()`s inside imported CSS files are not rebased when using `@tailwindcss/vite`
1313
- Fix issues with dev servers using Svelte 5 with the Vite plugin ([#15274](https://github.com/tailwindlabs/tailwindcss/issues/15274))
14+
- Fix resolution of imported CSS files in Vite SSR builds ([#15279](https://github.com/tailwindlabs/tailwindcss/issues/15279))
1415

1516
### Added
1617

integrations/vite/ssr.test.ts

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
import { expect } from 'vitest'
2+
import { candidate, css, html, json, test, ts } from '../utils'
3+
4+
test(
5+
`Vite 5`,
6+
{
7+
fs: {
8+
'package.json': json`
9+
{
10+
"type": "module",
11+
"dependencies": {
12+
"@tailwindcss/vite": "workspace:^",
13+
"tailwindcss": "workspace:^"
14+
},
15+
"_comment": "This test uses Vite 5.3 on purpose. Do not upgrade it to Vite 6.",
16+
"devDependencies": {
17+
"vite": "^5.3"
18+
}
19+
}
20+
`,
21+
'vite.config.ts': ts`
22+
import tailwindcss from '@tailwindcss/vite'
23+
import { defineConfig } from 'vite'
24+
25+
export default defineConfig({
26+
build: {
27+
cssMinify: false,
28+
ssrEmitAssets: true,
29+
},
30+
plugins: [tailwindcss()],
31+
ssr: { resolve: { conditions: [] } },
32+
})
33+
`,
34+
'index.html': html`
35+
<body>
36+
<div id="app"></div>
37+
<script type="module" src="./src/index.ts"></script>
38+
</body>
39+
`,
40+
'src/index.css': css`@import 'tailwindcss';`,
41+
'src/index.ts': ts`
42+
import './index.css'
43+
44+
document.querySelector('#app').innerHTML = \`
45+
<div class="underline m-2">Hello, world!</div>
46+
\`
47+
`,
48+
'server.ts': ts`
49+
import css from './src/index.css?url'
50+
51+
document.querySelector('#app').innerHTML = \`
52+
<link rel="stylesheet" href="\${css}">
53+
<div class="underline m-2">Hello, world!</div>
54+
\`
55+
`,
56+
},
57+
},
58+
async ({ fs, exec }) => {
59+
await exec('pnpm vite build --ssr server.ts')
60+
61+
let files = await fs.glob('dist/**/*.css')
62+
expect(files).toHaveLength(1)
63+
let [filename] = files[0]
64+
65+
await fs.expectFileToContain(filename, [
66+
//
67+
candidate`underline`,
68+
candidate`m-2`,
69+
])
70+
},
71+
)
72+
73+
test(
74+
`Vite 6`,
75+
{
76+
fs: {
77+
'package.json': json`
78+
{
79+
"type": "module",
80+
"dependencies": {
81+
"@tailwindcss/vite": "workspace:^",
82+
"tailwindcss": "workspace:^"
83+
},
84+
"devDependencies": {
85+
"vite": "^6.0"
86+
}
87+
}
88+
`,
89+
'vite.config.ts': ts`
90+
import tailwindcss from '@tailwindcss/vite'
91+
import { defineConfig } from 'vite'
92+
93+
export default defineConfig({
94+
build: {
95+
cssMinify: false,
96+
ssrEmitAssets: true,
97+
},
98+
plugins: [tailwindcss()],
99+
ssr: { resolve: { conditions: [] } },
100+
})
101+
`,
102+
'index.html': html`
103+
<body>
104+
<div id="app"></div>
105+
<script type="module" src="./src/index.ts"></script>
106+
</body>
107+
`,
108+
'src/index.css': css`@import 'tailwindcss';`,
109+
'src/index.ts': ts`
110+
import './index.css'
111+
112+
document.querySelector('#app').innerHTML = \`
113+
<div class="underline m-2">Hello, world!</div>
114+
\`
115+
`,
116+
'server.ts': ts`
117+
import css from './src/index.css?url'
118+
119+
document.querySelector('#app').innerHTML = \`
120+
<link rel="stylesheet" href="\${css}">
121+
<div class="underline m-2">Hello, world!</div>
122+
\`
123+
`,
124+
},
125+
},
126+
async ({ fs, exec }) => {
127+
await exec('pnpm vite build --ssr server.ts')
128+
129+
let files = await fs.glob('dist/**/*.css')
130+
expect(files).toHaveLength(1)
131+
let [filename] = files[0]
132+
133+
await fs.expectFileToContain(filename, [
134+
//
135+
candidate`underline`,
136+
candidate`m-2`,
137+
])
138+
},
139+
)

packages/@tailwindcss-vite/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default function tailwindcss(): Plugin[] {
4444
preferRelative: true,
4545
})
4646
function customCssResolver(id: string, base: string) {
47-
return cssResolver(id, base, false, isSSR)
47+
return cssResolver(id, base, true, isSSR)
4848
}
4949

5050
let jsResolver = config!.createResolver(config!.resolve)

0 commit comments

Comments
 (0)