Skip to content

Commit

Permalink
feat: remove unused imports
Browse files Browse the repository at this point in the history
  • Loading branch information
merceyz committed May 27, 2019
1 parent 9ac9b62 commit 8d2ae5f
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 13 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,12 @@ If you want the plugin to match on all functions with a specific name, no matter
| ------------------------ | --------- | ------------- |
| `removeUnnecessaryCalls` | `boolean` | `true` |

By default the plugin will remove unnecessary function calls, if for some reason you need to keep them, you can set this option to false.
By default the plugin will remove unnecessary function calls and if all calls are removed, imports. If you need to keep them, you can set this option to false.

Example of some unnecessary calls

```javascript
import clsx from 'clsx';
const x = clsx('foo', 'bar');
const y = clsx({ classA: foo === 'a', classB: foo !== 'a' });
const z = clsx({
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const visitors = [
combineArguments,
createConditionalExpression,
removeUnnecessaryCalls,
(path, options) => findFunctionNames(path, { ...options, _removeUnusedImports: true }),
];

export default () => ({
Expand Down
42 changes: 30 additions & 12 deletions src/visitors/findFunctionNames.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import * as t from '@babel/types';

export default (path, options) => {
if (options.libraries.length === 0) {
if (
options.libraries.length === 0 ||
(options._removeUnusedImports && !options.removeUnnecessaryCalls)
) {
return;
}

path.node.body.forEach(item => {
path.get('body').forEach(nodePath => {
const item = nodePath.node;

// import x from 'y';
if (t.isImportDeclaration(item)) {
if (
options.libraries.includes(item.source.value) &&
item.specifiers.length === 1 &&
t.isImportDefaultSpecifier(item.specifiers[0])
) {
options.functionNames.push(item.specifiers[0].local.name);
}
if (
t.isImportDeclaration(item) &&
options.libraries.includes(item.source.value) &&
item.specifiers.length === 1 &&
t.isImportDefaultSpecifier(item.specifiers[0])
) {
addOrRemoveNode(nodePath, item.specifiers[0].local.name);
}
// const x = require('y');
else if (t.isVariableDeclaration(item)) {
item.declarations.forEach(dec => {
nodePath.get('declarations').forEach(decPath => {
const dec = decPath.node;
if (
t.isVariableDeclarator(dec) &&
t.isCallExpression(dec.init) &&
Expand All @@ -27,9 +32,22 @@ export default (path, options) => {
t.isLiteral(dec.init.arguments[0]) &&
options.libraries.includes(dec.init.arguments[0].value)
) {
options.functionNames.push(dec.id.name);
addOrRemoveNode(decPath, dec.id.name);
}
});
}

function addOrRemoveNode(itemPath, name) {
if (!options._removeUnusedImports) {
options.functionNames.push(name);
return;
}

// Need to refresh references
itemPath.scope.crawl();
if (!itemPath.scope.getBinding(name).referenced) {
itemPath.remove();
}
}
});
};
5 changes: 5 additions & 0 deletions test/fixtures/find-function-names/unused-import/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import clsx from 'clsx';
const cn = require('classnames');

const x = clsx('foo');
const y = cn('bar');
3 changes: 3 additions & 0 deletions test/fixtures/find-function-names/unused-import/options.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"removeUnnecessaryCalls": true
}
2 changes: 2 additions & 0 deletions test/fixtures/find-function-names/unused-import/output.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const x = 'foo';
const y = 'bar';

0 comments on commit 8d2ae5f

Please sign in to comment.