From 12c1e7ef7aa2d222811dc3525d3b5e5d975e96d2 Mon Sep 17 00:00:00 2001 From: Amir Zarrinkafsh <3339418+nightah@users.noreply.github.com> Date: Sun, 15 Mar 2026 18:57:13 +1100 Subject: [PATCH 1/3] fix(vite): resolve tsconfig paths in CSS and JS resolvers Change `aliasOnly` from `true` to `false` when calling Vite's resolver so that the full resolution pipeline runs, including the oxc resolver responsible for tsconfig path resolution. When `aliasOnly` was `true`, only the @rollup/plugin-alias plugin ran, which meant `resolve.tsconfigPaths: true` had no effect on CSS `@import` or JS `@plugin` resolution in `@tailwindcss/vite`. Closes #19802 --- integrations/vite/resolvers.test.ts | 165 +++++++++++++++++++++++- packages/@tailwindcss-vite/src/index.ts | 8 +- 2 files changed, 168 insertions(+), 5 deletions(-) diff --git a/integrations/vite/resolvers.test.ts b/integrations/vite/resolvers.test.ts index f8e389a7e696..79ce57553555 100644 --- a/integrations/vite/resolvers.test.ts +++ b/integrations/vite/resolvers.test.ts @@ -1,5 +1,168 @@ import { describe } from 'vitest' -import { candidate, css, fetchStyles, html, js, retryAssertion, test, ts, txt } from '../utils' +import { + candidate, + css, + fetchStyles, + html, + js, + json, + retryAssertion, + test, + ts, + txt, +} from '../utils' + +test( + 'resolves tsconfig paths in production build', + { + fs: { + 'package.json': json` + { + "type": "module", + "dependencies": { + "@tailwindcss/vite": "workspace:^", + "tailwindcss": "workspace:^" + }, + "devDependencies": { + "vite": "^8" + } + } + `, + 'tsconfig.json': json` + { + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + } + } + `, + 'vite.config.ts': ts` + import tailwindcss from '@tailwindcss/vite' + import { defineConfig } from 'vite' + + export default defineConfig({ + build: { cssMinify: false }, + plugins: [tailwindcss()], + resolve: { + tsconfigPaths: true, + }, + }) + `, + 'index.html': html` + + + + +
Hello, world!
+ + `, + 'src/index.css': css` + @import '@/styles/base.css'; + @plugin '@/plugin.js'; + `, + 'src/styles/base.css': css` + @reference 'tailwindcss/theme'; + @import 'tailwindcss/utilities'; + `, + 'src/plugin.js': js` + export default function ({ addUtilities }) { + addUtilities({ '.custom-underline': { 'border-bottom': '1px solid green' } }) + } + `, + }, + }, + async ({ fs, exec, expect }) => { + await exec('pnpm vite build') + + let files = await fs.glob('dist/**/*.css') + expect(files).toHaveLength(1) + let [filename] = files[0] + + await fs.expectFileToContain(filename, [candidate`underline`, candidate`custom-underline`]) + }, +) + +test( + 'resolves tsconfig paths in dev mode', + { + fs: { + 'package.json': json` + { + "type": "module", + "dependencies": { + "@tailwindcss/vite": "workspace:^", + "tailwindcss": "workspace:^" + }, + "devDependencies": { + "vite": "^8" + } + } + `, + 'tsconfig.json': json` + { + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + } + } + `, + 'vite.config.ts': ts` + import tailwindcss from '@tailwindcss/vite' + import { defineConfig } from 'vite' + + export default defineConfig({ + build: { cssMinify: false }, + plugins: [tailwindcss()], + resolve: { + tsconfigPaths: true, + }, + }) + `, + 'index.html': html` + + + + +
Hello, world!
+ + `, + 'src/index.css': css` + @import '@/styles/base.css'; + @plugin '@/plugin.js'; + `, + 'src/styles/base.css': css` + @reference 'tailwindcss/theme'; + @import 'tailwindcss/utilities'; + `, + 'src/plugin.js': js` + export default function ({ addUtilities }) { + addUtilities({ '.custom-underline': { 'border-bottom': '1px solid green' } }) + } + `, + }, + }, + async ({ spawn, expect }) => { + let process = await spawn('pnpm vite dev') + await process.onStdout((m) => m.includes('ready in')) + + let url = '' + await process.onStdout((m) => { + let match = /Local:\s*(http.*)\//.exec(m) + if (match) url = match[1] + return Boolean(url) + }) + + await retryAssertion(async () => { + let styles = await fetchStyles(url, '/index.html') + expect(styles).toContain(candidate`underline`) + expect(styles).toContain(candidate`custom-underline`) + }) + }, +) describe.each(['postcss', 'lightningcss'])('%s', (transformer) => { test( diff --git a/packages/@tailwindcss-vite/src/index.ts b/packages/@tailwindcss-vite/src/index.ts index 6dfc7b227832..0352709b8ad6 100644 --- a/packages/@tailwindcss-vite/src/index.ts +++ b/packages/@tailwindcss-vite/src/index.ts @@ -62,8 +62,8 @@ export default function tailwindcss(opts: PluginOptions = {}): Plugin[] { let jsResolver = config!.createResolver(config!.resolve) - customCssResolver = (id: string, base: string) => cssResolver(id, base, true, isSSR) - customJsResolver = (id: string, base: string) => jsResolver(id, base, true, isSSR) + customCssResolver = (id: string, base: string) => cssResolver(id, base, false, isSSR) + customJsResolver = (id: string, base: string) => jsResolver(id, base, false, isSSR) } else { type ResolveIdFn = ( environment: Environment, @@ -105,8 +105,8 @@ export default function tailwindcss(opts: PluginOptions = {}): Plugin[] { let jsResolver = createBackCompatIdResolver(env.config, env.config.resolve) - customCssResolver = (id: string, base: string) => cssResolver(env, id, base, true) - customJsResolver = (id: string, base: string) => jsResolver(env, id, base, true) + customCssResolver = (id: string, base: string) => cssResolver(env, id, base, false) + customJsResolver = (id: string, base: string) => jsResolver(env, id, base, false) } return new Root( From 941631b15b9b30ca9ceff52e8babdf1ed32fe216 Mon Sep 17 00:00:00 2001 From: Amir Zarrinkafsh <3339418+nightah@users.noreply.github.com> Date: Tue, 17 Mar 2026 09:25:41 +1100 Subject: [PATCH 2/3] fix(vite): guard CSS resolver against non-CSS resolutions --- packages/@tailwindcss-vite/src/index.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/@tailwindcss-vite/src/index.ts b/packages/@tailwindcss-vite/src/index.ts index 0352709b8ad6..e03b365547c5 100644 --- a/packages/@tailwindcss-vite/src/index.ts +++ b/packages/@tailwindcss-vite/src/index.ts @@ -62,7 +62,11 @@ export default function tailwindcss(opts: PluginOptions = {}): Plugin[] { let jsResolver = config!.createResolver(config!.resolve) - customCssResolver = (id: string, base: string) => cssResolver(id, base, false, isSSR) + customCssResolver = async (id: string, base: string) => { + let resolved = await cssResolver(id, base, false, isSSR) + if (resolved && !resolved.endsWith('.css')) return undefined + return resolved + } customJsResolver = (id: string, base: string) => jsResolver(id, base, false, isSSR) } else { type ResolveIdFn = ( @@ -105,7 +109,11 @@ export default function tailwindcss(opts: PluginOptions = {}): Plugin[] { let jsResolver = createBackCompatIdResolver(env.config, env.config.resolve) - customCssResolver = (id: string, base: string) => cssResolver(env, id, base, false) + customCssResolver = async (id: string, base: string) => { + let resolved = await cssResolver(env, id, base, false) + if (resolved && !resolved.endsWith('.css')) return undefined + return resolved + } customJsResolver = (id: string, base: string) => jsResolver(env, id, base, false) } From aead31780a8200ee7ee708f171e180bc7bf089a9 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Fri, 20 Mar 2026 16:11:10 +0100 Subject: [PATCH 3/3] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a54331dbe32..a01ea1c9a06d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fix crash in canonicalization step when handling utilities with empty property maps ([#19727](https://github.com/tailwindlabs/tailwindcss/pull/19727)) - Skip full reload for server only modules scanned by client CSS when using `@tailwindcss/vite` ([#19745](https://github.com/tailwindlabs/tailwindcss/pull/19745)) - Add support for Vite 8 in `@tailwindcss/vite` ([#19790](https://github.com/tailwindlabs/tailwindcss/pull/19790)) +- Resolve tsconfig paths to allow for `@import '@/path/to/file'` when using `@tailwindcss/vite` ([#19803](https://github.com/tailwindlabs/tailwindcss/pull/19803)) ## [4.2.1] - 2026-02-23