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-default-import: limit highlight to the word "default" #2299

Merged
Merged
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,9 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
### Fixed
- `importType`: avoid crashing on a non-string' ([#2305], thanks [@ljharb])

### Changed
- [`no-default-import`]: report on the token "default" instead of the entire node ([#2299], [@pmcelhaney])

## [2.25.3] - 2021-11-09

### Fixed
Expand Down Expand Up @@ -945,7 +948,11 @@ for info on changes for earlier releases.

[`memo-parser`]: ./memo-parser/README.md

<<<<<<< HEAD
[#2305]: https://github.com/import-js/eslint-plugin-import/pull/2305
=======
[#2299]: https://github.com/import-js/eslint-plugin-import/pull/2299
>>>>>>> 374ce41e... [Fix] `no-default-import`: report on the token "default" instead of the entire node
[#2297]: https://github.com/import-js/eslint-plugin-import/pull/2297
[#2287]: https://github.com/import-js/eslint-plugin-import/pull/2287
[#2282]: https://github.com/import-js/eslint-plugin-import/pull/2282
Expand Down
20 changes: 9 additions & 11 deletions src/rules/no-default-export.js
Expand Up @@ -16,23 +16,21 @@ module.exports = {
}

const preferNamed = 'Prefer named exports.';
const noAliasDefault = ({ local }) =>
`Do not alias \`${local.name}\` as \`default\`. Just export ` +
`\`${local.name}\` itself instead.`;
const noAliasDefault = ({ local }) => `Do not alias \`${local.name}\` as \`default\`. Just export \`${local.name}\` itself instead.`;

return {
ExportDefaultDeclaration(node) {
context.report({ node, message: preferNamed });
const { loc } = context.getSourceCode().getFirstTokens(node)[1] || {};
context.report({ node, message: preferNamed, loc });
},

ExportNamedDeclaration(node) {
node.specifiers.forEach(specifier => {
if (specifier.type === 'ExportDefaultSpecifier' &&
specifier.exported.name === 'default') {
context.report({ node, message: preferNamed });
} else if (specifier.type === 'ExportSpecifier' &&
specifier.exported.name === 'default') {
context.report({ node, message: noAliasDefault(specifier) });
node.specifiers.filter(specifier => specifier.exported.name === 'default').forEach(specifier => {
const { loc } = context.getSourceCode().getFirstTokens(node)[1] || {};
if (specifier.type === 'ExportDefaultSpecifier') {
context.report({ node, message: preferNamed, loc });
} else if (specifier.type === 'ExportSpecifier') {
context.report({ node, message: noAliasDefault(specifier), loc });
}
});
},
Expand Down
94 changes: 69 additions & 25 deletions tests/src/rules/no-default-export.js
@@ -1,4 +1,4 @@
import { test } from '../utils';
import { test, testVersion } from '../utils';

import { RuleTester } from 'eslint';

Expand Down Expand Up @@ -85,38 +85,82 @@ ruleTester.run('no-default-export', rule, {
parser: require.resolve('babel-eslint'),
}),
],
invalid: [
test({
invalid: [].concat(
testVersion('> 2', () => ({
code: 'export default function bar() {};',
errors: [{
type: 'ExportDefaultDeclaration',
message: 'Prefer named exports.',
}],
}),
test({
errors: [
{
type: 'ExportDefaultDeclaration',
message: 'Prefer named exports.',
line: 1,
column: 8,
},
],
})),
testVersion('> 2', () => ({
code: `
export const foo = 'foo';
export default bar;`,
errors: [{
type: 'ExportDefaultDeclaration',
message: 'Prefer named exports.',
}],
}),
errors: [
{
type: 'ExportDefaultDeclaration',
message: 'Prefer named exports.',
line: 3,
column: 16,
},
],
})),
testVersion('> 2', () => ({
code: 'export default class Bar {};',
errors: [
{
type: 'ExportDefaultDeclaration',
message: 'Prefer named exports.',
line: 1,
column: 8,
},
],
})),
testVersion('> 2', () => ({
code: 'export default function() {};',
errors: [
{
type: 'ExportDefaultDeclaration',
message: 'Prefer named exports.',
line: 1,
column: 8,
},
],
})),
testVersion('> 2', () => ({
code: 'export default class {};',
errors: [
{
type: 'ExportDefaultDeclaration',
message: 'Prefer named exports.',
line: 1,
column: 8,
},
],
})),
test({
code: 'let foo; export { foo as default }',
errors: [{
type: 'ExportNamedDeclaration',
message: 'Do not alias `foo` as `default`. Just export `foo` itself ' +
'instead.',
}],
errors: [
{
type: 'ExportNamedDeclaration',
message: 'Do not alias `foo` as `default`. Just export `foo` itself instead.',
},
],
}),
test({
code: 'export default from "foo.js"',
parser: require.resolve('babel-eslint'),
errors: [{
type: 'ExportNamedDeclaration',
message: 'Prefer named exports.',
}],
}),
],
errors: [
{
type: 'ExportNamedDeclaration',
message: 'Prefer named exports.',
},
],
}),
),
});
2 changes: 1 addition & 1 deletion tests/src/utils.js
Expand Up @@ -28,7 +28,7 @@ export function getNonDefaultParsers() {
export const FILENAME = testFilePath('foo.js');

export function testVersion(specifier, t) {
return semver.satisfies(eslintPkg.version, specifier) && test(t());
return semver.satisfies(eslintPkg.version, specifier) ? test(t()) : [];
}

export function test(t) {
Expand Down