Skip to content

Commit ac758be

Browse files
committed
refactor(transformer): simplify template replacement logic
Now only the `css` template literal is replaced, not the entire variable declaration and its usages. This reduces code complexity and improves maintainability.
1 parent 4a17e84 commit ac758be

File tree

2 files changed

+20
-72
lines changed

2 files changed

+20
-72
lines changed

packages/rawstyle/src/transformer.ts

Lines changed: 20 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import { parseSync, Visitor } from 'oxc-parser'
22
import { generateHash } from '@/utils'
3-
import type { TransformResult, CssVarDecl, CssVarRef, Replacement } from '@/types'
3+
import type { TransformResult, Replacement } from '@/types'
44

55
export const transform = (file: string, source: string): TransformResult => {
66
const { program } = parseSync(file, source)
7-
const cssVarDecls: CssVarDecl[] = []
8-
const cssVarRefs: CssVarRef[] = []
7+
const fileHash = generateHash(file)
8+
let transformed = source
9+
let css = ''
910
const replacements: Replacement[] = []
10-
let isInClassNameAttr = false
11-
let activeRange: { start: number, end: number } | null
12-
let currentVarName: string | null
11+
let activeVarName: string | null
1312

1413
new Visitor({
1514
ImportDeclaration(node) {
@@ -24,74 +23,37 @@ export const transform = (file: string, source: string): TransformResult => {
2423
}
2524
},
2625

27-
JSXAttribute(node) {
28-
if (node.name.name !== 'className') return
29-
if (node.value?.type !== 'JSXExpressionContainer') return
30-
isInClassNameAttr = true
31-
},
32-
33-
Identifier(node) {
34-
if (!isInClassNameAttr) return
35-
cssVarRefs.push({ name: node.name, start: node.start, end: node.end })
36-
},
37-
38-
'JSXAttribute:exit'() {
39-
isInClassNameAttr = false
40-
},
41-
4226
VariableDeclaration(node) {
4327
const variableDeclarator = node.declarations[0]
4428
const identifier = variableDeclarator.id
4529
if (identifier.type !== 'Identifier') return
46-
currentVarName = identifier.name
47-
activeRange = { start: node.start, end: node.end }
30+
activeVarName = identifier.name
4831
},
4932

5033
'VariableDeclaration:exit'() {
51-
currentVarName = null
52-
activeRange = null
53-
},
54-
55-
ExpressionStatement(node) {
56-
activeRange = { start: node.start, end: node.end }
57-
},
58-
59-
'ExpressionStatement:exit'() {
60-
activeRange = null
34+
activeVarName = null
6135
},
6236

6337
TaggedTemplateExpression(node) {
6438
const tag = node.tag
6539
if (tag.type !== 'Identifier' || !/^g?css$/.test(tag.name)) return
66-
const template = node.quasi.quasis.map(q => {
67-
const tpl = q.value.cooked ?? ''
68-
const indent = (/^([^\n]*?)\S/m.exec(tpl))?.[1] ?? ''
69-
return tpl.split('\n').map(line => line.replace(indent, '')).join('\n').trim()
70-
}).join('')
71-
if (!activeRange) return
72-
cssVarDecls.push({ name: currentVarName ?? '', tag: tag.name, template, start: activeRange.start, end: activeRange.end })
73-
replacements.push({ start: activeRange.start, end: activeRange.end, replacement: '' })
74-
},
75-
}).visit(program)
7640

77-
let transformed = source
78-
const hash = generateHash(file)
79-
let css = ''
41+
const cssTpl = source.slice(node.quasi.start + 1, node.quasi.end - 1)
42+
let rep = ''
43+
if (tag.name === 'gcss') {
44+
css += cssTpl
45+
rep = '""'
46+
} else {
47+
const clName = `${activeVarName}_${fileHash}`
48+
css += `.${clName} {${cssTpl}}`
49+
rep = `'${activeVarName}_${fileHash}'`
50+
}
8051

81-
for (const cssVar of cssVarDecls) {
82-
if (cssVar.tag === 'gcss') {
83-
css += cssVar.template
84-
} else if (cssVar.tag === 'css') {
85-
const className = `${cssVar.name}_${hash}`
86-
const refs = cssVarRefs.filter(ref => ref.name === cssVar.name)
87-
if (!refs.length) continue
88-
for (const ref of refs) replacements.push({ start: ref.start, end: ref.end, replacement: `'${className}'` })
89-
css += `.${className}{${cssVar.template}}`
90-
}
91-
}
52+
replacements.push({ start: node.start, end: node.end, replacement: rep })
53+
},
54+
}).visit(program)
9255

9356
replacements.sort((a, b) => b.start - a.start)
94-
9557
for (const rep of replacements) transformed = transformed.slice(0, rep.start) + rep.replacement + transformed.slice(rep.end)
9658

9759
return { transformed, css }

packages/rawstyle/src/types.d.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,6 @@ export interface TransformResult {
33
css: string
44
}
55

6-
export interface CssVarRef {
7-
name: string
8-
start: number
9-
end: number
10-
}
11-
12-
export interface CssVarDecl {
13-
name: string
14-
tag: string
15-
template: string
16-
start: number
17-
end: number
18-
}
19-
206
export interface Replacement {
217
start: number
228
end: number

0 commit comments

Comments
 (0)