-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
CSS codemod: inject @import in a more expected location
#14536
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@improt in a more expected location@import in a more expected location
| /**! | ||
| * License header | ||
| */ | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't add html {} before these imports because that would be an invalid input.
| function migrate(root: Root) { | ||
| let baseNode: AtRule | null = null | ||
| let utilitiesNode: AtRule | null = null | ||
| let baseNode = null as AtRule | null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer the let baseNode: AtRule | null = null approach, but the types were wrong after the fact (either null or never). Didn't want to change tsconfigs (since they are shared) so solved it this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems really weird to me because the behavior between the declarations should be identical 🤔
|
@RobinMalfait In this scenario: /**! My license comment */
html {
color: red;
}
@tailwind base;
@tailwind components;
@tailwind utilities;...I think it's important that it compiles to this: /**! My license comment */
@import "tailwindcss";
@layer base {
html {
color: red;
}
}…otherwise any utility classes you add to the |
c8968bb to
6ed62bd
Compare
This test makes sure that we inject the new `@import` in the correct locations.
The idea is that we replace `@tailwind base; @tailwind components; @tailwind utilities;` with the much simple `@import "tailwindcss";`. We did this by adding the `@import` to the top of the file. While this is correct, this means that the diff might not be as clear. For example, if you have a situation where you have a license comment: ```css /**! My license comment */ @tailwind base; @tailwind components; @tailwind utilities; ``` This resulted in: ```css @import "tailwindcss"; /**! My license comment */ ``` While it is not wrong, it feels weird that this behaves like this. In this commit we make sure that it is injected in-place (the first `@tailwind` at-rule we find) and fixup the position if we can't inject it in-place. The above example results in this: ```css /**! My license comment */ @import "tailwindcss"; ``` However, there are scenario's where you can't replace the `@tailwind` directives directly. E.g.: ```css /**! My license comment */ html { color: red; } @tailwind base; @tailwind components; @tailwind utilities; ``` If we replace the `@tailwind` directives in-place, it would look like this: ```css /**! My license comment */ html { color: red; } @import "tailwindcss"; ``` But this is invalid CSS, because you can't have CSS above an `@import` at-rule. There are some exceptions like: - `@charset` - `@import` - `@layer foo, bar;` (just the order, without a body) - comments In this scenario, we inject the import in the nearest place where it is allowed to. In this case: ```css /**! My license comment */ @import "tailwindcss"; html { color: red; } ``` Note that the (license) comment is allowed to exist before the `@import`, therefore we do not put the `@import` above it. This also means that the diff doesn't touch the license header at all, which makes the diffs cleaner and easier to reason about.
1. One of the experimental codemods is new, and not a fix 2. Grouped the codemods together
These don't have to be wrapped in a layer.
6ed62bd to
67ae8b4
Compare
We already had it.
packages/@tailwindcss-upgrade/src/codemods/migrate-missing-layers.ts
Outdated
Show resolved
Hide resolved
…ers.ts Co-authored-by: Philipp Spiess <[email protected]>
This PR inserts the
@importin a more sensible location when running codemods.The idea is that we replace
@tailwind base; @tailwind components; @tailwind utilities;with the much simple@import "tailwindcss";. We did this by adding the@importto the top of the file.While this is correct, this means that the diff might not be as clear. For example, if you have a situation where you have a license comment:
This resulted in:
While it is not wrong, it feels weird that this behaves like this. In this commit we make sure that it is injected in-place (the first
@tailwindat-rule we find) and fixup the position if we can't inject it in-place.The above example results in this:
However, there are scenario's where you can't replace the
@tailwinddirectives directly. E.g.:If we replace the
@tailwinddirectives in-place, it would look like this:But this is invalid CSS, because you can't have CSS above an
@importat-rule. There are some exceptions like:@charset@import@layer foo, bar;(just the order, without a body)In this scenario, we inject the import in the nearest place where it is allowed to. In this case:
Additionally, we will wrap the existing CSS in an
@layerof the first Tailwind directive we saw. In this case an@layer base. This ensures that utilities still win from the default styles.Also note that the (license) comment is allowed to exist before the
@import, therefore we do not put the@importabove it. This also means that the diff doesn't touch the license header at all, which makes the diffs cleaner and easier to reason about.