Skip to content

Commit c862b68

Browse files
committed
fix #328: properly suppress default when looking at * exports.
1 parent e049817 commit c862b68

File tree

10 files changed

+56
-10
lines changed

10 files changed

+56
-10
lines changed

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44
This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com).
55

6+
## [Unreleased]
7+
### Fixed
8+
- `export * from 'foo'` now properly ignores a `default` export from `foo`, if any. ([#328]/[#332], thanks [@jkimbo])
9+
This impacts all static analysis of imported names. ([`default`], [`named`], [`namespace`], [`export`])
10+
611
## [1.8.0] - 2016-05-11
712
### Added
813
- [`prefer-default-export`], new rule. ([#308], thanks [@gavriguy])
@@ -206,10 +211,13 @@ for info on changes for earlier releases.
206211
[`no-nodejs-modules`]: ./docs/rules/no-nodejs-modules.md
207212
[`order`]: ./docs/rules/order.md
208213
[`named`]: ./docs/rules/named.md
214+
[`default`]: ./docs/rules/default.md
215+
[`export`]: ./docs/rules/export.md
209216
[`newline-after-import`]: ./docs/rules/newline-after-import.md
210217
[`no-mutable-exports`]: ./docs/rules/no-mutable-exports.md
211218
[`prefer-default-export`]: ./docs/rules/prefer-default-export.md
212219

220+
[#332]: https://github.com/benmosher/eslint-plugin-import/pull/332
213221
[#322]: https://github.com/benmosher/eslint-plugin-import/pull/322
214222
[#316]: https://github.com/benmosher/eslint-plugin-import/pull/316
215223
[#308]: https://github.com/benmosher/eslint-plugin-import/pull/308
@@ -235,6 +243,7 @@ for info on changes for earlier releases.
235243
[#164]: https://github.com/benmosher/eslint-plugin-import/pull/164
236244
[#157]: https://github.com/benmosher/eslint-plugin-import/pull/157
237245

246+
[#328]: https://github.com/benmosher/eslint-plugin-import/issues/328
238247
[#317]: https://github.com/benmosher/eslint-plugin-import/issues/317
239248
[#286]: https://github.com/benmosher/eslint-plugin-import/issues/286
240249
[#281]: https://github.com/benmosher/eslint-plugin-import/issues/281
@@ -290,3 +299,4 @@ for info on changes for earlier releases.
290299
[@josh]: https://github.com/josh
291300
[@borisyankov]: https://github.com/borisyankov
292301
[@gavriguy]: https://github.com/gavriguy
302+
[@jkimbo]: https://github.com/jkimbo

src/core/getExports.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,8 @@ export default class ExportMap {
228228
if (this.namespace.has(name)) return true
229229
if (this.reexports.has(name)) return true
230230

231-
for (let dep of this.dependencies.values()) {
231+
// default exports must be explicitly re-exported (#328)
232+
if (name !== 'default') for (let dep of this.dependencies.values()) {
232233
let innerMap = dep()
233234

234235
// todo: report as unresolved?
@@ -264,7 +265,9 @@ export default class ExportMap {
264265
return deep
265266
}
266267

267-
for (let dep of this.dependencies.values()) {
268+
269+
// default exports must be explicitly re-exported (#328)
270+
if (name !== 'default') for (let dep of this.dependencies.values()) {
268271
let innerMap = dep()
269272
// todo: report as unresolved?
270273
if (!innerMap) continue
@@ -298,7 +301,8 @@ export default class ExportMap {
298301
return imported.get(local)
299302
}
300303

301-
for (let dep of this.dependencies.values()) {
304+
// default exports must be explicitly re-exported (#328)
305+
if (name !== 'default') for (let dep of this.dependencies.values()) {
302306
let innerMap = dep()
303307
// todo: report as unresolved?
304308
if (!innerMap) continue
@@ -321,7 +325,7 @@ export default class ExportMap {
321325
callback.call(thisArg, getImport().get(local), name, this))
322326

323327
this.dependencies.forEach(dep => dep().forEach((v, n) =>
324-
callback.call(thisArg, v, n, this)))
328+
n !== 'default' && callback.call(thisArg, v, n, this)))
325329
}
326330

327331
// todo: keys, values, entries?

src/rules/export.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ module.exports = function (context) {
5050
return
5151
}
5252
let any = false
53-
remoteExports.forEach((v, name) => (any = true) && addNamed(name, node))
53+
remoteExports.forEach((v, name) => name !== 'default' && (any = true) && addNamed(name, node))
5454

5555
if (!any) {
5656
context.report(node.source,

tests/files/deep-es7/b.js

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * as c from './c'
2+
export default 'b'

tests/files/deep/b.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
import * as c from './c'
2-
export { c }
2+
export { c }
3+
export default 'b'

tests/files/re-export.js

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
export const c = 'foo'
22

33
export * from './named-exports'
4+
5+
// #328: this exports only 'foo', not the default.
6+
export * from './bar'

tests/src/rules/default.js

+6
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,11 @@ ruleTester.run('default', rule, {
115115
parser: 'babel-eslint',
116116
errors: ['No default export found in module.'],
117117
}),
118+
119+
// #328: * exports do not include default
120+
test({
121+
code: 'import barDefault from "./re-export"',
122+
errors: [`No default export found in module.`],
123+
}),
118124
],
119125
})

tests/src/rules/export.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ ruleTester.run('export', rule, {
2121
test({ code: 'export { bar }; export * from "./export-all"' }),
2222
test({ code: 'export * from "./export-all"' }),
2323
test({ code: 'export * from "./does-not-exist"' }),
24+
25+
// #328: "export * from" does not export a default
26+
test({ code: 'export default foo; export * from "./bar"' }),
2427
],
2528

2629
invalid: [
@@ -29,10 +32,6 @@ ruleTester.run('export', rule, {
2932
code: 'export default foo; export default bar',
3033
errors: ['Multiple default exports.', 'Multiple default exports.'],
3134
}),
32-
test({
33-
code: 'export default foo; export * from "./default-export"',
34-
errors: ['Multiple default exports.', 'Multiple default exports.'],
35-
}),
3635
test({
3736
code: 'export default function foo() {}; ' +
3837
'export default function bar() {}',
@@ -99,5 +98,11 @@ ruleTester.run('export', rule, {
9998
'Multiple exports of name \'bar\'.'],
10099
}),
101100

101+
102+
// #328: "export * from" does not export a default
103+
test({
104+
code: 'export * from "./default-export"',
105+
errors: [`No named exports found in module './default-export'.`],
106+
}),
102107
],
103108
})

tests/src/rules/named.js

+6
Original file line numberDiff line numberDiff line change
@@ -217,5 +217,11 @@ ruleTester.run('named', rule, {
217217
// todo: better error message
218218
errors: ["common not found via re-export-default.js -> common.js"],
219219
}),
220+
221+
// #328: * exports do not include default
222+
test({
223+
code: 'import { default as barDefault } from "./re-export"',
224+
errors: [`default not found in './re-export'`],
225+
}),
220226
],
221227
})

tests/src/rules/namespace.js

+10
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ const valid = [
7777

7878
// names.default is valid export
7979
test({ code: "import * as names from './default-export';" }),
80+
test({ code: "import * as names from './default-export'; console.log(names.default)" }),
8081
test({
8182
code: 'export * as names from "./default-export"',
8283
parser: 'babel-eslint',
@@ -164,6 +165,12 @@ const invalid = [
164165
errors: [error('c', 'names')],
165166
}),
166167

168+
// #328: * exports do not include default
169+
test({
170+
code: 'import * as ree from "./re-export"; console.log(ree.default)',
171+
errors: [`'default' not found in imported namespace 'ree'.`],
172+
}),
173+
167174
]
168175

169176
///////////////////////
@@ -177,6 +184,9 @@ const invalid = [
177184
test({ parser, code: `import * as a from "./${folder}/a"; var {b:{c:{d:{e}}}} = a` }),
178185
test({ parser, code: `import { b } from "./${folder}/a"; var {c:{d:{e}}} = b` }))
179186

187+
// deep namespaces should include explicitly exported defaults
188+
test({ parser, code: `import * as a from "./${folder}/a"; console.log(a.b.default)` }),
189+
180190
invalid.push(
181191
test({
182192
parser,

0 commit comments

Comments
 (0)