-
Notifications
You must be signed in to change notification settings - Fork 54
/
Copy pathremove-trivial-root.ts
89 lines (81 loc) · 2.56 KB
/
remove-trivial-root.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import wrap from '../src/wrapAstTransformation'
import type { ASTTransformation } from '../src/wrapAstTransformation'
import type * as N from 'jscodeshift'
/**
* It is expected to be run after the `createApp` transformataion
* if a root component is trivial, that is, it contains only one simple prop,
* like `{ render: h => h(App) }`, then just use the `App` variable
*
* TODO: implement `remove-trivial-render`,
* move all other rootProps to the second argument of `createApp`
*/
export const transformAST: ASTTransformation = ({ root, j }) => {
const appRoots = root.find(j.CallExpression, (node: N.CallExpression) => {
if (
node.arguments.length === 1 &&
j.ObjectExpression.check(node.arguments[0])
) {
if (j.Identifier.check(node.callee) && node.callee.name === 'createApp') {
return true
}
if (
j.MemberExpression.check(node.callee) &&
j.Identifier.check(node.callee.object) &&
node.callee.object.name === 'Vue' &&
j.Identifier.check(node.callee.property) &&
node.callee.property.name === 'createApp'
) {
return true
}
}
})
appRoots.forEach(({ node: createAppCall }) => {
if (!j.ObjectExpression.check(createAppCall.arguments[0])) {
return
}
const { properties } = createAppCall.arguments[0]
if (properties.length !== 1) {
return
}
const prop = properties[0]
if (j.SpreadProperty.check(prop) || j.SpreadElement.check(prop)) {
return
}
if (
prop.key &&
j.Identifier.check(prop.key) &&
prop.key.name === 'render'
) {
let renderFnBody
if (j.ObjectMethod.check(prop)) {
renderFnBody = prop.body
} else if (j.ArrowFunctionExpression.check(prop.value)) {
renderFnBody = prop.value.body
} else {
return
}
let callExpr
if (j.CallExpression.check(renderFnBody)) {
callExpr = renderFnBody
} else if (
j.BlockStatement.check(renderFnBody) &&
renderFnBody.body.length === 1 &&
j.ReturnStatement.check(renderFnBody.body[0]) &&
j.CallExpression.check(renderFnBody.body[0].argument)
) {
callExpr = renderFnBody.body[0].argument
}
if (
callExpr &&
j.Identifier.check(callExpr.callee) &&
callExpr.callee.name === 'h' &&
callExpr.arguments.length === 1
) {
const rootComponent = callExpr.arguments[0]
createAppCall.arguments[0] = rootComponent
}
}
})
}
export default wrap(transformAST)
export const parser = 'babylon'