jscodeshift snippet - printing a whole MemberExpression
I’ve been writing codemods using jscodeshift. I find that while the main goal of codemods is to refactor code, I often have to print some output either for debugging or making sure I’m on the right path.
One of the things I had to do recently was to print a whole MemberExpression based on a module name I was looking for. For example, consider the following code snippet.
myUtils.doAction();
// ...
myUtils.subModule.doAction();
// ...
myUtils[selectedSubModule][selectedAction]();
// ...
myUtils[selectedSubModule][SOME_NAMESPACE.CONSTANT_NAME];
From the code above, I want to be able to print, in full, all the MemberExpressions related to myUtils. Below is the desired output.
myUtils.doAction
myUtils.subModule.doAction
myUtils[selectedSubModule][selectedAction]
myUtils[selectedSubModule][SOME_NAMESPACE.CONSTANT_NAME]
This turns out to be a very simple thing to do. We just have to do the following.
- Locate a
MemberExpressionthat has anIdentifiernamedmyUtilsas theobject. -
If the
MemberExpressionfrom (1) is part of anotherMemberExpression, find the rootMemberExpression.(For example, the
myUtils.subModule, though aMemberExpression, is still theobjectinmyUtils.subModule.doAction.) - Print the root
MemberExpressionusingtoSource().
We should end up with something like below.
// print-root-member-expressions.js
export default function printRootMemberExpressions(file, api) {
const j = api.jscodeshift;
const getRootMemberExpressionPath = p => {
if (j.MemberExpression.check(p.parent.node)) {
return p.parent;
}
return p;
};
const getRootMemberExpressionSource = p => {
const rootMemberExpressionPath = getRootMemberExpressionPath(p);
return j(rootMemberExpressionPath).toSource();
};
j(file.source)
.find(j.MemberExpression, {
object: {
name: "myUtils"
}
})
.forEach(path => {
console.log(getRootMemberExpressionSource(path));
});
}
See it in action on AST Explorer. Check the console log.