Jordan Pittman 6a1df6acf6
Ignore @tailwind utilities inside @reference (#17836)
You can use `@reference "tailwindcss"` or `@reference
"../path/to/your/css/file.css"` to reference your theme for use in
`@apply`, `theme(…)`, etc…

Unfortunatley, because the imported file still contains `@tailwind
utilities` it would trigger a re-scan of the filesystem — even though
the use of `@reference` ensures that no CSS can actually be output by
the import itself.

This PR does two things:
- Adds some explicit feature detection tests for what features we pick
up in a stylesheet based on the CSS written and how things are imported
- Explicitly ignores `@tailwind utilities` inside of `@reference` so it
isn't a trigger for file scanning

Because of how Vite itself handles dependencies editing files on disk
will still trigger a rebuild of any file using `@reference`. This is
because Vite rebuilds files when _any_ of its transitive dependencies
change.

For example, given this Vue file:
```vue
<style>
@reference "./styles.css";
</style>
<template> <!-- ... --> </template>
```

And this stylesheet:
```css
@import "tailwindcss";
```

The dependency chain looks like this: `file.vue -> styles.css -> {all
the sources in your project}`

Vite sees that a file (e.g. `index.html`) has changed, thus `styles.css`
needs change, which means `file.vue` needs to be compiled again as well.
Now in reality we depend on the _on disk_ version of styles.css not the
compiled version but Vite itself doesn't know that (or have a way to
indicate this afaik).

Coming up with a solution to that problem will have to be a separate PR
— but there is a workaround:

### 1. Inline the imports from `@import "tailwindcss";`

Replace this in your main stylesheet:
```css
@import "tailwindcss";
```

with this (this is basically what `node_modules/tailwindcss/index.css`
is):
```css
@layer theme, base, components, utilities;

@import 'tailwindcss/theme' layer(theme);
@import 'tailwindcss/preflight' layer(base);
@import 'tailwindcss/utilities' layer(utilities);

/* the rest of your styles imports, styles, etc… */
```

### 2. Split your stylesheet into "main" and "theme" parts

Your "theme" is comprised of the `@import 'tailwindcss/theme'
layer(theme);` import, any custom `@theme` blocks, any `@config`
directives, and any `@plugin` directives. Move all of these into their
own file.

For example, replace this with two files:

```css
@layer theme, base, components, utilities;
@import 'tailwindcss/theme' layer(theme);
@import 'tailwindcss/preflight' layer(base);
@import 'tailwindcss/utilities' layer(utilities);

@theme {
  --color-primary: #c0ffee;
}

@plugin "./my-plugin.js";

/* the rest of your styles imports, styles, etc… */
```

with a theme file:
```css
@import 'tailwindcss/theme' layer(theme);

/* all your `@theme` stuff goes in this file */
@theme {
  --color-primary: #c0ffee;
}

/* additionally any @config or @plugin does too */
@plugin "./my-plugin.js";
```

and your main CSS file:
```css
@layer theme, base, components, utilities;
@import './my-theme.css'; /* I replaced this import */
@import 'tailwindcss/preflight' layer(base);
@import 'tailwindcss/utilities' layer(utilities);

/* the rest of your styles imports, styles, etc… */
```

### 3. Import only your "theme" file in your Vue components / CSS
modules / etc…

```vue
<style>
@reference "./my-theme.css";
</style>
<template> <!-- ... --> </template>
```

Fixes #17693
2025-05-05 11:21:55 -04:00
..
2024-12-11 15:27:20 +01:00