Skip to content

Instantly share code, notes, and snippets.

@nemtsov
Last active December 20, 2022 04:02
Show Gist options
  • Save nemtsov/8f5a6a78268839abaca78ad1fbe8368c to your computer and use it in GitHub Desktop.
Save nemtsov/8f5a6a78268839abaca78ad1fbe8368c to your computer and use it in GitHub Desktop.
A jscodeshift to remove unused imports
module.exports = (file, api, options) => {
const j = api.jscodeshift;
const printOptions = options.printOptions || {quote: 'single'};
const root = j(file.source);
const requires = {};
const filterAndTransformRequires = path => {
const varName = path.value.local.name;
const scopeNode = path.parentPath.scope.node;
const importPath = path.parentPath.parentPath;
// Check if we already have a require for this, if we do just use
// that one.
if (
requires[varName] &&
requires[varName].scopeNode === scopeNode
) {
j(importPath).remove();
return true;
}
// We need this to make sure the JSX transform can use `React`
if (varName === 'React') {
return false;
}
// Remove required vars that aren't used.
const usages = j(path)
.closestScope()
.find(j.Identifier, {name: varName})
.filter(p => p.value !== path.value.local)
.filter(p => !(p.parentPath.value.type === 'Property' && p.name === 'key'))
.filter(p => p.name !== 'property')
if (!usages.size()) {
j(importPath).remove();
return true;
}
requires[varName] = {scopeNode, varName};
};
const didTransform = root
.find(j.ImportDefaultSpecifier)
.filter(filterAndTransformRequires)
.size() > 0;
return didTransform ? root.toSource(printOptions) : null;
};
@angelyordanov
Copy link

angelyordanov commented Apr 30, 2018

@john-hadron great work!

FYI, the transformation does not retain first line comments, if one needs that check this out https://github.com/facebook/jscodeshift/blob/master/recipes/retain-first-comment.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment