ast exployer
@babel/traverse
是一款用来自动遍历抽象语法树的工具,它会访问树中的所有节点,在进入每个节点时触发 enter 钩子函数,退出每个节点时触发 exit 钩子函数。开发者可在钩子函数中对 AST 进行修改。
@babel/types
@babel/types 是一款作用于 AST 的类 lodash 库,其封装了大量与 AST 有关的方法,大大降低了转换 AST 的成本。@babel/types 的功能主要有两种:一方面可以用它验证 AST 节点的类型,例如使用 isClassMethod 或 assertClassMethod 方法可以判断 AST 节点是否为 class 中的一个 method;另一方面可以用它构建 AST 节点,例如调用 classMethod 方法,可生成一个新的 classMethod 类型 AST 节点 。
path
AST中有很多节点,每个节点可能有不同的属性,并且节点之间可能存在关联。path是个对象,它代表了两个节点之间的关联。你可以在path上访问到节点的属性,也可以通过path来访问到关联的节点(比如父节点、兄弟节点等) state:代表了插件的状态,你可以通过state来访问插件的配置项。
state
代表了插件的状态,你可以通过state来访问插件的配置项。
下面是 remove console插件,支持通过注释保留需要的注释
"use strict";
const isArray = require('../lib/isArray')
module.exports = function({ types: t }) {
return {
name: "transform-remove-console-enhance",
visitor: {
CallExpression(path, { opts }) {
const calleePath = path.get("callee")
// 保留 options中配置的console
if (opts && isArray(opts.exclude)) {
const hasTarget = opts.exclude.some(type => {
return calleePath.matchesPattern("console." + type)
})
if (hasTarget) return
}
// 保留 通过注释 //remove--console-disable 保留的console
const leadingComments = path.parent.leadingComments || []
const removeConsoleDisable = leadingComments.find(item => item.value.trim()=== 'remove--console-disable' )
if(removeConsoleDisable) {
return
}
// 移除console
if (calleePath.matchesPattern("console", true)) {
path.remove()
}
},
},
};
};