-
Notifications
You must be signed in to change notification settings - Fork 51
/
Copy pathparse.js
124 lines (105 loc) · 3.13 KB
/
parse.js
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// babel-plugin-parse-mp-info.js
const generate = require('babel-generator').default
const babelon = require('babelon')
const { getImportsMap } = require('./util')
// 解析 config
const traverseConfigVisitor = {
Property: function (path) {
const k = path.node.key.name || path.node.key.value
if (k !== 'config') {
return
}
path.stop()
const { metadata } = path.hub.file
const { code } = generate(path.node.value, {}, '')
metadata.config = { code, node: path.node.value, value: babelon.eval(code) }
// path.remove()
}
}
// config 的遍历器
const configVisitor = {
ExportDefaultDeclaration: function (path) {
path.traverse(traverseConfigVisitor)
path.remove()
},
NewExpression: function (path) {
const { metadata } = path.hub.file
const { importsMap } = getImportsMap(metadata)
const calleeName = path.node.callee.name
const isVue = /vue$/.test(importsMap[calleeName])
if (!isVue) {
return
}
const arg = path.node.arguments[0]
if (!arg) {
return
}
const v = arg.type === 'Identifier' ? importsMap[arg.name] : importsMap['App']
metadata.rootComponent = v || importsMap['index'] || importsMap['main']
}
}
function parseConfig (babel) {
return { visitor: configVisitor }
}
// 解析 components
const traverseComponentsVisitor = {
Property: function (path) {
if (path.node.key.name !== 'components') {
return
}
path.stop()
const { metadata } = path.hub.file
const { importsMap } = getImportsMap(metadata)
// 找到所有的 imports
const { properties } = path.node.value
const components = {}
properties.forEach(p => {
const k = p.key.name || p.key.value
const v = p.value.name || p.value.value
// 保留组件引用路径及模块名
components[k] = {
src: importsMap[v],
module: v
}
})
metadata.components = components
}
}
// components 的遍历器
const componentsVisitor = {
ExportDefaultDeclaration: function (path) {
path.traverse(traverseComponentsVisitor)
}
}
function parseComponentsDeps (babel) {
return { visitor: componentsVisitor }
}
// 解析全局components
let globalComponents = {}
const globalComponentsVisitor = {
CallExpression (path) {
const { callee, arguments: args } = path.node
const { metadata } = path.hub.file
if (!callee.object || !callee.property) {
return
}
if (callee.object.name === 'Vue' && callee.property.name === 'component') {
if (!args[0] || args[0].type !== 'StringLiteral') {
throw new Error('Vue.component()的第一个参数必须为静态字符串')
}
if (!args[1]) {
throw new Error('Vue.component()需要两个参数')
}
const { importsMap } = getImportsMap(metadata)
globalComponents[args[0].value] = importsMap[args[1].name]
}
metadata.globalComponents = globalComponents
}
}
function parseGlobalComponents (babel) {
return { visitor: globalComponentsVisitor }
}
function clearGlobalComponents () {
globalComponents = {}
}
module.exports = { parseConfig, parseComponentsDeps, parseGlobalComponents, clearGlobalComponents }