Skip to content

Commit 2fb95bb

Browse files
feat(un-jsx): inline constant tag inlining (#129)
* feat(un-jsx): improve jsx constant tag inlining * test: update test cases * refactor(un-jsx): remove array inlining * refactor(un-jsx): remove ternary inlining * refactor(un-jsx): rewrite the implementation of constant tag variable inlining --------- Co-authored-by: Pionxzh <[email protected]>
1 parent 8546f81 commit 2fb95bb

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

packages/unminify/src/transformations/__tests__/un-jsx.spec.ts

+29
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,35 @@ const Foo = () => {
206206
`,
207207
)
208208

209+
inlineTest('jsx with dynamic Component tag - tag name in constant variable',
210+
`
211+
function fn() {
212+
const Name = "div";
213+
return React.createElement(Name, null);
214+
}
215+
`,
216+
`
217+
function fn() {
218+
return <div />;
219+
}
220+
`,
221+
)
222+
223+
inlineTest('jsx with dynamic Component tag - tag name in constant variable but the value is not a string',
224+
`
225+
function fn() {
226+
const Name = 1;
227+
return React.createElement(Name, null);
228+
}
229+
`,
230+
`
231+
function fn() {
232+
const Name = 1;
233+
return <Name />;
234+
}
235+
`,
236+
)
237+
209238
inlineTest('jsx with child text that should be wrapped',
210239
`
211240
function fn() {

packages/unminify/src/transformations/un-jsx.ts

+22-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { removePureAnnotation } from '@wakaru/ast-utils/comments'
44
import { generateName } from '@wakaru/ast-utils/identifier'
55
import { insertBefore } from '@wakaru/ast-utils/insert'
66
import { isNull, isTrue, isUndefined } from '@wakaru/ast-utils/matchers'
7+
import { findDeclaration, removeDeclarationIfUnused } from '@wakaru/ast-utils/scope'
78
import { nonNullable } from '@wakaru/shared/array'
89
import { createJSCodeshiftTransformationRule } from '@wakaru/shared/rule'
910
import { z } from 'zod'
@@ -106,7 +107,6 @@ export const transformAST: ASTTransformation<typeof Schema> = (context, params)
106107
if (jsxElement) {
107108
const parentWithComments = j.ExpressionStatement.check(path.parent.node) ? path.parent : path
108109
removePureAnnotation(j, parentWithComments.node)
109-
110110
path.replace(jsxElement)
111111
}
112112
})
@@ -131,6 +131,27 @@ function toJSX(j: JSCodeshift, path: ASTPath<CallExpression>, pragmas: string[],
131131
if (isCapitalizationInvalid(j, type)) return null
132132

133133
let tag = toJsxTag(j, type)
134+
135+
// constant tag name will convert into JSX tag
136+
if (j.JSXIdentifier.check(tag)) {
137+
const scope = path.scope
138+
assertScopeExists(scope)
139+
140+
const tagName = tag.name
141+
const declaration = findDeclaration(scope, tagName)
142+
if (declaration) {
143+
// if the tag is a variable and it's string literal, inline it
144+
const variableDeclarator = j(declaration).closest(j.VariableDeclarator)
145+
if (variableDeclarator.size() === 1) {
146+
const init = variableDeclarator.get().node.init
147+
if (j.StringLiteral.check(init)) {
148+
tag = j.jsxIdentifier(init.value)
149+
removeDeclarationIfUnused(j, path, tagName)
150+
}
151+
}
152+
}
153+
}
154+
134155
// If a tag cannot be converted to JSX tag, convert it to a variable
135156
if (!tag && !j.SpreadElement.check(type)) {
136157
const name = generateName('Component', scope)

0 commit comments

Comments
 (0)