Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: [no-duplicate-imports] ignore namespace imports (fixes #12758) #12935

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 13 additions & 1 deletion docs/rules/no-duplicate-imports.md
Expand Up @@ -12,7 +12,9 @@ import { find } from 'module';

## Rule Details

This rule requires that all imports from a single module exists in a single `import` statement.
an import that can be merged with another is a duplicate of that other

This rule requires that all imports from a single module that can be merged exists in a single `import` statement.

Example of **incorrect** code for this rule:

Expand All @@ -33,6 +35,16 @@ import { merge, find } from 'module';
import something from 'another-module';
```

Example of **correct** code for this rule (namespace imports can't be merged):

```js
/*eslint no-duplicate-imports: "error"*/

import * as Namespace from 'module';
import { merge } from 'module';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This behaviour doesn't fit the heuristic:

an import that can be merged with another is a duplicate of that other.

Namespace imports and named imports can be merged with default imports.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your feedback @G-Rath
I'll rework on it to fit this scenario

import something from 'another-module';
```

## Options

This rule takes one optional argument, an object with a single key, `includeExports` which is a `boolean`. It defaults to `false`.
Expand Down
16 changes: 15 additions & 1 deletion lib/rules/no-duplicate-imports.js
Expand Up @@ -21,6 +21,20 @@ function getValue(node) {
return "";
}

/**
* Checks if the import's type is a namespace import.
* @param {ASTNode} node A node to get.
*
* @returns {boolean} Whether or not the import's type is "ImportNamespaceSpecifier".
*/
function isNamespaceImport(node) {
return (
node.specifiers &&
node.specifiers[0] &&
node.specifiers[0].type === "ImportNamespaceSpecifier"
);
}

/**
* Checks if the name of the import or export exists in the given array, and reports if so.
* @param {RuleContext} context The ESLint rule context object.
Expand Down Expand Up @@ -61,7 +75,7 @@ function handleImports(context, includeExports, importsInFile, exportsInFile) {
return function(node) {
const value = getValue(node);

if (value) {
if (value && !isNamespaceImport(node)) {
checkAndReport(context, node, value, importsInFile, "import");

if (includeExports) {
Expand Down
1 change: 1 addition & 0 deletions tests/lib/rules/no-duplicate-imports.js
Expand Up @@ -20,6 +20,7 @@ const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6, sourceType:

ruleTester.run("no-duplicate-imports", rule, {
valid: [
"import * as Lodash from \"lodash-es\";import { merge } from \"lodash-es\";;",
"import os from \"os\";\nimport fs from \"fs\";",
"import { merge } from \"lodash-es\";",
"import _, { merge } from \"lodash-es\";",
Expand Down