babel插件入门知识可以参看 Babel 插件手册,里面可以让你了解一些基本关于babel和AST的一些基本知识。本文主要介绍一些常见的简单babel插件。

Babel运行阶段

Babel运行主要分为三个阶段,解析,转换,生成。解析就是读入源码,通过词法分析和语法分析,生成AST;转换就是通过babel插件,对AST进行修改,得到新的AST;生成就是将AST解析成新的代码。

入门插件

现在编写一个babel插件,让let bad = true;let dead = true;中的bad变成goods,dead变成alive。

首先安装项目依赖

然后我们在node_modules目录下新建一个babel-plugin-abcd目录,里面新建一个index.js,内容如下:

上面的步骤就是写了一个babel插件,现在我们需要在项目下新建一个.babelrc,并配置刚才那个插件:

abcd代表的就是babel-plugin-abcd这个插件,就是我们刚才创建的,然后目录下的index.js里面就是插件的内容了。{"bad": "good","dead": "alive"}就是传给Identifier(path, state){}中的state的。

现在我们在项目下新建一个index.js,放入我们需要转换的代码:

目录结构如下(node_modules下的无关目录这里没有展示,正常有很多目录):

运行npx babel index.js,那么我们就会得到结果:

我们可以发现,源文件中的bad变成了goods,dead变成了alive,也就是我们的插件起了效果。现在我们来看看这个插件的原理。

我们可以去 AST explorer里面将源文件转成AST看看,下面是部分截图:

AST中,所有的东西都有一个”类型“,例如这里的bad和dead就属于"Identifier",true部分属于“Literal”。babel插件的原理就是利用Visitor去访问特定的类型,然后匹配,这里就是匹配Identifier这种类型。

这个插件的主要原理就是,看Identifier类型中的值是否有在state({'bad':'goods','dead':'alive'})的key中,如果有,那么就替换成state的value。

上面详细讲解了如何安装,运行一个babel插件,后面将更加主要讲解插件内容部分。

简单计算插件

分析let a=1+2+3;并计算得到正确的结果。

我们只需要把上面babel-plugin-abcd中index.js的内容替换如下:

然后外层的index.js,也就是我们要翻译的源码替换成如下:

然后运行npx babel index.js,可以得到结果:

我们用上面的网站看let a=1+2+3;的结构:

我们可以发现AST中对于运算符的表示是用BinaryExpression,然后有left,operation,right。对于1+2+3这种,超过两个的,就会把它分开,1+2为一个BinaryExpression,其中1为left,2为right。再往上,1+2的整体BinaryExpression作为left,3作为right。

因此我们首先用visitor去访问BinaryExpression,然后去匹配两边都是数字的情况,利用operation计算出结果。最关键的一步,我们要将去验证当前的父节点是否也是一个满足条件的BinaryExpression,因此要将path.parentPath带入循环计算。

简单import拆分插件

import {flattenDeep, chunk} from 'lodash'将会下载整个lodash包,想将它拆分成两个:import flattenDeep from 'lodash/flattenDeep';import chunk from 'lodash/chunk';这样只会下载两个相关的包。

同样的,我们将babel-plugin-abcd中index.js的内容替换如下:

源码index.js变成:

通过配置.babelrc:

执行npx babel index.js,可以得到结果:

我们看import {falttenDeep,chunk} from 'lodash'的AST结构:

import下有一个specifiers,就是import前面部分,这里也就是falttenDep,chunk。然后判断是否是默认,默认就是只有一个那种。然后如果是多个就遍历并将source拼在前面。

替换process.env.NODE_ENV

根据当前的环境替换process.env.NODE_ENV这个变量。

来规矩,先替换babel-plugin-abcd中index.js的内容:

再替换源码index.js中的内容:

执行npx babel index.js,得到结果:

我们把process.env.NODE_ENV替换成了当前环境的process.env.NODE_ENV(当前是undefined)。

我们现在看看AST的结构:

在AST中,对于a.b这种结构是MemberExpression,像这里process.env.NODE_ENV就是一个MemberExpression的嵌套。matchesPattern,toComputedKey这些api都很难查到,因此这玩意要多看别人写的才会用。

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

提交
还可以输入500个字