本文将以把es6的语法let
改成var
为例,讲述如何编写一个babel插件。其中涉及到一些babel的基本知识,babel的工做流程,语法抽象树等。前端
关于babel 官网作了以下解释:node
Babel 是一个工具链,主要用于在旧的浏览器或环境中将 ECMAScript 2015+ 代码转换为向后兼容版本的 JavaScript 代码react
相信你们在开发中或多或少的都使用过bable
对代码进行编译。在babel配置文件.babelrc
中最主要就是对presets
和Plugins
的配置。其中presets
通俗来讲就是某一类的插件转译集合,好比说babel官方封装好的@babel/preset-react
中就包括如下插件@babel/plugin-syntax-jsx
,@babel/plugin-transform-react-jsx
,@babel/plugin-transform-react-display-name
。而Plugins相对来讲功能比较单一,好比transform-es2015-arrow-functions
,这个插件只负责转译es2015新增的箭头函数。es6
因此在咱们的平常开发中也能够根据本身的需求开发bebal插件,从而提升开发效率。编程
Babel转码的过程分三个阶段:解析(parse)、转换(transform)、生成(generate)。下面这张图能够很好的说明babel的工做过程浏览器
其中,解析、生成阶段由Babel核心完成,而转换阶段,则由Babel插件完成,这也是本文的重点。bash
在计算机科学中,抽象语法树(Abstract Syntax Tree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每一个节点都表示源代码中的一种结构。之因此说语法是“抽象”的,是由于这里的语法并不会表示出真实语法中出现的每一个细节。微信
开发一个babel插件必定要对AST有所了解,上面是维基百科对抽象语法树的解释babel
举个例子:编程语言
var a = 1;
复制代码
转换成的AST结构为:
这里是能够实时查看代码ast结构的网站astexplorer.net/,有助于更好的了解ast以及编写babel插件
可用于从命令行编译文件
"@babel/cli": "^7.1.5",
"@babel/core": "^7.1.6",
复制代码
新建一个babel-letToVar.js
文件,代码以下
function letToVar(babel) {
const { types: t, template } = babel;
return visitor = { };
}
module.exports = letToVar;
复制代码
咱们能够在letToVar
这个方法中接收babel对象。
visitor 属性是这个插件的主要访问者,且其中的每一个函数接收2个参数:path 和 stat。访问者是一个用于 AST 遍历的跨语言的模式。简单的说它们就是一个对象,定义了用于在一个树状结构中获取具体节点的方法。
咱们的需求是将let
转换成var
,那么咱们须要添加一个VariableDeclaration
访问者方法
function letToVar(babel) {
const { types: t, template } = babel;
const visitor = {
VariableDeclaration(path) {
if(path.get('kind').node!='let')return;
path.node.kind='var';
}
};
return {visitor};
}
module.exports = letToVar;
复制代码
咱们能够经过path.get()方法获取到kind,并判断他是否是为let,若是是就将其改成var,以实现咱们的需求。
下面咱们能够运行看一下效果是否符合咱们的预期。
.eslintrc
文件咱们能够直接在此文件中引入咱们的babel-letToVar.js文件
{
"plugins": [ "./babel-letToVar.js"]
}
复制代码
咱们能够在终端运行下面命令,将inedx.js文件编译后输出到dest.js文件中。
$ babel index.js --out-file dest.js
复制代码
下图是运行效果,能够看到已经实现了咱们的需求。
本文演示的只是一个简单的babel插件的开发,咱们在转换的过程当中拿到代码的AST结构后,就能够为所欲为的对代码进行增长、删除、修改。咱们还能够经过编写babel插件实现更多的功能,好比删除代码中全部console.log
等。
卓月,铜板街前端开发工程师,2018年3月加入团队,目前主要负责自营端 H5 项目开发。