Skip to content

Commit 951f644

Browse files
authored
Improve missing layer codemod (#14512)
This PR improves the missing layers codemod where everything after the last Tailwind directive can stay as-is without wrapping it in a `@layer` directive. The `@layer` at-rules are only important for CSS that exists between Tailwind directives. E.g.: ```css @tailwind base; html {} @tailwind components; .btn {} @tailwind utilities; .foo {} .bar {} ``` Was transformed into: ```css @import "tailwindcss"; @layer base { html {} } @layer components { .btn {} } @layer utilities { .foo {} .bar {} } ``` But the last `@layer utilities` is already in the correct spot, so we can simplify this to just this instead: ```css @import "tailwindcss"; @layer base { html {} } @layer components { .btn {} } .foo {} .bar {} ```
1 parent c094fad commit 951f644

File tree

3 files changed

+20
-16
lines changed

3 files changed

+20
-16
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
- Nothing yet!
10+
### Fixed
11+
12+
- _Experimental_: Improve codemod output, keep CSS after last Tailwind directive unlayered ([#14512](https://github.com/tailwindlabs/tailwindcss/pull/14512))
1113

1214
## [4.0.0-alpha.25] - 2024-09-24
1315

packages/@tailwindcss-upgrade/src/codemods/migrate-missing-layers.test.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,9 @@ it('should migrate rules between tailwind directives', async () => {
5555
5656
@tailwind utilities;
5757
58-
@layer utilities {
59-
.utility-a {
60-
}
61-
.utility-b {
62-
}
58+
.utility-a {
59+
}
60+
.utility-b {
6361
}"
6462
`)
6563
})

packages/@tailwindcss-upgrade/src/codemods/migrate-missing-layers.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,28 +78,32 @@ export function migrateMissingLayers(): Plugin {
7878

7979
// Track the node
8080
if (lastLayer !== '') {
81-
if (bucket.push(node) !== 1) {
82-
node.remove()
83-
}
81+
bucket.push(node)
8482
}
8583
})
8684

87-
// Add the last bucket if it's not empty
88-
if (bucket.length > 0) {
89-
buckets.push([lastLayer, bucket.splice(0)])
90-
}
91-
9285
// Wrap each bucket in an `@layer` at-rule
9386
for (let [layerName, nodes] of buckets) {
87+
let target = nodes[0]
9488
let layerNode = new AtRule({
9589
name: 'layer',
9690
params: layerName,
97-
nodes,
91+
nodes: nodes.map((node) => {
92+
// Keep the target node as-is, because we will be replacing that one
93+
// with the new layer node.
94+
if (node === target) {
95+
return node
96+
}
97+
98+
// Every other node should be removed from its original position. They
99+
// will be added to the new layer node.
100+
return node.remove()
101+
}),
98102
raws: {
99103
tailwind_pretty: true,
100104
},
101105
})
102-
nodes[0].replaceWith(layerNode)
106+
target.replaceWith(layerNode)
103107
}
104108
}
105109

0 commit comments

Comments
 (0)