标签归档:Babel

使用Babel的AST功能,来智能分析处理源码

在重构时,往往会遇到一些不合理的代码需要被批量替换。这种需求一般的全文替换是可以的,但是如果要根据文件名、变量名动态的进行智能替换,而且被替换的代码块格式不一,这时还有什么方式?正则是一个办法,但是还有没有别的方法可以尝试呢?

有的!之前在重构某些项目时,有许多属性需要批量替换,但是我希望能加入一些逻辑判断、和一些其他变量的状态获取。在查询许多资料之后,除了正则+脚本,还有Babel能帮我解决这个问题

Babel

我们一般前端开发是用Babel来转换新语法,然而它的API也能让你来自定义转换源码。这个API就是将你的源码转换成AST(Abstract Syntax Tree)抽象语法树。能实现AST转换的其实不止Babel一家,在Babel之前还有Esprima等。只不过我们大部分用的都是Babel,为了和.babelrc语法一致,所以我更推荐使用Babel来进行AST转换

AST(抽象语法树)

维基百科:在计算机科学中,抽象语法树(AST),或简称语法树,是用编程语言编写的源代码的抽象语法结构的树表示。树的每个节点表示源代码中出现的一个构造。

例如:Program -[Code1 ,Code2],同时Code1又包含
VariableDeclaration(变量定义)、CallExpression(函数定义)等,在函数内又有许多语法在其中。这么一看,是不是很像一颗树呢?有树层次、节点关系等^_^。然后实践的过程中,只要我们增减其中的节点,或者是修改节点的属性值,再将AST转换成源码,这样就可以很轻松的达到“智能转换代码”的功能了!

学习资料

官方手册:
https://github.com/jamiebuilds/babel-handbook/blob/master/translations/zh-Hans/README.md

AST Explorer(在线解析语法AST):https://astexplorer.net/

维基百科定义:https://en.wikipedia.org/wiki/Abstract_syntax_tree

具体实践

只是给出几个定义感觉不直观,让我们直接上手AST吧!相信AST能让你今后的重构或者代码调整,能够如虎添翼,这并不是奇巧淫技,而是真正提升你效率的一个利器!下面列出一个Github仓库,这是我实际用AST进行转换的例子:

Github仓库:
https://github.com/tun100/ReplaceContentByBabelAST

实际需求:

替换前文件
替换后文件

我们现在需要拿到{form.getFieldDecorator(‘myname’, {})}的“myname”字符串,这是定义form的prop值的。然后对Form.Item的label需要改为传递<ErrorTooltip>

一般正则是可以使用,但是AST也可以帮助你实现这个功能,让我们打开index.js这个文件

index.js文件概览

在进行AST处理时,我们会通过core.parse得到一颗树。那么我们怎么去遍历,去拿到这个值呢?这时候会用到traverse这个函数,通过这个函数,它可以帮你遍历所有的节点,如果你判断当前的tree node符合你的条件,那么就立刻进行处理,如下图:

具体解析转换代码

在语法树中,每个节点都有自己的定义,比如:节点是什么语法,带有什么属性,自身是什么值,在自己语法下还有没有更深层次的子树存在。那么这些节点具体有哪些属性,我应该怎么知道呢?

其实有一个很快捷的方式,就是把你的代码拷贝到 https://astexplorer.net (如果不放心可以clone它的仓库,在本地运行,不过我检查过不会有隐私问题),然后在菜单顶部选择babylon7,这样右侧就会有你想要的各个节点的属性和之间的关系

AST-Explorer具体使用