Skip to content

Commit 5454014

Browse files
Postcss: Run plugin in Once hook (#15273)
Closes #15138 This PR changes the postcss client to run in the `Once` hook instead of `OnceExit`. This makes sure the postcss order in v4 matches that of v3. Conceptually this also makes more sense, since we expect tailwindcss to be run as one of the first plugins in the pipeline (where `OnceExit` would run it almost at the end). To make sure it's still possible to use `postcss-import` before and have it resolve to the right paths, we also needed to change the `postcss-fix-relative-paths` plugin to run in the `Once` order (`postcss-import` also uses `Once` order so the order). ## Test Plan This issue had many ways in which it can manifest. I added a unit test to ensure the plugin order works but here's a concrete example when using the postcss plugin in Vite. ### Before Image `url()`s were not properly handled since the postcss plugin to transform these was run before Tailwind CSS could generate the class for it: <img width="2532" alt="Screenshot 2024-12-02 at 14 55 42" src="https://github.com/user-attachments/assets/2f23b409-1576-441d-9ffe-6f24ad6e7436"> ### After <img width="2529" alt="Screenshot 2024-12-02 at 14 53 52" src="https://github.com/user-attachments/assets/b754c3d8-1af1-4aeb-87da-0bfc3ffecdb7"> --------- Co-authored-by: Jordan Pittman <jordan@cryptica.me>
1 parent 93b922d commit 5454014

File tree

4 files changed

+64
-6
lines changed

4 files changed

+64
-6
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
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))
1414
- Fix resolution of imported CSS files in Vite SSR builds ([#15279](https://github.com/tailwindlabs/tailwindcss/issues/15279))
15+
- Ensure other plugins can run after `@tailwindcss/postcss` ([#15273](https://github.com/tailwindlabs/tailwindcss/pull/15273))
16+
- Rebase `url()` inside imported CSS files when using Vite with the `@tailwindcss/postcss` extension ([#15273](https://github.com/tailwindlabs/tailwindcss/pull/15273))
1517

1618
### Added
1719

packages/@tailwindcss-postcss/src/index.test.ts

+59-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import dedent from 'dedent'
22
import { unlink, writeFile } from 'node:fs/promises'
33
import postcss from 'postcss'
44
import { afterEach, beforeEach, describe, expect, test } from 'vitest'
5-
// @ts-ignore
65
import tailwindcss from './index'
76

87
// We give this file path to PostCSS for processing.
@@ -248,3 +247,62 @@ test('bail early when Tailwind is not used', async () => {
248247
}"
249248
`)
250249
})
250+
251+
test('runs `Once` plugins in the right order', async () => {
252+
let before = ''
253+
let after = ''
254+
let processor = postcss([
255+
{
256+
postcssPlugin: 'before',
257+
Once(root) {
258+
before = root.toString()
259+
},
260+
},
261+
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
262+
{
263+
postcssPlugin: 'after',
264+
Once(root) {
265+
after = root.toString()
266+
},
267+
},
268+
])
269+
270+
let result = await processor.process(
271+
css`
272+
@theme {
273+
--color-red-500: red;
274+
}
275+
.custom-css {
276+
color: theme(--color-red-500);
277+
}
278+
`,
279+
{ from: inputCssFilePath() },
280+
)
281+
282+
expect(result.css.trim()).toMatchInlineSnapshot(`
283+
":root {
284+
--color-red-500: red;
285+
}
286+
287+
.custom-css {
288+
color: red;
289+
}"
290+
`)
291+
expect(before).toMatchInlineSnapshot(`
292+
"@theme {
293+
--color-red-500: red;
294+
}
295+
.custom-css {
296+
color: theme(--color-red-500);
297+
}"
298+
`)
299+
expect(after).toMatchInlineSnapshot(`
300+
":root {
301+
--color-red-500: red;
302+
}
303+
304+
.custom-css {
305+
color: red;
306+
}"
307+
`)
308+
})

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
5555

5656
{
5757
postcssPlugin: 'tailwindcss',
58-
async OnceExit(root, { result }) {
58+
async Once(root, { result }) {
5959
env.DEBUG && console.time('[@tailwindcss/postcss] Total time in @tailwindcss/postcss')
6060
let inputFile = result.opts.from ?? ''
6161
let context = getContextFromCache(inputFile, opts)

packages/@tailwindcss-postcss/src/postcss-fix-relative-paths/index.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,8 @@ export default function fixRelativePathsPlugin(): Plugin {
6767

6868
return {
6969
postcssPlugin: 'tailwindcss-postcss-fix-relative-paths',
70-
AtRule: {
71-
source: fixRelativePath,
72-
plugin: fixRelativePath,
73-
config: fixRelativePath,
70+
Once(root) {
71+
root.walkAtRules(/source|plugin|config/, fixRelativePath)
7472
},
7573
}
7674
}

0 commit comments

Comments
 (0)