vueconf续:VIDE是怎么样从AST层分析vue文件进行提示的
Posted 大前端工程师
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vueconf续:VIDE是怎么样从AST层分析vue文件进行提示的相关的知识,希望对你有一定的参考价值。
vueconf后,加了好多微信朋友,问我AST层分析vue文件是怎么样做的,今天就特意写一篇文章说一下 从AST这个词出发,然后关联js,我们应该很快就会联想到babel,的确,vide也是基于babel来分析vue文件,从来在编辑器界面进行友好提示。
首先,vide在打开vue文件后,引擎就会判断,是否是vue文件,如果是vue文件,就会调用对vue文件分析的函数
第一步,利用child_process模块,开一个子进程,以免block整个ide,然后利用vue-template-compiler模块提取vue文件中的script部分,对js进行分析提取(目前只分析了js,之后会分析template和style)
第二步,提取完js部分后,我们就需要用到babylon(babel中的javascript的parser),通过babylon来分析之前的js片段,具体代码如下
var result = babylon.parse(scriptContent, {
sourceType:'module',
plugins: '*'
})
第三步,用babylon解析完之后,我们就需要使用babel-traverse这个模块来遍历AST树了,根据traverse的原理,对相应的语句类型进行分析,从而提取出我们想要的内容
traverse(result, {
//vue是通过export default来导出的,那就分析这个类型
ExportDefaultDeclaration (path) {
path.traverse({
ObjectProperty (subpath) {
if (subpath.parentPath.parentPath.type !== 'ExportDefaultDeclaration') {
return
}
//分析vue文件的函数及其参数和位置
if (subpath.node.key.name === 'methods') {
subpath.node.value.properties.forEach((property) => {
let name = property.key.name
let params = property.params.map((param) => {
return param.name ? param.name : param.left.name
})
mapResult.component.methods[name] = {
row: property.loc.start.line,
params
}
})
} else if (subpath.node.key.name === 'computed') {
// 获取通过computed计算的值
let properties = subpath.node.value.properties
properties.forEach((property) => {
if (property.key && property.key.name) {
mapResult.component.variables.push(property.key.name)
} else {
subpath.traverse({
SpreadProperty (_path) {
_path.traverse({
ObjectExpression (__path) {
__path.node.properties.forEach((property) => {
if (property.key.name) {
mapResult.component.variables.push(property.key.name)
}
})
}
})
}
})
}
})
}
},
ObjectMethod (subpath) {
if (subpath.parentPath.parentPath.type !== 'ExportDefaultDeclaration') {
return
}
// 获取data返回的自动,组件的属性值
if (subpath.node.key.name === 'data' && subpath.node.kind === 'method') {
subpath.traverse({
ReturnStatement (path) {
path.node.argument.properties.forEach((property) => {
mapResult.component.variables.push(property.key.name)
})
}
})
}
}
})
},
FunctionDeclaration (path) {
//分析常规函数
let node = path.node
let name = node.id.name
let params = []
try {
params = node.params.map((param) => {
if (param.type === 'ObjectPattern') {
return scriptContent.split('\n')[param.loc.start.line - 1].slice(param.loc.start.column, param.loc.end.column)
} else {
return param.name ? param.name : param.left.name
}
})
} catch (e) {}
let value = {
row: node.id.loc.start.line,
params
}
mapResult.funcs[name] = value
}
})
第四步,分析完后,得到相应的结果集,然后通过process.send把数据返回给父进程供ide的自动化提示
插件
vide-plugin-prompt-vue
总结
对于目前的vue提示插件,只做到了冰山一角,还可以深度挖掘,之后把全部的vue全家桶插件做完之后,再给大家讨论更多的。
如果大家有什么建议或者想要怎么样的功能,可以回复我,我之后把这些插件统一到vue全家桶开发插件当中,方便大家对vue的开发
回顾我以前的文章:
以上是关于vueconf续:VIDE是怎么样从AST层分析vue文件进行提示的的主要内容,如果未能解决你的问题,请参考以下文章