Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Babylon和babel-traverse详解 #7

Open
xtx1130 opened this issue Nov 13, 2017 · 5 comments
Open

Babylon和babel-traverse详解 #7

xtx1130 opened this issue Nov 13, 2017 · 5 comments
Labels

Comments

@xtx1130
Copy link
Owner

xtx1130 commented Nov 13, 2017

网上讲的babylon比较笼统,并没有详细介绍,利用demo剖析一下babylon内部不同的type,以及用babel-traverse如何遍历babel

Babylon type详解

首先看一段babylon转义之后的代码:
issue7-1
这其中包括了:
* comments:注释内容
* loc:location
* program:程序的ast
* tokens: 程序拆分出来的字符串

comments

首先介绍一下comments,下面看一个例子:
issue7-2
应该比较容易读懂,value就是这个注释的具体内容。

program

详细给大家介绍一下program:
issue7-3
大家可以看到 program的body分为了三个部分,分别为:

  • ExpressionStatement 表达式语句
    表达式语句下面主要为CallExpression,即调用表达式:
    issue7-4
    调用表达式下面则是程序的主要逻辑拉,见下图:
    issue7-5
    看到这里大家应该就清晰一点了,body里面其实就是不断地对表达式、变量、函数不断嵌套,形成一套ast
  • VariableDeclaration 变量声明
    issue7-6
    变量声明拥有一个declarations的Array,里面存放的是需要声明的变量名,因为都是对变量声明,所以这里面并没有语句(statement)存在。
  • FunctionDeclaration 函数声明
    issue7-7
    函数声明中包含了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:小菜

@xtx1130 xtx1130 added the 框架 label Nov 13, 2017
@Pines-Cheng
Copy link

Pines-Cheng commented Jul 17, 2018

为什么不用 https://astexplorer.net/ ,为什么不用 https://astexplorer.net/ ,为什么不用 https://astexplorer.net/~

@xtx1130
Copy link
Owner Author

xtx1130 commented Jul 17, 2018

@Pines-Cheng console里面截图还方便。。。

@Landon-CN
Copy link

请问babel-traverse里的api哪里找呢,我在别人的plugin里找到了这段代码path.get('specifiers'),但是我完全不知道get里面可以传哪些参数

@xtx1130
Copy link
Owner Author

xtx1130 commented Jul 18, 2018

@scliuyang 所有的ast traversal都差不多的,比如说你这个是拿到引用声明,应该是拿import中的声明,我猜的。。。你可以根据ast树来一点一点比对

@zzuhan
Copy link

zzuhan commented Apr 9, 2019

请问babel-traverse里的api哪里找呢,我在别人的plugin里找到了这段代码path.get('specifiers'),但是我完全不知道get里面可以传哪些参数

https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/plugin-handbook.md#toc-visitors 这个handbook有解释

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants