Skip to content

Commit bc6e4b8

Browse files
4ndvRobinMalfait
andauthored
Fallback to config.createResolver for client and ssr environments in @tailwindcss/vite (#19679)
<!-- 👋 Hey, thanks for your interest in contributing to Tailwind! **Please ask first before starting work on any significant new features.** It's never a fun experience to have your pull request declined after investing a lot of time and effort into a new feature. To avoid this from happening, we request that contributors create a discussion to first discuss any significant new features. For more info, check out the contributing guide: https://github.com/tailwindcss/tailwindcss/blob/main/.github/CONTRIBUTING.md --> ## Summary Sometimes even if Vite Envrionment API is available, some plugins are still override `config.createResolver` function to inject own aliases Since technically `config.createResolver` was only [properly deprecated](vitejs/vite#20031) in Vite 7.0.0, it's still a valid(-ish) to do so, even if it wasn't ever officially supported Vite already handles this in its internal css resolvers, but not exposes the code to do so as part of public API, so I've copied and adapted it Fixes #19677 ## Test plan Tested by copying built package into my repro from the issue, also ran vite integration tests --------- Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
1 parent 095ff96 commit bc6e4b8

File tree

3 files changed

+109
-4
lines changed

3 files changed

+109
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2929
- Allow multiples of `.25` in `aspect-*` fractions ([#19688](https://github.com/tailwindlabs/tailwindcss/pull/19688))
3030
- Ensure changes to external files listed via `@source` trigger a full page reload when using `@tailwindcss/vite` ([#19670](https://github.com/tailwindlabs/tailwindcss/pull/19670))
3131
- Improve performance Oxide scanner in bigger projects ([#19632](https://github.com/tailwindlabs/tailwindcss/pull/19632))
32+
- Ensure import aliases in Astro v5 work without crashing ([#19677](https://github.com/tailwindlabs/tailwindcss/issues/19677))
3233

3334
### Deprecated
3435

integrations/vite/astro.test.ts

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { candidate, fetchStyles, html, js, json, retryAssertion, test, ts } from '../utils'
1+
import { candidate, css, fetchStyles, html, js, json, retryAssertion, test, ts } from '../utils'
22

33
test(
44
'dev mode',
@@ -129,3 +129,73 @@ test(
129129
await fs.expectFileToContain(files[0][0], [candidate`underline`, candidate`overline`])
130130
},
131131
)
132+
133+
// https://github.com/tailwindlabs/tailwindcss/issues/19677
134+
test(
135+
'import aliases should work in <style> blocks',
136+
{
137+
fs: {
138+
'package.json': json`
139+
{
140+
"type": "module",
141+
"dependencies": {
142+
"astro": "^5",
143+
"@tailwindcss/vite": "workspace:^",
144+
"tailwindcss": "workspace:^"
145+
}
146+
}
147+
`,
148+
'astro.config.mjs': ts`
149+
import tailwindcss from '@tailwindcss/vite'
150+
import { defineConfig } from 'astro/config'
151+
152+
// https://astro.build/config
153+
export default defineConfig({
154+
vite: { plugins: [tailwindcss()] },
155+
})
156+
`,
157+
'tsconfig.json': json`
158+
{
159+
"extends": "astro/tsconfigs/strict",
160+
"include": [".astro/types.d.ts", "**/*"],
161+
"exclude": ["dist"],
162+
"compilerOptions": {
163+
"paths": {
164+
"@styles/*": ["./src/styles/*"]
165+
}
166+
}
167+
}
168+
`,
169+
// prettier-ignore
170+
'src/pages/index.astro': html`
171+
---
172+
import '@styles/global.css'
173+
---
174+
175+
<html lang="en">
176+
<head>
177+
<meta charset="utf-8" />
178+
<meta name="viewport" content="width=device-width" />
179+
<meta name="generator" content={Astro.generator} />
180+
<title>Astro</title>
181+
<style>
182+
@reference "@styles/global.css";
183+
</style>
184+
</head>
185+
<body>
186+
<h1 class="underline">Astro</h1>
187+
</body>
188+
</html>
189+
`,
190+
'src/styles/global.css': css`@import 'tailwindcss';`,
191+
},
192+
},
193+
async ({ fs, exec, expect }) => {
194+
await exec('pnpm astro build')
195+
196+
let files = await fs.glob('dist/**/*.css')
197+
expect(files).toHaveLength(1)
198+
199+
await fs.expectFileToContain(files[0][0], [candidate`underline`])
200+
},
201+
)

packages/@tailwindcss-vite/src/index.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ import { Scanner } from '@tailwindcss/oxide'
1212
import { realpathSync } from 'node:fs'
1313
import fs from 'node:fs/promises'
1414
import path from 'node:path'
15-
import type { Environment, Plugin, ResolvedConfig, ViteDevServer } from 'vite'
15+
import type {
16+
Environment,
17+
InternalResolveOptions,
18+
Plugin,
19+
ResolvedConfig,
20+
ViteDevServer,
21+
} from 'vite'
1622
import * as vite from 'vite'
1723

1824
const DEBUG = env.DEBUG
@@ -59,8 +65,36 @@ export default function tailwindcss(opts: PluginOptions = {}): Plugin[] {
5965
customCssResolver = (id: string, base: string) => cssResolver(id, base, true, isSSR)
6066
customJsResolver = (id: string, base: string) => jsResolver(id, base, true, isSSR)
6167
} else {
68+
type ResolveIdFn = (
69+
environment: Environment,
70+
id: string,
71+
importer?: string,
72+
aliasOnly?: boolean,
73+
) => Promise<string | undefined>
74+
75+
// There are cases where Environment API is available,
76+
// but `createResolver` is still overriden (for example astro v5)
77+
//
78+
// Copied as-is from vite, because this function is not a part of public API
79+
//
80+
// TODO: Remove this function and pre-environment code when Vite < 7 is no longer supported
81+
function createBackCompatIdResolver(
82+
config: ResolvedConfig,
83+
options?: Partial<InternalResolveOptions>,
84+
): ResolveIdFn {
85+
const compatResolve = config.createResolver(options)
86+
let resolve: ResolveIdFn
87+
return async (environment, id, importer, aliasOnly) => {
88+
if (environment.name === 'client' || environment.name === 'ssr') {
89+
return compatResolve(id, importer, aliasOnly, environment.name === 'ssr')
90+
}
91+
resolve ??= vite.createIdResolver(config, options)
92+
return resolve(environment, id, importer, aliasOnly)
93+
}
94+
}
95+
6296
// Newer Vite versions
63-
let cssResolver = vite.createIdResolver(env.config, {
97+
let cssResolver = createBackCompatIdResolver(env.config, {
6498
...env.config.resolve,
6599
extensions: ['.css'],
66100
mainFields: ['style'],
@@ -69,7 +103,7 @@ export default function tailwindcss(opts: PluginOptions = {}): Plugin[] {
69103
preferRelative: true,
70104
})
71105

72-
let jsResolver = vite.createIdResolver(env.config, env.config.resolve)
106+
let jsResolver = createBackCompatIdResolver(env.config, env.config.resolve)
73107

74108
customCssResolver = (id: string, base: string) => cssResolver(env, id, base, true)
75109
customJsResolver = (id: string, base: string) => jsResolver(env, id, base, true)

0 commit comments

Comments
 (0)