Skip to content

Commit e085977

Browse files
PostCSS: Fix Turbopack 'one-revision-behind' bug (#17554)
Closes #17508 This PR fixes another issue we found that caused dev builds with Next.js and Turbopack to resolve the CSS file that was saved one revision before the latest update. When debugging this we noticed that the PostCSS entry is called twice for every one update when changing the input CSS file directly. That was caused by the input file itself being added as a _dependency_ so you would first get the callback that a _dependency_ has updated (at which point we look at the file system and figure out we need a full-rebuild because the input.css file has changed) and then another callback for when the _input file_ has updated. The problem with the second callback was that the file-system was already scanned for updates and since this includes the `mtimes` for the input file, we seemingly thought that the input file did not change. However, the issue is that the first callback actually came with an outdated PostCSS input AST... We found that this problem arises when you register the input CSS as a dependency of itself. This is not expected and we actually guard against this in the PostCSS client. However, we found that the input `from` argument is _a relative path when using Next.js with Turbopack_ so that check was not working as expected. ## Test plan Added the change to the repro from #17508 and it seems to work fine now. https://github.com/user-attachments/assets/2acb0078-f961-4498-be1a-b1c72d5ceda1 Also added a unit test to ensure we document that the input file path can be a relative path. Co-authored-by: Robin Malfait <[email protected]>
1 parent 2fd7c8d commit e085977

File tree

4 files changed

+27
-1
lines changed

4 files changed

+27
-1
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Fixed
1111

1212
- Show warning when using unsupported bare value data type in `--value(…)` ([#17464](https://github.com/tailwindlabs/tailwindcss/pull/17464))
13+
- PostCSS: Resolve an issue where changes to the input CSS file showed outdated content when using Turbopack ([#17554](https://github.com/tailwindlabs/tailwindcss/pull/17554))
1314

1415
## [4.1.2] - 2025-04-03
1516

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/* the content for this file is set in the tests */

Diff for: packages/@tailwindcss-postcss/src/index.test.ts

+22
Original file line numberDiff line numberDiff line change
@@ -420,3 +420,25 @@ describe('concurrent builds', () => {
420420
expect(await promise2).toContain('.red')
421421
})
422422
})
423+
424+
test('does not register the input file as a dependency, even if it is passed in as relative path', async () => {
425+
let processor = postcss([
426+
tailwindcss({ base: `${__dirname}/fixtures/example-project`, optimize: { minify: false } }),
427+
])
428+
429+
let result = await processor.process(`@tailwind utilities`, { from: './input.css' })
430+
431+
expect(result.css.trim()).toMatchInlineSnapshot(`
432+
".underline {
433+
text-decoration-line: underline;
434+
}"
435+
`)
436+
437+
// Check for dependency messages
438+
expect(result.messages).not.toContainEqual({
439+
type: 'dependency',
440+
file: expect.stringMatching(/input.css$/g),
441+
parent: expect.any(String),
442+
plugin: expect.any(String),
443+
})
444+
})

Diff for: packages/@tailwindcss-postcss/src/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,12 @@ function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
223223
if (compiler.features & Features.Utilities) {
224224
DEBUG && I.start('Register dependency messages')
225225
// Add all found files as direct dependencies
226+
// Note: With Turbopack, the input file might not be a resolved path
227+
let resolvedInputFile = path.resolve(base, inputFile)
226228
for (let file of context.scanner.files) {
227229
let absolutePath = path.resolve(file)
228230
// The CSS file cannot be a dependency of itself
229-
if (absolutePath === result.opts.from) {
231+
if (absolutePath === resolvedInputFile) {
230232
continue
231233
}
232234
result.messages.push({

0 commit comments

Comments
 (0)