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">
This commit is contained in:
parent
744e43fc0e
commit
b07832772a
22 changed files with 450 additions and 99 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import watcher from '@parcel/watcher'
|
||||
import { IO, Parsing, scanDir, scanFiles, type ChangedContent } from '@tailwindcss/oxide'
|
||||
import fixRelativePathsPlugin from 'internal-postcss-fix-relative-paths'
|
||||
import { Features, transform } from 'lightningcss'
|
||||
import { existsSync } from 'node:fs'
|
||||
import fs from 'node:fs/promises'
|
||||
|
|
@ -259,6 +260,7 @@ function handleImports(
|
|||
|
||||
return postcss()
|
||||
.use(atImport())
|
||||
.use(fixRelativePathsPlugin())
|
||||
.process(input, { from: file })
|
||||
.then((result) => [
|
||||
result.css,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue