SIGN IN SIGN UP

A utility-first CSS framework for rapid UI development.

0 0 25 TypeScript

fix(vite): avoid resolving JS plugins to browser CSS entries (#19949)

Edit: some edits by @RobinMalfait 

---

## Summary

Fix a regression in `@tailwindcss/vite` introduced by `#19803` where JS
plugin resolution could incorrectly resolve a package to its `browser`
CSS entry.

In cases like `daisyui`, Vite can resolve `@plugin "daisyui"` to
`daisyui.css` instead of the package's JS entry, which causes Tailwind
to try to load a CSS file as a JS plugin and fail with:

```txt
Unknown file extension ".css"
```

This change keeps the `aliasOnly: false` behavior from `#19803` so
tsconfig path resolution still works, but adds a JS-entry guard to
`customJsResolver` in `@tailwindcss/vite`. If Vite resolves a plugin
request to a non-JS file like `.css`, the custom resolver now returns
`undefined` so Tailwind's internal fallback resolver can resolve the
package as a JS plugin entry instead.

I also added integration coverage for a package whose `main`/`module`
points to JS while `browser` points to CSS, and verified that `@plugin
"pkg"` still resolves to the JS entry in both build and dev mode.

## Test plan

Added new integration tests in `integrations/vite/resolvers.test.ts`
covering a package with:

- `main` / `module` -> JS
- `browser` -> CSS
- `@plugin "pkg"` -> should resolve to JS, not CSS

Verified with:

```sh
pnpm test:integrations vite/resolvers.test.ts -t "browser points to CSS"
pnpm test:integrations vite/resolvers.test.ts -t "resolves tsconfig paths"
```

These verify that:

- `@plugin` no longer resolves to a CSS browser entry
- the original tsconfig paths fix from `#19803` still works in both
build and dev mode

---

Maintainer edits:

Instead of hardcoding file extensions, first try to resolve aliases and
then fallback to the default resolving system we had before. We still
check for a `.css` extension, even in the JS resolver because some
dependencies (like `daisyUI`) put the CSS file there instead of in an
`exports.style`. If we detect that, we still fallback to the default
resolving logic.

This should be compatible with the original issue we were trying to fix
where we wanted to make Vite aliases work.

Fixes: #19950

[ci-all]

---------

Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
A
ArcherGu committed
f3fdda2a5cb9de50c897c79003aa58182cd9269b
Parent: 69ad7cc
Committed by GitHub <noreply@github.com> on 4/22/2026, 3:25:01 PM