babel 编写plugin(三)----原理

AST 抽象语法树

抽象语法树就是通过JavaScript Parser将代码转化成为一颗抽象语法树,这棵树定义了代码的结构。然后通过操纵这棵树的增删改查实现对代码的分析,变更,优化。

一般业界有现成的方法来进行词法和语法的分析,比如:

  1. babel/core: 提供 transform、parse方法
  2. babel/parse: babel解析器
  3. babel/traverse: 对AST遍历,维护了整棵树的状态
  4. babel/generator: 代码的生成,通过AST生成新的代码

工作流程

Parse 解析阶段: 将js代码进行词法分析生成tokens,再进行语法分析生成AST树
Transform 转化阶段:遍历AST树,把js语法转化成浏览器兼容的语法,得到ES5 AST树
Generator 生成阶段:将生成的新的AST进行深度遍历生成新的代码,生成ES5代码

AST遍历(深度遍历)

遍历基于一种访问者模式(Visitor), 不同的访问者会执行不同的操作得到不同的结果
Visitor 上挂载了每个节点命名的方法,当进行AST遍历时触发匹配的方法名执行对于方法进行操作

实战开发(ES6箭头函数转化插件)

babel插件其实就是个对象,里面都有一个属性visitor,visitor对象上会有很多方法,每个方法都是基于节点的名称(比如箭头函数:ArrowFunctionExpress,当执行到箭头函数的属性时,就会命中该方法)去命名的。
关于节点的名称或者类型 babel/types 都有覆盖,我们可以通过查询babel/types查阅对应的节点类型

let { transform, parse } = require('@babel/core');
let arrowFunctionPlugin = require('./arrowFunctionPlugin');
let souceCode = `const func = () => {console.log(this)}`;
let targetCode = transform(souceCode, {
	plugins: []
})

//arroeFunctionPlugin.js
//命中箭头函数,进入ArrowFunctionExpress方法
//transform已经把代码转化为AST,可以对比转化前和转化后的AST,分析要处理什么步骤
//1.output 中将节点类型替换成FunctionDeclaration
//2.在箭头函数通作用域内额外添加了变量声明,const _this = this;
//3.output中针对箭头函数的body,调用表达式声明ExpressionStatement时,传入的arguments从ThisExpression更换成了Identifier。
const arrorFunctionPlugin = () => {
	return {
		visitor: {
			ArrowFunctionExpress (nodePath) {
				  const node = path.node;
				  node.type = 'FunctionDeclaration';
				  
			}
		}
	}
}
module.exports = {
	arrorFunctionPlugin
}

总结

  1. 通过源代码和转义后代码进行AST节点对比,找出对应的区别节点,尽量复用之前的节点
  2. 存在增删改的节点,通过nodePath的Api调用对应的方法进行AST处理
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值