tailwindcss/packages/@tailwindcss-upgrade/src/codemods/format-nodes.test.ts
Robin Malfait d869442a54
Add CSS codemod for missing @layer (#14504)
This PR adds a codemod that ensures that some parts of your stylesheet
are wrapped in an `@layer`.

This is a follow-up PR of #14411, in that PR we migrate `@tailwind`
directives to imports.

As a quick summary, that will turn this:
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

Into:
```css
@import 'tailwindcss';
```

But there are a few issues with that _if_ we have additional CSS on the
page. For example let's imagine we had this:
```css
@tailwind base;

body {
  background-color: red;
}

@tailwind components;

.btn {}

@tailwind utilities;
```

This will now be turned into:
```css
@import 'tailwindcss';

body {
  background-color: red;
}

.btn {}
```

But in v4 we use real layers, in v3 we used to replace the directive
with the result of that layer. This means that now the `body` and `.btn`
styles are in the incorrect spot.

To solve this, we have to wrap them in a layer. The `body` should go in
an `@layer base`, and the `.btn` should be in an `@layer components` to
make sure it's in the same spot as it was before.

That's what this PR does, the original input will now be turned into:

```css
@import 'tailwindcss';

@layer base {
  body {
    background-color: red;
  }
}

@layer components {
  .btn {
  }
}
```

There are a few internal refactors going on as well, but those are less
important.
2024-09-24 16:32:50 +00:00

35 lines
825 B
TypeScript

import postcss, { type Plugin } from 'postcss'
import { expect, it } from 'vitest'
import { formatNodes } from './format-nodes'
function markPretty(): Plugin {
return {
postcssPlugin: '@tailwindcss/upgrade/mark-pretty',
OnceExit(root) {
root.walkAtRules('utility', (atRule) => {
atRule.raws.tailwind_pretty = true
})
},
}
}
function migrate(input: string) {
return postcss()
.use(markPretty())
.use(formatNodes())
.process(input, { from: expect.getState().testPath })
.then((result) => result.css)
}
it('should format PostCSS nodes that are marked with tailwind_pretty', async () => {
expect(
await migrate(`
@utility .foo { .foo { color: red; } }`),
).toMatchInlineSnapshot(`
"@utility .foo {
.foo {
color: red;
}
}"
`)
})