Skip to content

Instantly share code, notes, and snippets.

@CodingNinja
Created November 6, 2017 18:19
Show Gist options
  • Save CodingNinja/e502c5e76b8a19a51e575cab02fe05da to your computer and use it in GitHub Desktop.
Save CodingNinja/e502c5e76b8a19a51e575cab02fe05da to your computer and use it in GitHub Desktop.
JS Codemode to remove unused imports - https://Retroanalytics.io
module.exports = (file, api, options) => {
const j = api.jscodeshift;
const printOptions = options.printOptions || { quote: "single" };
const root = j(file.source);
const filterAndTransformRequires = path => {
const specifiers = path.value.specifiers;
const parentScope = j(path).closestScope();
return (
specifiers.filter(importPath => {
const varName = importPath.local.name;
const requireName = importPath.imported
? importPath.imported.name
: importPath.local.name;
const scopeNode = path.scope.node;
// We need this to make sure the JSX transform can use `React`
if (requireName === "React") {
return false;
}
console.log("parsing require named ", requireName);
// Remove required vars that aren't used.
const identifierUsages = parentScope
.find(j.Identifier, { name: varName })
// Ignore require vars
.filter(identifierPath => identifierPath.parentPath.value !== importPath);
const decoratorUsages = parentScope.find(j.ClassDeclaration).filter(it => {
return (
(it.value.decorators || []).filter(
decorator => decorator.expression.name === varName
).length > 0
);
});
if (!identifierUsages.size() && !decoratorUsages.size()) {
path.value.specifiers = path.value.specifiers.filter(
it => (it === importPath) === false
);
if (path.value.specifiers.length === 0) {
j(path).remove();
}
return true;
}
}).length > 0
);
};
const didTransform =
root
.find(j.ImportDeclaration)
.filter(filterAndTransformRequires)
.size() > 0;
return didTransform ? root.toSource(printOptions) : null;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment