From 59e003e6d1ebf2a0c1724c17c23a998e3602f9f3 Mon Sep 17 00:00:00 2001 From: Philipp Spiess Date: Tue, 25 Feb 2025 11:29:58 +0100 Subject: [PATCH] Vite: Don't crash with virtual module dependencies (#16780) Fixes #16732 If we can not get the mtime from a file, chances are that the resource is a virtual module. This is perfectly legit and we can fall back to what we did before the changes in `4.0.8` (which is to rebuild the root every time a change contains a dependency like that). ## Test plan Added a test to mimic the setup from the repor in #16732. Also ensured the repro now passes: Screenshot 2025-02-24 at 17 29 38 Note that importing virtual modules directly in CSS does not work as the resolver we use does not resolve against the Vite runtime it seems. This is unrelated to the regression added in `4.0.8` though and something to look into in the future. --- CHANGELOG.md | 4 ++++ integrations/vite/virtual-modules.test.ts | Bin 0 -> 2339 bytes packages/@tailwindcss-vite/src/index.ts | 21 +++++++++++++++------ 3 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 integrations/vite/virtual-modules.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index b75932023..5a5742b7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - _Experimental_: Add `user-valid` and `user-invalid` variants ([#12370](https://github.com/tailwindlabs/tailwindcss/pull/12370)) - _Experimental_: Add `wrap-anywhere`, `wrap-break-word`, and `wrap-normal` utilities ([#12128](https://github.com/tailwindlabs/tailwindcss/pull/12128)) +### Fixed + +- Vite: Don't crash when importing a virtual module in JavaScript that ends in `.css` ([#16780](https://github.com/tailwindlabs/tailwindcss/pull/16780)) + ## [4.0.8] - 2025-02-21 ### Added diff --git a/integrations/vite/virtual-modules.test.ts b/integrations/vite/virtual-modules.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..12eadb6c715b903259d0e2840a7ee9435d82caf2 GIT binary patch literal 2339 zcmaJ@O>^5e5bfE&V#5n5S0$V2ZVDCpa&_sq8tGx>*Ln&K`eysaIc&VL zW(ppir!%elM-Mxw8oP!x&x_V8?b4Hz(i-RC-@iZpb@}1V+dp6dPbUCrEy{bb#Qe@# zlg`-rhFZNUYIFG^IjE7JDCnd&e}#()wlro z7-T^)MXUWm?5rpJwpCgZ|E!ny%BX5PgGy+JFmP7ucBzb;!PRI#*<=bE)%aHE_o2Ai zt`aeC*t+kK*UU1xVq z`iwk}y;!m{?y8&Dz2m5T(qGAbcXGnhHzVd!Y0-hP9?C|z6+EoaK=e~)38EJo#D)Nx zo%~)I;NIYC-B26Gh6_FIf|Q@2qQ>11?@(Ofwx)!P*QPWiu;g=%C5`_HEY3QuiwB{6 zSkBVg)N4w?BZSy#*WwyI@Fa57wb8tC`BK~4ES1Xn;`FpQ4ZS-F;)ozw@R;P@z7rd~ zK(q9#>}9mzfLFZEeR)k$gYDJN*Rg>Ij2P)pGW=v|SQ4=&gk`rWTn(SWo1ySG*Ni~h zr_=-KDR-AU;x#ZSal*e?(CH+Q&nPtMd0cWEM`oUj6Nf#!tOflLkW+DC zOQC09+-bJ*zRpi4Uy34UEf91l77w{#J?U`5!_~{{u-XmM->lUrOh%amdP8b4m&5;z stfOtDFHR>;h=Hcj?+S;ULfXxWFmz&Gort0*tEjL4{}sJUiatsI0i~D8_W%F@ literal 0 HcmV?d00001 diff --git a/packages/@tailwindcss-vite/src/index.ts b/packages/@tailwindcss-vite/src/index.ts index 8e3d2348e..2a7c933e6 100644 --- a/packages/@tailwindcss-vite/src/index.ts +++ b/packages/@tailwindcss-vite/src/index.ts @@ -202,8 +202,9 @@ class Root { private candidates: Set = new Set() // List of all build dependencies (e.g. imported stylesheets or plugins) and - // their last modification timestamp - private buildDependencies = new Map() + // their last modification timestamp. If no mtime can be found, we need to + // assume the file has always changed. + private buildDependencies = new Map() constructor( private id: string, @@ -334,14 +335,22 @@ class Root { } private async addBuildDependency(path: string) { - let stat = await fs.stat(path) - this.buildDependencies.set(path, stat.mtimeMs) + let mtime: number | null = null + try { + mtime = (await fs.stat(path)).mtimeMs + } catch {} + this.buildDependencies.set(path, mtime) } private async requiresBuild(): Promise { for (let [path, mtime] of this.buildDependencies) { - let stat = await fs.stat(path) - if (stat.mtimeMs > mtime) { + if (mtime === null) return true + try { + let stat = await fs.stat(path) + if (stat.mtimeMs > mtime) { + return true + } + } catch { return true } }