Skip to content

Commit afe0a3a

Browse files
ntdbbenmosher
authored andcommitted
Add no-named-default rule (#596)
* Add empty `no-named-default` rule and tests (failing) * Functioning `no-named-default` rule with tests * Document `no-named-default` rule * Add `no-named-default` to README * Simplify docs * Add `no-named-default` note to CHANGELOG * Remove unnecessary check for `name` key * Simplify rule logic, add new test, fix syntax error in docs * Remove source check, use template literal syntax for message * Simplify rationale in docs
1 parent edbb570 commit afe0a3a

File tree

6 files changed

+93
-2
lines changed

6 files changed

+93
-2
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
44
This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com).
55

66
## [Unreleased]
7+
### Added
8+
- Add [`no-named-default`] rule: style-guide rule to report use of unnecessarily named default imports
9+
710
### Fixed
811
- [`prefer-default-export`] handles re-exported default exports ([#609])
912
- Fix crash when using `newline-after-import` with decorators ([#592])

README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,9 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a
8585
* Enforce a convention in module import order ([`order`])
8686
* Enforce a newline after import statements ([`newline-after-import`])
8787
* Prefer a default export if module exports a single name ([`prefer-default-export`])
88-
* Limit the maximum number of dependencies a module can have. ([`max-dependencies`])
89-
* Forbid unassigned imports. ([`no-unassigned-import`])
88+
* Limit the maximum number of dependencies a module can have ([`max-dependencies`])
89+
* Forbid unassigned imports ([`no-unassigned-import`])
90+
* Forbid named default exports ([`no-named-default`])
9091

9192
[`first`]: ./docs/rules/first.md
9293
[`no-duplicates`]: ./docs/rules/no-duplicates.md
@@ -97,6 +98,7 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a
9798
[`prefer-default-export`]: ./docs/rules/prefer-default-export.md
9899
[`max-dependencies`]: ./docs/rules/max-dependencies.md
99100
[`no-unassigned-import`]: ./docs/rules/no-unassigned-import.md
101+
[`no-named-default`]: ./docs/rules/no-named-default.md
100102

101103
## Installation
102104

docs/rules/no-named-default.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# no-named-default
2+
3+
Reports use of a default export as a locally named import.
4+
5+
Rationale: the syntax exists to import default exports expressively, let's use it.
6+
7+
## Rule Details
8+
9+
Given:
10+
```js
11+
// foo.js
12+
export default 'foo';
13+
export const bar = 'baz';
14+
```
15+
16+
...these would be valid:
17+
```js
18+
import foo from './foo.js';
19+
import foo, { bar } from './foo.js';
20+
```
21+
22+
...and these would be reported:
23+
```js
24+
// message: Using exported name 'bar' as identifier for default export.
25+
import { default as foo } from './foo.js';
26+
import { default as foo, bar } from './foo.js';
27+
```

src/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export const rules = {
1010
'no-restricted-paths': require('./rules/no-restricted-paths'),
1111
'no-internal-modules': require('./rules/no-internal-modules'),
1212

13+
'no-named-default': require('./rules/no-named-default'),
1314
'no-named-as-default': require('./rules/no-named-as-default'),
1415
'no-named-as-default-member': require('./rules/no-named-as-default-member'),
1516

src/rules/no-named-default.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module.exports = {
2+
meta: {
3+
docs: {},
4+
},
5+
6+
create: function (context) {
7+
return {
8+
'ImportDeclaration': function (node) {
9+
node.specifiers.forEach(function (im) {
10+
if (im.type === 'ImportSpecifier' && im.imported.name === 'default') {
11+
context.report({
12+
node: im.local,
13+
message: `Use default import syntax to import \'${im.local.name}\'.` })
14+
}
15+
})
16+
},
17+
}
18+
},
19+
}

tests/src/rules/no-named-default.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { test, SYNTAX_CASES } from '../utils'
2+
import { RuleTester } from 'eslint'
3+
4+
const ruleTester = new RuleTester()
5+
, rule = require('rules/no-named-default')
6+
7+
ruleTester.run('no-named-default', rule, {
8+
valid: [
9+
test({code: 'import bar from "./bar";'}),
10+
test({code: 'import bar, { foo } from "./bar";'}),
11+
12+
...SYNTAX_CASES,
13+
],
14+
15+
invalid: [
16+
test({
17+
code: 'import { default } from "./bar";',
18+
errors: [{
19+
message: 'Use default import syntax to import \'default\'.',
20+
type: 'Identifier',
21+
}],
22+
parser: 'babel-eslint',
23+
}),
24+
test({
25+
code: 'import { default as bar } from "./bar";',
26+
errors: [{
27+
message: 'Use default import syntax to import \'bar\'.',
28+
type: 'Identifier',
29+
}],
30+
}),
31+
test({
32+
code: 'import { foo, default as bar } from "./bar";',
33+
errors: [{
34+
message: 'Use default import syntax to import \'bar\'.',
35+
type: 'Identifier',
36+
}],
37+
}),
38+
],
39+
})

0 commit comments

Comments
 (0)