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