如何编写一个babel插件?babel插件万能模板

前言

想要提高工作效率,想要更多的时间去摸鱼,那么babel插件绝对是一大利器。babel的强大之处就像《风云》中步惊云手中的绝世好剑一样,快如闪电,所向披靡,敌人无不望风而逃

但是有些同学感觉babel插件好难呀,经常忘记怎么编写。这就像看着别人手里的绝世好剑,自己只能流口水🤤

所以我们用此篇文章来讲一下babel插件的模板,让大家只用套用模板就可以了,方便大家使用和记忆

搭建最小babel运行环境

首先我们应该搭建babel的最小运行环境,方便我们运行和调试

新建目录

js 复制代码
mkdir customPlugin && cd customPlugin

然后初始化pacage.json

js 复制代码
npm init -y

安装两个必须的包

@babel/core : Babel核心包
@babel/cli : 是 Babel 生态系统中的一个命令行工具,它提供了一个简单易用的接口,让你可以通过命令行来使用 Babel 进行代码转换。

js 复制代码
npm i @babel/core @babel/cli -D

再在customPlugin目录下创建.babelrc文件

.babelrc文件是用来干什么的呢? 是 Babel 的配置文件,用于指定 Babel 在代码转换过程中所使用的插件(Plugin)和预设(Presets),以及其他相关选项。

js 复制代码
{
  "plugins": ["./pluginDemo.js"]
}

plugin中引用我们的插件,插件内容稍后我们会写

package.json中添加编译命令, 用于编译src下面的文件到dist目录

js 复制代码
 "scripts": {
    "build": "babel src -d dist"
  },

插件的基本结构

插件本身是一个函数,函数的入参是 babel 对象,从中我们可以拿到 babel 的所有成员,最常用的是 types 对象,它是由 babel-types 包提供的一个工具对象,用于构造、验证以及变换 AST 节点。对编写处理 AST 逻辑非常有用,编写插件会频繁的使用这个对象。

如下是一个插件的最基本的结构,返回一个对象,对象中有定义了一个访问者(visitor)。

js 复制代码
module.exports = (babel) => {
  return {
    visitor: {
        ...
    }
  }
}

简单实战

接下来我们开始实战演示

我们把

js 复制代码
console.log(1);

中的值1改为2

学习使用AST explorer

先来上网站 https://astexplorer.net/ 网站的意思就是AST 探索者的意思,比较好记

然后看一下下面这张图,看一下astexplorer网站如何使用

然后上面这些选项都不怎么使用,除了type其他都可以暂时隐藏掉

此时在需要解析的代码中放入我们要解析的代码

编写插件几个常用的概念

  1. babel:插件的入参,可以从中拿到 types 对象,操作 AST 节点,由于 types 对象太常用了,babel 大部分情况下写做 {types:t}。
  2. visitor:插件核心对象,其中定义了插件生效的节点类型,以及生效方式。
  3. path:path 对象代表了当前节点的路径,通过 path 节点可以访获得当前的 node 对象,以及和该路径相关的对象,比如父节点、兄弟节点等。path 对象上还包含一些操作路径的方法等。

如何访问node?

我们写babel插件其实就是对node的增删改。

我们知道AST是由一个个node组成的,那么这些node是如何区分的呢?我们如何访问这些node呢?

第一个问题: node是通过type来进行区分的,所以第二个问题也就好回答了:node是通过type来访问的。

那么问题来了ast为什么要这样设计呢?

因为我们的babel插件是要解决某一类有共性的问题的,而且一个插件一般只解决一种问题,所以这也是为什么设计使用type来进行区分和访问的原因

那么node的值都有哪些呢,这个我们可以去astExplorer网站上查看,一目了然

比如typeNumericLiteral的这个值,他的node包含如下

编写插件

我们只需要把node中的value值修改一下就可以了

然后我们把在网站中写的插件内容,复制到我们customPlugin程序中的插件中,因为customPlugin插件中只支持commonjs modules模式,所以我们复制的时候需要转化一下导出方法

./pluginDemo.js

js 复制代码
module.exports = (babel) => {
  const { types: t } = babel;

  return {
    name: "ast-transform", // not required
    visitor: {
      NumericLiteral(path) {
        path.node.value = 2;
      }
    }
  };
}

然后我们运行编译命令

js 复制代码
npm run build

最后查看一下dist中的输出内容

./dist/test.js

js 复制代码
console.log(2);

写到这里,肯定有同学要骂了,我看了你10分钟文章,你就实现了个这?什么垃圾废文!

首先我这篇文章主要是讲babel插件的模板的,实战我们会在后面的文章中陆续更新

总结

  1. 首先我们学习了babel插件的最小运行环境,方便我们测试和调试我们的插件
  2. 讲了babel插件的模板的格式,Babel 插件通过定义访问者(visitor)对象,定义了需要处理的节点类型以及执行的操作。
  3. 讲解了如何使用AST explorer网站,如何使用这个网站帮助我们快速查看node节点,以及快速编写,调试babel插件
  4. 了解了编写插件的几个常用概念babel,type,path

后面还简单的写了一个插件,虽然写的太简单了,但是后面我们会循序渐进,写更多的实战内容

参考

相关推荐
编程零零七2 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
(⊙o⊙)~哦4 小时前
JavaScript substring() 方法
前端
无心使然云中漫步5 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者5 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_5 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js
麒麟而非淇淋6 小时前
AJAX 入门 day1
前端·javascript·ajax
2401_858120536 小时前
深入理解MATLAB中的事件处理机制
前端·javascript·matlab
阿树梢6 小时前
【Vue】VueRouter路由
前端·javascript·vue.js
随笔写8 小时前
vue使用关于speak-tss插件的详细介绍
前端·javascript·vue.js
史努比.8 小时前
redis群集三种模式:主从复制、哨兵、集群
前端·bootstrap·html