-
Notifications
You must be signed in to change notification settings - Fork 20
Description
网上讲的babylon比较笼统,并没有详细介绍,利用demo剖析一下babylon内部不同的type,以及用babel-traverse如何遍历babel
Babylon type详解
首先看一段babylon转义之后的代码:
这其中包括了:
* comments:注释内容
* loc:location
* program:程序的ast
* tokens: 程序拆分出来的字符串
comments
首先介绍一下comments,下面看一个例子:
应该比较容易读懂,value就是这个注释的具体内容。
program
详细给大家介绍一下program:
大家可以看到 program的body分为了三个部分,分别为:
- ExpressionStatement 表达式语句
表达式语句下面主要为CallExpression,即调用表达式:
调用表达式下面则是程序的主要逻辑拉,见下图:
看到这里大家应该就清晰一点了,body里面其实就是不断地对表达式、变量、函数不断嵌套,形成一套ast - VariableDeclaration 变量声明
变量声明拥有一个declarations的Array,里面存放的是需要声明的变量名,因为都是对变量声明,所以这里面并没有语句(statement)存在。 - FunctionDeclaration 函数声明
函数声明中包含了async属性,来判别是否是async函数以及BlockStatement(块语句),因为函数拥有自己的上下文,所以在这里分离出来一个BlockStatement 来进行管理。
利用babel-traverse来进行筛选遍历节点
一个babylon产生的json通常都有几万行+,那么我们如何快速找出来我们想要的代码树的树枝呢?这个时候babel-traverse就派上用场了。babel-traverse的readme内容比较少,所以详细跟大家说一下如何找出来符合我想要的规则的节点。
const traverse = require('babel-traverse').default
traverse(ast, {
enter(path){
if(path.isExpressionStatement(){
console.log(path.node.start)
}
if(path.isIdentifier({name: 'test'})){
console.dir(path.node)
}
}
})
在这里列出两个demo,第一个是通过isExpressionStatement来查找符合我的条件的表达式节点,并且打出来表达式的开始行数,第二个是通过isIdentifier来找到符合我的条件的节点,并且打印出这个节点。如果我想要获取他的父节点怎么办呢?traverse提供了一个方法:path.node.parentPath
就可以获取到他的父节点了。traverse 还有很多过滤的方法,比如:isDoWhileStatement、isDebuggerStatement、isEmptyStatement、isFile、isIfStatement、isClassMethod、isObjectPattern等等,基本可以满足你的所有查找需求,我就不一一列举了。
利用babel-types来筛选节点
let exp = path.node.expression
if (t.isAssignmentExpression(exp)) {
}
通过babel提供的babel-types包也可以进行节点判断。这个包提供的api很详细,有兴趣的同学可以去它的readme下面详查。
Babylon和babel-traverse暂时就学到了这里,如果有什么疑问或者我的文章写的有什么问题,欢迎在下面回复。😆
by:小菜