Skip to content

Commit

Permalink
Add no-named-default rule (#596)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
ntdb authored and benmosher committed Nov 2, 2016
1 parent edbb570 commit afe0a3a
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com).

## [Unreleased]
### Added
- Add [`no-named-default`] rule: style-guide rule to report use of unnecessarily named default imports

### Fixed
- [`prefer-default-export`] handles re-exported default exports ([#609])
- Fix crash when using `newline-after-import` with decorators ([#592])
Expand Down
6 changes: 4 additions & 2 deletions README.md
Expand Up @@ -85,8 +85,9 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a
* Enforce a convention in module import order ([`order`])
* Enforce a newline after import statements ([`newline-after-import`])
* Prefer a default export if module exports a single name ([`prefer-default-export`])
* Limit the maximum number of dependencies a module can have. ([`max-dependencies`])
* Forbid unassigned imports. ([`no-unassigned-import`])
* Limit the maximum number of dependencies a module can have ([`max-dependencies`])
* Forbid unassigned imports ([`no-unassigned-import`])
* Forbid named default exports ([`no-named-default`])

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

## Installation

Expand Down
27 changes: 27 additions & 0 deletions docs/rules/no-named-default.md
@@ -0,0 +1,27 @@
# no-named-default

Reports use of a default export as a locally named import.

Rationale: the syntax exists to import default exports expressively, let's use it.

## Rule Details

Given:
```js
// foo.js
export default 'foo';
export const bar = 'baz';
```

...these would be valid:
```js
import foo from './foo.js';
import foo, { bar } from './foo.js';
```

...and these would be reported:
```js
// message: Using exported name 'bar' as identifier for default export.
import { default as foo } from './foo.js';
import { default as foo, bar } from './foo.js';
```
1 change: 1 addition & 0 deletions src/index.js
Expand Up @@ -10,6 +10,7 @@ export const rules = {
'no-restricted-paths': require('./rules/no-restricted-paths'),
'no-internal-modules': require('./rules/no-internal-modules'),

'no-named-default': require('./rules/no-named-default'),
'no-named-as-default': require('./rules/no-named-as-default'),
'no-named-as-default-member': require('./rules/no-named-as-default-member'),

Expand Down
19 changes: 19 additions & 0 deletions src/rules/no-named-default.js
@@ -0,0 +1,19 @@
module.exports = {
meta: {
docs: {},
},

create: function (context) {
return {
'ImportDeclaration': function (node) {
node.specifiers.forEach(function (im) {
if (im.type === 'ImportSpecifier' && im.imported.name === 'default') {
context.report({
node: im.local,
message: `Use default import syntax to import \'${im.local.name}\'.` })
}
})
},
}
},
}
39 changes: 39 additions & 0 deletions tests/src/rules/no-named-default.js
@@ -0,0 +1,39 @@
import { test, SYNTAX_CASES } from '../utils'
import { RuleTester } from 'eslint'

const ruleTester = new RuleTester()
, rule = require('rules/no-named-default')

ruleTester.run('no-named-default', rule, {
valid: [
test({code: 'import bar from "./bar";'}),
test({code: 'import bar, { foo } from "./bar";'}),

...SYNTAX_CASES,
],

invalid: [
test({
code: 'import { default } from "./bar";',
errors: [{
message: 'Use default import syntax to import \'default\'.',
type: 'Identifier',
}],
parser: 'babel-eslint',
}),
test({
code: 'import { default as bar } from "./bar";',
errors: [{
message: 'Use default import syntax to import \'bar\'.',
type: 'Identifier',
}],
}),
test({
code: 'import { foo, default as bar } from "./bar";',
errors: [{
message: 'Use default import syntax to import \'bar\'.',
type: 'Identifier',
}],
}),
],
})

0 comments on commit afe0a3a

Please sign in to comment.