Skip to content

Commit ffbaab4

Browse files
vite-third-party-plugins
1 parent ca4e4ae commit ffbaab4

File tree

3 files changed

+176
-41
lines changed

3 files changed

+176
-41
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import { describe, expect } from 'vitest'
2+
import { css, fetchStyles, html, retryAssertion, test, ts, txt } from '../utils'
3+
4+
function createSetup(transformer: 'postcss' | 'lightningcss') {
5+
return {
6+
fs: {
7+
'package.json': txt`
8+
{
9+
"type": "module",
10+
"dependencies": {
11+
"@tailwindcss/vite": "workspace:^",
12+
"tailwindcss": "workspace:^"
13+
},
14+
"devDependencies": {
15+
${transformer === 'lightningcss' ? `"lightningcss": "^1.26.0",` : ''}
16+
"vite": "^5.3.5"
17+
}
18+
}
19+
`,
20+
'vite.config.ts': ts`
21+
import tailwindcss from '@tailwindcss/vite'
22+
import { defineConfig } from 'vite'
23+
24+
export default defineConfig({
25+
css: ${transformer === 'postcss' ? '{}' : "{ transformer: 'lightningcss' }"},
26+
build: { cssMinify: false },
27+
plugins: [
28+
tailwindcss(),
29+
{
30+
name: 'recolor',
31+
transform(code, id) {
32+
if (id.includes('.css')) {
33+
return code.replace(/red/g, 'blue')
34+
}
35+
},
36+
},
37+
],
38+
})
39+
`,
40+
'index.html': html`
41+
<head>
42+
<link rel="stylesheet" href="./src/index.css" />
43+
</head>
44+
<body>
45+
<div class="foo">Hello, world!</div>
46+
</body>
47+
`,
48+
'src/index.css': css`
49+
@import 'tailwindcss/theme' theme(reference);
50+
@import 'tailwindcss/utilities';
51+
52+
.foo {
53+
color: red;
54+
}
55+
`,
56+
},
57+
}
58+
}
59+
60+
for (let transformer of ['postcss', 'lightningcss'] as const) {
61+
describe(transformer, () => {
62+
test(`production build`, createSetup(transformer), async ({ fs, exec }) => {
63+
await exec('pnpm vite build')
64+
65+
let files = await fs.glob('dist/**/*.css')
66+
expect(files).toHaveLength(1)
67+
let [filename] = files[0]
68+
69+
await fs.expectFileToContain(filename, [
70+
css`
71+
.foo {
72+
color: blue;
73+
}
74+
`,
75+
])
76+
})
77+
78+
test(`dev mode`, createSetup(transformer), async ({ spawn, getFreePort, fs }) => {
79+
let port = await getFreePort()
80+
await spawn(`pnpm vite dev --port ${port}`)
81+
82+
await retryAssertion(async () => {
83+
let styles = await fetchStyles(port, '/index.html')
84+
expect(styles).toContain(css`
85+
.foo {
86+
color: blue;
87+
}
88+
`)
89+
})
90+
91+
await retryAssertion(async () => {
92+
await fs.write(
93+
'src/index.css',
94+
css`
95+
@import 'tailwindcss/theme' theme(reference);
96+
@import 'tailwindcss/utilities';
97+
98+
.foo {
99+
background-color: red;
100+
}
101+
`,
102+
)
103+
104+
let styles = await fetchStyles(port)
105+
expect(styles).toContain(css`
106+
.foo {
107+
background-color: blue;
108+
}
109+
`)
110+
})
111+
})
112+
113+
test('watch mode', createSetup(transformer), async ({ spawn, fs }) => {
114+
await spawn(`pnpm vite build --watch`)
115+
116+
await retryAssertion(async () => {
117+
let files = await fs.glob('dist/**/*.css')
118+
expect(files).toHaveLength(1)
119+
let [, styles] = files[0]
120+
121+
expect(styles).toContain(css`
122+
.foo {
123+
color: blue;
124+
}
125+
`)
126+
})
127+
128+
await retryAssertion(async () => {
129+
await fs.write(
130+
'src/index.css',
131+
css`
132+
@import 'tailwindcss/theme' theme(reference);
133+
@import 'tailwindcss/utilities';
134+
135+
.foo {
136+
background-color: red;
137+
}
138+
`,
139+
)
140+
141+
let files = await fs.glob('dist/**/*.css')
142+
expect(files).toHaveLength(1)
143+
let [, styles] = files[0]
144+
145+
expect(styles).toContain(css`
146+
.foo {
147+
background-color: blue;
148+
}
149+
`)
150+
})
151+
})
152+
})
153+
}

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

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@ export default function tailwindcss(): Plugin[] {
1515
let isSSR = false
1616
let minify = false
1717

18-
// A list of css plugins defined in the Vite config. We need to retain these
19-
// so that we can rerun the right transformations in build mode where we have
20-
// to manually rebuild the css file after the compilation is done.
21-
let cssPlugins: readonly Plugin[] = []
22-
2318
// The Vite extension has two types of sources for candidates:
2419
//
2520
// 1. The module graph: These are all modules that vite transforms and we want
@@ -109,8 +104,24 @@ export default function tailwindcss(): Plugin[] {
109104
},
110105
}
111106

112-
for (let plugin of cssPlugins) {
107+
for (let plugin of config!.plugins) {
113108
if (!plugin.transform) continue
109+
110+
if (plugin.name.startsWith('@tailwindcss/')) {
111+
// We do not run any Tailwind transforms anymore
112+
continue
113+
} else if (
114+
plugin.name.startsWith('vite:') &&
115+
// Apply the vite:css plugin to generated CSS for transformations like
116+
// URL path rewriting and image inlining.
117+
plugin.name !== 'vite:css' &&
118+
// In build mode, since `renderStart` runs after all transformations, we
119+
// need to also apply vite:css-post.
120+
plugin.name !== 'vite:css-post'
121+
) {
122+
continue
123+
}
124+
114125
let transformHandler =
115126
'handler' in plugin.transform! ? plugin.transform.handler : plugin.transform!
116127

@@ -147,20 +158,6 @@ export default function tailwindcss(): Plugin[] {
147158
config = _config
148159
minify = config.build.cssMinify !== false
149160
isSSR = config.build.ssr !== false && config.build.ssr !== undefined
150-
151-
let allowedPlugins = [
152-
// Apply the vite:css plugin to generated CSS for transformations like
153-
// URL path rewriting and image inlining.
154-
'vite:css',
155-
156-
// In build mode, since renderChunk runs after all transformations, we
157-
// need to also apply vite:css-post.
158-
...(config.command === 'build' ? ['vite:css-post'] : []),
159-
]
160-
161-
cssPlugins = config.plugins.filter((plugin) => {
162-
return allowedPlugins.includes(plugin.name)
163-
})
164161
},
165162

166163
// Scan all non-CSS files for candidates

pnpm-lock.yaml

Lines changed: 6 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)