diff --git a/CHANGELOG.md b/CHANGELOG.md index b75932023c29..5a5742b7eb40 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 000000000000..12eadb6c715b Binary files /dev/null and b/integrations/vite/virtual-modules.test.ts differ diff --git a/packages/@tailwindcss-vite/src/index.ts b/packages/@tailwindcss-vite/src/index.ts index 8e3d2348ea16..2a7c933e6340 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 } }