I'm trying to write a simple babel plugin, but I am having a hard time traversing a matched node with a nested visitor. I would like to find all require
calls in a module that require a certain module and then apply some transformation in the same scope.
To illustrate this with a contrived example I'd like to transform source code like:
const f = require('foo-bar');
const result = f() * 2;
into something like:
const result = 99 * 2; // as i "know" that calling f will always return 99
I was trying to do the following:
module.exports = ({ types: t }) => ({
visitor: {
CallExpression(path) {
if (path.node.callee.name === 'require'
&& path.node.arguments.length === 1
&& t.isStringLiteral(p.node.arguments[0])
&& path.node.arguments[0].value === 'foo-bar'
) {
const localIdentifier = path.parent.id.name;
// if i print here it will show me that it successfully
// found all require calls
p.scope.traverse({
Identifier(subp) {
// this will never run at all
if (subp.name === localIdentifier) {
console.log('MATCH!');
}
}
});
}
}
}
});
Is my approach flawed or is there something I need to do differently from a code perspective?
I know that this question is very old, but this answer could be useful for someone that arrived here by Google.
You could use a traverse inside of another traverse using node.scope.traverse
, for example, if you want to change each CallExpression
only if inside at the body of try
:
module.exports = ({ types: t }) => ({
visitor: {
TryStatement(path) {
const { scope, node } = path
const traversalHandler = {
CallExpression(path) {
path.replaceWith(t.Identifier('foo'))
}
}
scope.traverse(node, traversalHandler, this)
}
}
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With