Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5c76efd

Browse files
fix: Add error recovery for @apply directives to avoid stuck error state
This commit addresses an issue where the PostCSS plugin would get stuck in an error state when processing files with invalid @apply directives, particularly affecting Angular 19 applications. The fix: 1. Adds error recovery in the @apply directive processor to gracefully handle errors 2. Prevents the PostCSS plugin from getting stuck in an error state after encountering an invalid @apply directive
1 parent 8e826b1 commit 5c76efd

File tree

8 files changed

+442
-249
lines changed

8 files changed

+442
-249
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- Don't scan `.db` files for classes by default ([#17711](https://github.com/tailwindlabs/tailwindcss/pull/17711))
1818
- Hide default shadow suggestions when missing theme keys ([#17743](https://github.com/tailwindlabs/tailwindcss/pull/17743))
1919
- Replace `_` with `.` in theme suggestions for `@utility` if surrounded by digits ([#17743](https://github.com/tailwindlabs/tailwindcss/pull/17743))
20+
- PostCSS: Ensure that errors in stylesheet dependencies are recoverable ([#17754](https://github.com/tailwindlabs/tailwindcss/pull/17754))
21+
22+
### Changed
23+
24+
- Using unknown utilities with `@apply` will not cause the whole build to fail anymore ([#17754](https://github.com/tailwindlabs/tailwindcss/pull/17754))
2025

2126
## [4.1.4] - 2025-04-14
2227

integrations/postcss/index.test.ts

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,3 +635,93 @@ test(
635635
await fs.expectFileToContain('project-a/dist/out.css', [candidate`content-['c/src/index.js']`])
636636
},
637637
)
638+
639+
test(
640+
'rebuild error recovery',
641+
{
642+
fs: {
643+
'package.json': json`
644+
{
645+
"devDependencies": {
646+
"postcss": "^8",
647+
"postcss-cli": "^10",
648+
"tailwindcss": "workspace:^",
649+
"@tailwindcss/postcss": "workspace:^"
650+
}
651+
}
652+
`,
653+
'postcss.config.js': js`
654+
module.exports = {
655+
plugins: {
656+
'@tailwindcss/postcss': {},
657+
},
658+
}
659+
`,
660+
'src/index.html': html`
661+
<div class="underline"></div>
662+
`,
663+
'src/index.css': css` @import './tailwind.css'; `,
664+
// prettier-ignore
665+
'src/tailwind.css': css`
666+
/* Intentional typo */
667+
@reference 'tailwindcss/thm';
668+
@import 'tailwindcss/utilities';
669+
`,
670+
},
671+
},
672+
async ({ fs, expect, spawn }) => {
673+
let process = await spawn('pnpm postcss src/index.css --output dist/out.css --watch --verbose')
674+
675+
await process.onStderr((message) =>
676+
message.includes('Package path ./thm is not exported from package'),
677+
)
678+
679+
expect(await fs.dumpFiles('dist/*.css')).toMatchInlineSnapshot(`
680+
"
681+
--- dist/out.css ---
682+
<EMPTY>
683+
"
684+
`)
685+
686+
await process.onStderr((message) => message.includes('Waiting for file changes...'))
687+
688+
// Fix the CSS file
689+
await fs.write(
690+
'src/tailwind.css',
691+
css`
692+
@reference 'tailwindcss/theme';
693+
@import 'tailwindcss/utilities';
694+
`,
695+
)
696+
await process.onStderr((message) => message.includes('Finished src/index.css'))
697+
698+
expect(await fs.dumpFiles('dist/*.css')).toMatchInlineSnapshot(`
699+
"
700+
--- dist/out.css ---
701+
.underline {
702+
text-decoration-line: underline;
703+
}
704+
"
705+
`)
706+
707+
// Now break the CSS file again
708+
await fs.write(
709+
'src/tailwind.css',
710+
css`
711+
@reference 'tailwindcss/thm';
712+
@import 'tailwindcss/utilities';
713+
`,
714+
)
715+
await process.onStderr((message) =>
716+
message.includes('Package path ./thm is not exported from package'),
717+
)
718+
await process.onStderr((message) => message.includes('Finished src/index.css'))
719+
720+
expect(await fs.dumpFiles('dist/*.css')).toMatchInlineSnapshot(`
721+
"
722+
--- dist/out.css ---
723+
<EMPTY>
724+
"
725+
`)
726+
},
727+
)

integrations/utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ interface SpawnedProcess {
1818
flush: () => void
1919
onStdout: (predicate: (message: string) => boolean) => Promise<void>
2020
onStderr: (predicate: (message: string) => boolean) => Promise<void>
21+
getExitCode(): number | string | undefined
2122
}
2223

2324
interface ChildProcessOptions {
@@ -273,6 +274,9 @@ export function test(
273274
notifyNext(stderrActors, stderrMessages)
274275
})
275276
},
277+
getExitCode(): number | string | undefined {
278+
return process.exitCode
279+
},
276280
}
277281
},
278282
fs: {

0 commit comments

Comments
 (0)