diff --git a/CHANGELOG.md b/CHANGELOG.md index fbb5c8092..4d03e9821 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 @@ -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 diff --git a/src/rules/no-default-export.js b/src/rules/no-default-export.js index cb7c0bb72..a17428c56 100644 --- a/src/rules/no-default-export.js +++ b/src/rules/no-default-export.js @@ -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 }); } }); }, diff --git a/tests/src/rules/no-default-export.js b/tests/src/rules/no-default-export.js index bc0119a01..61e55d959 100644 --- a/tests/src/rules/no-default-export.js +++ b/tests/src/rules/no-default-export.js @@ -1,4 +1,4 @@ -import { test } from '../utils'; +import { test, testVersion } from '../utils'; import { RuleTester } from 'eslint'; @@ -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.', + }, + ], + }), + ), }); diff --git a/tests/src/utils.js b/tests/src/utils.js index 4d23af755..012c3a7c7 100644 --- a/tests/src/utils.js +++ b/tests/src/utils.js @@ -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) {