Skip to content

Commit f84d457

Browse files
sveyretljharb
authored andcommitted
no-duplicates: allow duplicate if one is namespace and other not
It is a syntax error to put both namespace and non namespace import on the same line, so allow it. Fixes #1538
1 parent 7e71b50 commit f84d457

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

Diff for: CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
99
- [`import/external-module-folders` setting] now correctly works with directories containing modules symlinked from `node_modules` ([#1605], thanks [@skozin])
1010
- [`extensions`]: for invalid code where `name` does not exist, do not crash ([#1613], thanks [@ljharb])
1111
- [`extentions`]: Fix scope regex ([#1611], thanks [@yordis])
12+
- [`no-duplicates`]: allow duplicate imports if one is a namespace and the other not ([#1612], thanks [@sveyret])
1213

1314
### Changed
1415
- [`import/external-module-folders` setting] behavior is more strict now: it will only match complete path segments ([#1605], thanks [@skozin])
@@ -644,6 +645,7 @@ for info on changes for earlier releases.
644645
[`memo-parser`]: ./memo-parser/README.md
645646

646647
[#1613]: https://github.com/benmosher/eslint-plugin-import/issues/1613
648+
[#1612]: https://github.com/benmosher/eslint-plugin-import/pull/1612
647649
[#1611]: https://github.com/benmosher/eslint-plugin-import/pull/1611
648650
[#1605]: https://github.com/benmosher/eslint-plugin-import/pull/1605
649651
[#1589]: https://github.com/benmosher/eslint-plugin-import/issues/1589
@@ -1081,3 +1083,4 @@ for info on changes for earlier releases.
10811083
[@ivo-stefchev]: https://github.com/ivo-stefchev
10821084
[@skozin]: https://github.com/skozin
10831085
[@yordis]: https://github.com/yordis
1086+
[@sveyret]: https://github.com/sveyret

Diff for: src/rules/no-duplicates.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -257,12 +257,14 @@ module.exports = {
257257
}) : defaultResolver
258258

259259
const imported = new Map()
260+
const nsImported = new Map()
260261
const typesImported = new Map()
261262
return {
262263
'ImportDeclaration': function (n) {
263264
// resolved path will cover aliased duplicates
264265
const resolvedPath = resolver(n.source.value)
265-
const importMap = n.importKind === 'type' ? typesImported : imported
266+
const importMap = n.importKind === 'type' ? typesImported :
267+
(hasNamespace(n) ? nsImported : imported)
266268

267269
if (importMap.has(resolvedPath)) {
268270
importMap.get(resolvedPath).push(n)
@@ -273,6 +275,7 @@ module.exports = {
273275

274276
'Program:exit': function () {
275277
checkImports(imported, context)
278+
checkImports(nsImported, context)
276279
checkImports(typesImported, context)
277280
},
278281
}

Diff for: tests/src/rules/no-duplicates.js

+21-6
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,20 @@ ruleTester.run('no-duplicates', rule, {
3131
code: "import x from './bar?optionX'; import y from './bar?optionY';",
3232
options: [{'considerQueryString': true}],
3333
settings: { 'import/resolver': 'webpack' },
34-
}),
34+
}),
3535
test({
3636
code: "import x from './foo'; import y from './bar';",
3737
options: [{'considerQueryString': true}],
3838
settings: { 'import/resolver': 'webpack' },
39-
}),
39+
}),
40+
41+
// #1538: It is impossible to import namespace and other in one line, so allow this.
42+
test({
43+
code: "import * as ns from './foo'; import {y} from './foo'",
44+
}),
45+
test({
46+
code: "import {y} from './foo'; import * as ns from './foo'",
47+
}),
4048
],
4149
invalid: [
4250
test({
@@ -179,17 +187,24 @@ ruleTester.run('no-duplicates', rule, {
179187
}),
180188

181189
test({
182-
code: "import * as ns from './foo'; import {y} from './foo'",
183-
// Autofix bail because first import is a namespace import.
184-
output: "import * as ns from './foo'; import {y} from './foo'",
190+
code: "import * as ns1 from './foo'; import * as ns2 from './foo'",
191+
// Autofix bail because cannot merge namespace imports.
192+
output: "import * as ns1 from './foo'; import * as ns2 from './foo'",
193+
errors: ['\'./foo\' imported multiple times.', '\'./foo\' imported multiple times.'],
194+
}),
195+
196+
test({
197+
code: "import * as ns from './foo'; import {x} from './foo'; import {y} from './foo'",
198+
// Autofix could merge some imports, but not the namespace import.
199+
output: "import * as ns from './foo'; import {x,y} from './foo'; ",
185200
errors: ['\'./foo\' imported multiple times.', '\'./foo\' imported multiple times.'],
186201
}),
187202

188203
test({
189204
code: "import {x} from './foo'; import * as ns from './foo'; import {y} from './foo'; import './foo'",
190205
// Autofix could merge some imports, but not the namespace import.
191206
output: "import {x,y} from './foo'; import * as ns from './foo'; ",
192-
errors: ['\'./foo\' imported multiple times.', '\'./foo\' imported multiple times.', '\'./foo\' imported multiple times.', '\'./foo\' imported multiple times.'],
207+
errors: ['\'./foo\' imported multiple times.', '\'./foo\' imported multiple times.', '\'./foo\' imported multiple times.'],
193208
}),
194209

195210
test({

0 commit comments

Comments
 (0)