Skip to content

Commit ca07ca8

Browse files
authored
Only output @property foo once instead of N times (#13087)
* only output `@property foo` once instead of N times * compute the indent once * improve performance by using strings and for-loops * drop unnecessary new line
1 parent 191643f commit ca07ca8

File tree

1 file changed

+27
-11
lines changed
  • packages/tailwindcss/src

1 file changed

+27
-11
lines changed

packages/tailwindcss/src/ast.ts

+27-11
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,19 @@ export function walk(
7272
}
7373

7474
export function toCss(ast: AstNode[]) {
75-
let atRoots: string[] = []
75+
let atRoots: string = ''
76+
let seenAtProperties = new Set<string>()
7677

7778
function stringify(node: AstNode, depth = 0): string {
7879
let css = ''
80+
let indent = ' '.repeat(depth)
7981

8082
// Rule
8183
if (node.kind === 'rule') {
8284
// Pull out `@at-root` rules to append later
8385
if (node.selector === '@at-root') {
8486
for (let child of node.nodes) {
85-
atRoots.push(stringify(child, 0))
87+
atRoots += stringify(child, 0)
8688
}
8789
return css
8890
}
@@ -95,31 +97,45 @@ export function toCss(ast: AstNode[]) {
9597
// @layer base, components, utilities;
9698
// ```
9799
if (node.selector[0] === '@' && node.nodes.length === 0) {
98-
return `${' '.repeat(depth)}${node.selector};\n`
100+
return `${indent}${node.selector};\n`
99101
}
100102

101-
css += `${' '.repeat(depth)}${node.selector} {\n`
103+
if (node.selector[0] === '@' && node.selector.startsWith('@property ') && depth === 0) {
104+
// Don't output duplicate `@property` rules
105+
if (seenAtProperties.has(node.selector)) {
106+
return ''
107+
}
108+
109+
seenAtProperties.add(node.selector)
110+
}
111+
112+
css += `${indent}${node.selector} {\n`
102113
for (let child of node.nodes) {
103114
css += stringify(child, depth + 1)
104115
}
105-
css += `${' '.repeat(depth)}}\n`
116+
css += `${indent}}\n`
106117
}
107118

108119
// Comment
109120
else if (node.kind === 'comment') {
110-
css += `${' '.repeat(depth)}/*${node.value}*/\n`
121+
css += `${indent}/*${node.value}*/\n`
111122
}
112123

113124
// Declaration
114125
else if (node.property !== '--tw-sort' && node.value !== undefined && node.value !== null) {
115-
css += `${' '.repeat(depth)}${node.property}: ${node.value}${node.important ? '!important' : ''};\n`
126+
css += `${indent}${node.property}: ${node.value}${node.important ? '!important' : ''};\n`
116127
}
117128

118129
return css
119130
}
120131

121-
return ast
122-
.map((node) => stringify(node))
123-
.concat(atRoots)
124-
.join('\n')
132+
let css = ''
133+
for (let node of ast) {
134+
let result = stringify(node)
135+
if (result !== '') {
136+
css += result
137+
}
138+
}
139+
140+
return `${css}${atRoots}`
125141
}

0 commit comments

Comments
 (0)