lodash codemod
Published
Bummed that you can’t treeshake lodash away? Well you can use jscodeshift to run a codemod which will explicitly import all of the lodash functions that you're using.
I've taken the codemod from blog.laurenashpole.com:
export default (fileInfo, api) => {
const j = api.jscodeshift;
const root = j(fileInfo.source);
let specifiers = [];
root
.find(j.ImportDeclaration, isLodashImport)
.forEach((path) => specifiers.push(...path.node.specifiers.map((specifier) => specifier.local.name)))
.remove();
root
.find(j.CallExpression, isLodashExpression)
.forEach((path) => specifiers.push(path.node.callee.property.name))
.replaceWith((path) => replaceExpression(path, j));
if (specifiers.length) {
cleanSpecifiers(specifiers).forEach((specifier) => {
root.find(j.Declaration).at(0).get()
.insertBefore(createImport(j, specifier));
});
}
return root.toSource();
};
function isLodashImport (node) {
return node.source.value.startsWith('lodash');
}
function isLodashExpression (node) {
return node.callee.type === 'MemberExpression' && node.callee.object && node.callee.object.name === '_';
}
function replaceExpression (path, j) {
return j.callExpression(j.identifier(path.node.callee.property.name), path.node.arguments);
}
function cleanSpecifiers (specifiers) {
return specifiers.filter((specifier, i) => {
return specifier !== '_' && specifiers.indexOf(specifier) === i;
});
}
function createImport (j, specifier) {
return j.importDeclaration(
[j.importDefaultSpecifier(j.identifier(specifier))],
j.stringLiteral(`lodash/${specifier}`)
);
}
Name this file lodash-import-codemod.js
and put it in the root of your project (no need to commit it to git, as you're just using this as a tool to refactor some code). Then run
the following to do the code mod on all your .tsx
files:
npx jscodeshift -t ./lodash-import-codemod.js --extensions=tsx --parser=tsx .
and then run this to do it on all your TypeScript files:
npx jscodeshift -t ./lodash-import-codemod.js --extensions=ts --parser=ts .
Just be aware that this could result in some name collisions. For example, if you have a variable in your code
named groupBy
and the file also uses the _.groupBy
method, after running the codemod, you will also import
the groupBy
function from lodash, so you’ll either need to change the name that you use to import it, or just rename
your constant to something else.