我正在构建一个插件,通过调用enterFunction()
在每个现有函数调用之前插入path.insertBefore
。所以我的代码转自:
myFunction();
要:
enterFunction();
myFunction();
问题是,当我插入节点时,Babel再次遍历插入的节点。这是日志记录输出:
'CallExpression','myFunction'
'CallExpression','enterFunction'
如何阻止Babel进入enterFunction
来电表达及其子女?
这是我目前用于Babel插件的代码:
function(babel) {
return {
visitor: {
CallExpression: function(path) {
console.log("CallExpression", path.node.callee.name)
if (path.node.ignore) {
return;
}
path.node.ignore = true
var enterCall = babel.types.callExpression(
babel.types.identifier("enterFunction"), []
)
enterCall.ignore = true;
path.insertBefore(enterCall)
}
}
}
}
答案 0 :(得分:3)
Babel Handbook提及以下部分:
如果您的插件不需要在某种情况下运行,最简单的方法就是尽早写回。
BinaryExpression(path) { if (path.node.operator !== '**') return; }
如果您在顶级路径中进行子遍历,则可以使用2种提供的API方法:
path.skip()跳过遍历当前路径的子节点。 path.stop()完全停止遍历。
outerPath.traverse({ Function(innerPath) { innerPath.skip(); // if checking the children is irrelevant }, ReferencedIdentifier(innerPath, state) { state.iife = true; innerPath.stop(); // if you want to save some state and then stop traversal, or deopt } });
简而言之,使用path.skip()
跳过遍历当前路径的子项。
this snippet using Visitors, CallExpression and skip():
export default function (babel) {
const { types: t } = babel;
return {
name: "ast-transform", // not required
visitor: {
CallExpression(path) {
path.replaceWith(t.blockStatement([
t.expressionStatement(t.yieldExpression(path.node))
]));
path.skip();
}
}
};
}