# 编写一个babel插件
Babel的原理,简单点说: Babel解析成AST,然后插件更改AST,最后由Babel输出代码(解析->转换->生成,parse->transform->generate)。
Babel的插件模块需要暴露一个function,function内返回visitor:
module.export = function(babel){
return {
visitor: { }
}
}
visitor是对各类型的AST节点做处理的地方,那么我们怎么知道Babel生成了的AST有哪些节点呢?
很简单,你可以把Babel转换的结果打印出来,或者这里有传送门: AST explorer (opens new window)
下面是一个实例,可以将x = 1 +2 +3,转成 x = 6:
var babel = require('@babel/core');
var t = require('@babel/types');
const visitor = {
BinaryExpression(path) {
const node = path.node;
let result;
// 判断表达式两边,是否都是数字
if (t.isNumericLiteral(node.left) && t.isNumericLiteral(node.right)) {
// 根据不同的操作符作运算
switch (node.operator) {
case "+":
result = node.left.value + node.right.value;
break
case "-":
result = node.left.value - node.right.value;
break;
case "*":
result = node.left.value * node.right.value;
break;
case "/":
result = node.left.value / node.right.value;
break;
case "**":
let i = node.right.value;
while (--i) {
result = result || node.left.value;
result = result * node.left.value;
}
break;
default:
}
}
// 如果上面的运算有结果的话
if (result !== undefined) {
// 把表达式节点替换成number字面量
path.replaceWith(t.numericLiteral(result));
let parentPath = path.parentPath;
// 向上遍历父级节点
parentPath && visitor.BinaryExpression.call(this, parentPath);
}
}
};
module.exports = function (babel) {
return {
visitor
};
}
测试一下:
const babel = require("@babel/core");
const result = babel.transform("const result = 1 + 2 + 1 + 1;",{
plugins:[
require("./custom_plugin.js")
]
});
console.log(result.code); // const result = 5;
参考资料:https://juejin.im/post/6844903566809759758