Don't clear the build plugin's Root cache during watch rebuilds

This commit is contained in:
lazerg 2026-09-21 08:58:57 +05:00
parent 44eca1b2da
commit ff8a6f67e8
No known key found for this signature in database
2 changed files with 11 additions and 0 deletions

View file

@ -33,6 +33,7 @@ test(
const NAME = '@tailwindcss/vite:generate:build'
let ctxRef = null
let probeRan = false
function instrument(plugins) {
return plugins.map((plugin) => {
@ -44,6 +45,7 @@ test(
...plugin.transform,
handler(...args) {
ctxRef ??= new WeakRef(this)
probeRan = true
return original.apply(this, args)
},
},
@ -67,12 +69,14 @@ test(
await new Promise((resolve) => setImmediate(resolve))
}
console.log('probeRan=' + probeRan)
console.log('pluginContextAlive=' + (ctxRef?.deref() !== undefined))
`,
},
},
async ({ exec, expect }) => {
let output = await exec('node --expose-gc probe.mjs')
expect(output).toContain('probeRan=true')
expect(output).toContain('pluginContextAlive=false')
},
)

View file

@ -284,6 +284,13 @@ export default function tailwindcss(opts: PluginOptions = {}): Plugin[] {
},
closeBundle() {
// In `--watch` mode, `closeBundle` fires after every rebuild, not
// just once at the end — clearing the roots here would throw away
// the mtime-based rebuild cache `Root` relies on and force a full
// recompile on every change. Only clear once the build itself is
// done for good.
if (config?.build.watch) return
// Roots hold on to the compiler (and, through it, the `PluginContext`
// of whichever transform call created it) for the lifetime of the
// plugin instance. Drop them once the bundle is done so a long-lived