tailwindcss/packages/@tailwindcss-cli
Philipp Spiess b07832772a Add PostCSS plugin to fix relative @content and @plugin paths in @imported files (#14063)
We noticed an issue that happened when handling relative file imports in
the `@plugin` and the upcoming `@content` APIs. The problem arises from
relative files that are inside `@import`ed stylesheets. Take, for
example, the following folder structure:

```css
/* src/index.css */
@import "./dir/index.css";
```
```css
/* src/dir/index.css */
@plugin "../../plugin.ts";
```

It's expected that the path is relative to the CSS file that defined it.
However, right now, we use
[`postcss-import`](https://github.com/postcss/postcss-import) to flatten
the CSS file before running the tailwind build step. This causes these
custom-properties to be inlined in a flat file which removes the
information of which file is being referred:

```css
/* src/flat.css */
@plugin "../../plugin.ts"; /* <- This is now pointing to the wrong file */
```

There are generally two approaches that we can do to solve this:

1. **Handle `@import` flattening inside tailwindcss:** While generally
this would give us more freedom and less dependencies, this would
require some work to get all edge cases right. We need to support
layers/conditional imports and also handle all relative urls for
properties like `background-image`.
2. **Rewrite relative paths as a separate postcss visitor:** The
approach this PR takes is instead to implement a custom postcss plugin
that uses the AST to rewrite relative references inside `@plugin` and
`@content`. This has the benefit of requiring little changes to our
existing APIs. The rule is only enabled for relative references inside
`@plugin` and `@content`, so the surface of this rule is very small.

We can use this plugin inside all three current clients:

- `@tailwindcss/postcss` obviously already uses postcss
- `@tailwindcss/cli` also uses postcss to handle `@import` flattening
- `@tailwindcss/vite` allows us to add custom postcss rules via the CSS
pipeline. There are a few cases that we handle with care (e.g. in vite
you can pass a string to the postcss config which is supposed to load
the config from a file).

To validate the changes, we have added both a list of unit test cases to
the plugin itself as well as verified that all three clients are working
as expected:

- `@tailwindcss/postcss` now has an explicit test for this behavior
- `@tailwindcss/cli` and `@tailwindcss/vite` were manually tested by
updating the vite playground. The CLI was run with `--cwd
playgrounds/vite/ -i ./src/app.css -o foo.css`:
<img width="531" alt="Screenshot 2024-07-29 at 11 35 59"
src="https://github.com/user-attachments/assets/78f0acdc-a46c-4c6c-917a-2916417b1001">
2024-07-30 14:06:06 +02:00
..
src Add PostCSS plugin to fix relative @content and @plugin paths in @imported files (#14063) 2024-07-30 14:06:06 +02:00
package.json Add PostCSS plugin to fix relative @content and @plugin paths in @imported files (#14063) 2024-07-30 14:06:06 +02:00
README.md Copy README file to every package (#13096) 2024-03-06 08:49:31 -05:00
tsconfig.json Move the CLI to its own package @tailwindcss/cli (#13095) 2024-03-06 05:41:12 -05:00
tsup.config.ts Add PostCSS plugin to fix relative @content and @plugin paths in @imported files (#14063) 2024-07-30 14:06:06 +02:00

Tailwind CSS

A utility-first CSS framework for rapidly building custom user interfaces.

Build Status Total Downloads Latest Release License


Documentation

For full documentation, visit tailwindcss.com.

Community

For help, discussion about best practices, or any other conversation that would benefit from being searchable:

Discuss Tailwind CSS on GitHub

For chatting with others using the framework:

Join the Tailwind CSS Discord Server

Contributing

If you're interested in contributing to Tailwind CSS, please read our contributing docs before submitting a pull request.