Skip to content

Commit 317fba1

Browse files
Fix source maps of variant utilities that come from an @layer rule (#12508)
* Refactor * Keep traversing sibling nodes * Make sure the root node has a source location for the end * Add source map test for at-rule variants * Update changelog
1 parent 3169d15 commit 317fba1

File tree

4 files changed

+45
-15
lines changed

4 files changed

+45
-15
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
- Improve candidate detection in minified JS arrays (without spaces) ([#12396](https://github.com/tailwindlabs/tailwindcss/pull/12396))
1717
- Don't crash when given applying a variant to a negated version of a simple utility ([#12514](https://github.com/tailwindlabs/tailwindcss/pull/12514))
1818
- Fix support for slashes in arbitrary modifiers ([#12515](https://github.com/tailwindlabs/tailwindcss/pull/12515))
19+
- Fix source maps of variant utilities that come from an `@layer` rule ([#12508](https://github.com/tailwindlabs/tailwindcss/pull/12508))
1920
- [Oxide] Remove `autoprefixer` dependency ([#11315](https://github.com/tailwindlabs/tailwindcss/pull/11315))
2021
- [Oxide] Fix source maps issue resulting in a crash ([#11319](https://github.com/tailwindlabs/tailwindcss/pull/11319))
2122
- [Oxide] Fallback to RegEx based parser when using custom transformers or extractors ([#11335](https://github.com/tailwindlabs/tailwindcss/pull/11335))

src/lib/expandTailwindAtRules.js

+3
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,9 @@ export default function expandTailwindAtRules(context) {
291291
root.append(cloned)
292292
}
293293

294+
// TODO: Why is the root node having no source location for `end` possible?
295+
root.source.end = root.source.end ?? root.source.start
296+
294297
// If we've got a utility layer and no utilities are generated there's likely something wrong
295298
const hasUtilityVariants = variantNodes.some(
296299
(node) => node.raws.tailwind?.parentLayer === 'utilities'

src/util/cloneNodes.js

+35-14
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,49 @@
1+
/**
2+
* @param {import('postcss').Container[]} nodes
3+
* @param {any} source
4+
* @param {any} raws
5+
* @returns {import('postcss').Container[]}
6+
*/
17
export default function cloneNodes(nodes, source = undefined, raws = undefined) {
28
return nodes.map((node) => {
39
let cloned = node.clone()
410

5-
// We always want override the source map
6-
// except when explicitly told not to
7-
let shouldOverwriteSource = node.raws.tailwind?.preserveSource !== true || !cloned.source
8-
9-
if (source !== undefined && shouldOverwriteSource) {
10-
cloned.source = source
11-
12-
if ('walk' in cloned) {
13-
cloned.walk((child) => {
14-
child.source = source
15-
})
16-
}
17-
}
18-
1911
if (raws !== undefined) {
2012
cloned.raws.tailwind = {
2113
...cloned.raws.tailwind,
2214
...raws,
2315
}
2416
}
2517

18+
if (source !== undefined) {
19+
traverse(cloned, (node) => {
20+
// Do not traverse nodes that have opted
21+
// to preserve their original source
22+
let shouldPreserveSource = node.raws.tailwind?.preserveSource === true && node.source
23+
if (shouldPreserveSource) {
24+
return false
25+
}
26+
27+
// Otherwise we can safely replace the source
28+
// And continue traversing
29+
node.source = source
30+
})
31+
}
32+
2633
return cloned
2734
})
2835
}
36+
37+
/**
38+
* Traverse a tree of nodes and don't traverse children if the callback
39+
* returns false. Ideally we'd use Container#walk instead of this
40+
* function but it stops traversing siblings too.
41+
*
42+
* @param {import('postcss').Container} node
43+
* @param {(node: import('postcss').Container) => boolean} onNode
44+
*/
45+
function traverse(node, onNode) {
46+
if (onNode(node) !== false) {
47+
node.each?.((child) => traverse(child, onNode))
48+
}
49+
}

tests/source-maps.test.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ test('components have source maps', async () => {
427427

428428
test('source maps for layer rules are not rewritten to point to @tailwind directives', async () => {
429429
let config = {
430-
content: [{ raw: `font-normal foo hover:foo` }],
430+
content: [{ raw: `font-normal foo hover:foo lg:foo` }],
431431
}
432432

433433
let utilitiesFile = postcss.parse(
@@ -481,6 +481,11 @@ test('source maps for layer rules are not rewritten to point to @tailwind direct
481481
"6:0 -> 6:0",
482482
"7:2-23 -> 7:2-23",
483483
"8:0 -> 8:0",
484+
"10:0 -> 10:0",
485+
"11:2 -> 11:2",
486+
"12:4-25 -> 12:4-25",
487+
"13:2 -> 13:2",
488+
"14:0 -> 14:0",
484489
]
485490
`)
486491
})

0 commit comments

Comments
 (0)