Skip to content

Commit 2994128

Browse files
authored
feat: implement new-component-api transformation (#58)
1 parent d2c7827 commit 2994128

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { defineInlineTest } from 'jscodeshift/src/testUtils'
2+
const transform = require('../new-component-api')
3+
4+
global.globalApi= []
5+
6+
defineInlineTest(
7+
transform,
8+
{},
9+
`import Vue from 'vue'
10+
import MyComponent from './MyComponent'
11+
Vue.component('my-component', MyComponent)`,
12+
`import MyComponent from './MyComponent'
13+
export default {
14+
install: app => {
15+
app.component('my-component', MyComponent);
16+
}
17+
};;`,
18+
'transform global component registration'
19+
)

transformations/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ type JSTransformationModule = {
88
const transformationMap: {
99
[name: string]: JSTransformationModule
1010
} = {
11+
'new-component-api': require('./new-component-api'),
1112
'vue-class-component-v8': require('./vue-class-component-v8'),
1213
'new-global-api': require('./new-global-api'),
1314
'vue-router-v4': require('./vue-router-v4'),

transformations/new-component-api.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import wrap from '../src/wrapAstTransformation'
2+
import type { ASTTransformation } from '../src/wrapAstTransformation'
3+
import { transformAST as removeExtraneousImport } from './remove-extraneous-import'
4+
import type { GlobalApi } from '../src/global'
5+
import * as _ from 'lodash'
6+
7+
export const transformAST: ASTTransformation = context => {
8+
const { root, j, filename } = context
9+
// find Vue.component
10+
const componentRegistration = root
11+
.find(j.CallExpression, {
12+
callee: {
13+
type: 'MemberExpression',
14+
object: {
15+
name: 'Vue'
16+
},
17+
property: {
18+
name: 'component'
19+
}
20+
}
21+
})
22+
.filter(path => {
23+
return path.parent.parent.value.type === 'Program'
24+
})
25+
26+
let componentArgs: any[] = []
27+
componentRegistration.forEach(({ node }) => {
28+
if (node.arguments.length === 2) {
29+
componentArgs = node.arguments
30+
let componentApi: GlobalApi
31+
if (j.Identifier.check(componentArgs[1])) {
32+
componentApi = { name: componentArgs[1].name, path: filename }
33+
} else {
34+
componentApi = {
35+
name: _.upperFirst(_.camelCase(componentArgs[0].value)),
36+
path: filename
37+
}
38+
}
39+
global.globalApi.push(componentApi)
40+
}
41+
})
42+
43+
// app.component()
44+
const componentCall = j.callExpression(
45+
j.memberExpression(j.identifier('app'), j.identifier('component')),
46+
componentArgs
47+
)
48+
// app => { app.component() }
49+
const installArrowFunction = j.arrowFunctionExpression(
50+
[j.identifier('app')],
51+
j.blockStatement([j.expressionStatement(componentCall)])
52+
)
53+
54+
// { install: app => {app.component() } }
55+
const objectExpression = j.objectExpression([
56+
j.objectProperty(j.identifier('install'), installArrowFunction)
57+
])
58+
59+
// export default {}
60+
const exportDefaultDeclaration = j.exportDefaultDeclaration(objectExpression)
61+
62+
componentRegistration.replaceWith(() => exportDefaultDeclaration)
63+
64+
removeExtraneousImport(context, { localBinding: 'Vue' })
65+
}
66+
67+
export default wrap(transformAST)
68+
export const parser = 'babylon'

0 commit comments

Comments
 (0)