diff --git a/CHANGELOG.md b/CHANGELOG.md index bb38ab5ab7..eab3e500b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel - [`extensions`]/[`no-cycle`]/[`no-extraneous-dependencies`]: Correct module real path resolution ([#1696], thanks [@paztis]) - [`no-named-default`]: ignore Flow import type and typeof ([#1983], thanks [@christianvuerings]) - [`no-extraneous-dependencies`]: Exclude flow `typeof` imports ([#1534], thanks [@devongovett]) +- [`no-unused-modules`]: Support destructuring assignment for `export`. ([#1997], thanks [@s-h-a-d-o-w]) ### Changed - [Generic Import Callback] Make callback for all imports once in rules ([#1237], thanks [@ljqx]) @@ -759,6 +760,7 @@ for info on changes for earlier releases. [`memo-parser`]: ./memo-parser/README.md +[#1997]: https://github.com/benmosher/eslint-plugin-import/pull/1997 [#1983]: https://github.com/benmosher/eslint-plugin-import/pull/1983 [#1974]: https://github.com/benmosher/eslint-plugin-import/pull/1974 [#1958]: https://github.com/benmosher/eslint-plugin-import/pull/1958 @@ -1340,4 +1342,5 @@ for info on changes for earlier releases. [@panrafal]: https://github.com/panrafal [@ttmarek]: https://github.com/ttmarek [@christianvuerings]: https://github.com/christianvuerings -[@devongovett]: https://github.com/devongovett \ No newline at end of file +[@devongovett]: https://github.com/devongovett +[@s-h-a-d-o-w]: https://github.com/s-h-a-d-o-w diff --git a/src/rules/no-unused-modules.js b/src/rules/no-unused-modules.js index dfea6de6df..42567b1ed6 100644 --- a/src/rules/no-unused-modules.js +++ b/src/rules/no-unused-modules.js @@ -4,7 +4,7 @@ * @author René Fermann */ -import Exports from '../ExportMap'; +import Exports, { recursivePatternCapture } from '../ExportMap'; import { getFileExtensions } from 'eslint-module-utils/ignore'; import resolve from 'eslint-module-utils/resolve'; import docsUrl from '../docsUrl'; @@ -63,6 +63,8 @@ const IMPORT_DEFAULT_SPECIFIER = 'ImportDefaultSpecifier'; const VARIABLE_DECLARATION = 'VariableDeclaration'; const FUNCTION_DECLARATION = 'FunctionDeclaration'; const CLASS_DECLARATION = 'ClassDeclaration'; +const IDENTIFIER = 'Identifier'; +const OBJECT_PATTERN = 'ObjectPattern'; const TS_INTERFACE_DECLARATION = 'TSInterfaceDeclaration'; const TS_TYPE_ALIAS_DECLARATION = 'TSTypeAliasDeclaration'; const TS_ENUM_DECLARATION = 'TSEnumDeclaration'; @@ -80,7 +82,15 @@ function forEachDeclarationIdentifier(declaration, cb) { cb(declaration.id.name); } else if (declaration.type === VARIABLE_DECLARATION) { declaration.declarations.forEach(({ id }) => { - cb(id.name); + if(id.type === OBJECT_PATTERN) { + recursivePatternCapture(id, (pattern) => { + if (pattern.type === IDENTIFIER) { + cb(pattern.name); + } + }); + } else { + cb(id.name); + } }); } } diff --git a/tests/files/no-unused-modules/destructuring-a.js b/tests/files/no-unused-modules/destructuring-a.js new file mode 100644 index 0000000000..1da867deff --- /dev/null +++ b/tests/files/no-unused-modules/destructuring-a.js @@ -0,0 +1 @@ +import {a, b} from "./destructuring-b"; diff --git a/tests/files/no-unused-modules/destructuring-b.js b/tests/files/no-unused-modules/destructuring-b.js new file mode 100644 index 0000000000..b477a5b6f2 --- /dev/null +++ b/tests/files/no-unused-modules/destructuring-b.js @@ -0,0 +1,2 @@ +const obj = {a: 1, dummy: {b: 2}}; +export const {a, dummy: {b}} = obj; diff --git a/tests/src/rules/no-unused-modules.js b/tests/src/rules/no-unused-modules.js index 5906c9afbf..3ace4a3287 100644 --- a/tests/src/rules/no-unused-modules.js +++ b/tests/src/rules/no-unused-modules.js @@ -965,3 +965,23 @@ describe('ignore flow types', () => { invalid: [], }); }); + +describe('support (nested) destructuring assignment', () => { + ruleTester.run('no-unused-modules', rule, { + valid: [ + test({ + options: unusedExportsOptions, + code: 'import {a, b} from "./destructuring-b";', + parser: require.resolve('babel-eslint'), + filename: testFilePath('./no-unused-modules/destructuring-a.js'), + }), + test({ + options: unusedExportsOptions, + code: 'const obj = {a: 1, dummy: {b: 2}}; export const {a, dummy: {b}} = obj;', + parser: require.resolve('babel-eslint'), + filename: testFilePath('./no-unused-modules/destructuring-b.js'), + }), + ], + invalid: [], + }); +});