本篇只讲babel插件的实现, js AST部分后面有时间再写

首先当然是新建一个文件夹啦, 名字我们叫 bar 好了

开始做准备工作:

安装babel, 略…

然后在根文件内新建一个.babelrc文件, 如果我们的插件名叫console-clear的话, .babelrc文件内容为:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"plugins": [
[
"./console-clear",
{
"ignore": [
"time",
"timeEnd"
]
}
]
]
}

由于我们把插件放在本地, 没有发布到npm上, 所以是带相对路径的
ignore参数代表会被忽略的console, 比如以上会忽略console.time, console.timeEnd

新建一个待编译的js文件, 比如index.js, 内容如下:

1
2
3
4
console.log('foo')
console.time('bar')
console.error('network error')
console.timeEnd('bar')

我们的插件叫console-clear, 所以就创建一个console-clear.js文件(创建一个文件夹里面再创建index.js也行), 内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = function ({ types: t }) {
return {
visitor: {
ExpressionStatement(path, { opts }) {
// 拿到object与property, 比如console.log语句的object name为console, property name为log
const { object, property } = path.node.expression.callee
// 如果表达式语句的object name不为console, 不作处理
if (object.name !== 'console') return
// 判断property name是不是插件配置里被忽略的
const isIgnore = (opts.ignore || []).find(ele => ele === property.name)
// 如果不是, 删除此条语句
if (!isIgnore) path.remove()
}
}
}
}

命令行执行 babel index.js 发现输出就只有以下两条了:

1
2
console.time('bar')
console.timeEnd('bar')

至此, 一个清除console的babel插件就写好啦

如果你看的一脸懵b, 比如ExpressionStatement函数是干嘛的等等, 看下文档吧

插件文档这里

项目代码在这里