如何编写一个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

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

参考

相关推荐
轻口味19 分钟前
命名空间与模块化概述
开发语言·前端·javascript
前端小小王1 小时前
React Hooks
前端·javascript·react.js
迷途小码农零零发1 小时前
react中使用ResizeObserver来观察元素的size变化
前端·javascript·react.js
娃哈哈哈哈呀1 小时前
vue中的css深度选择器v-deep 配合!important
前端·css·vue.js
旭东怪2 小时前
EasyPoi 使用$fe:模板语法生成Word动态行
java·前端·word
ekskef_sef3 小时前
32岁前端干了8年,是继续做前端开发,还是转其它工作
前端
sunshine6414 小时前
【CSS】实现tag选中对钩样式
前端·css·css3
真滴book理喻4 小时前
Vue(四)
前端·javascript·vue.js
蜜獾云4 小时前
npm淘宝镜像
前端·npm·node.js