diff --git a/CHANGELOG.md b/CHANGELOG.md index 452a0fcfe..123d48029 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel - [`prefer-default-export`]: handle empty array destructuring ([#1965], thanks [@ljharb]) - [`no-unused-modules`]: make type imports mark a module as used (fixes #1924) ([#1974], thanks [@cherryblossom000]) - [`no-cycle`]: fix perf regression ([#1944], thanks [@Blasz]) +- [`first`]: fix handling of `import = require` ([#1963], thanks [@MatthiasKunnen]) ### Changed - [Generic Import Callback] Make callback for all imports once in rules ([#1237], thanks [@ljqx]) @@ -1307,4 +1308,5 @@ for info on changes for earlier releases. [@fa93hws]: https://github.com/fa93hws [@Librazy]: https://github.com/Librazy [@swernerx]: https://github.com/swernerx -[@fsmaia]: https://github.com/fsmaia \ No newline at end of file +[@fsmaia]: https://github.com/fsmaia +[@MatthiasKunnen]: https://github.com/MatthiasKunnen diff --git a/src/rules/first.js b/src/rules/first.js index 4d909bea3..a3b7f24e0 100644 --- a/src/rules/first.js +++ b/src/rules/first.js @@ -1,5 +1,11 @@ import docsUrl from '../docsUrl'; +function getImportValue(node) { + return node.type === 'ImportDeclaration' + ? node.source.value + : node.moduleReference.expression.value; +} + module.exports = { meta: { type: 'suggestion', @@ -43,13 +49,13 @@ module.exports = { anyExpressions = true; - if (node.type === 'ImportDeclaration') { + if (node.type === 'ImportDeclaration' || node.type === 'TSImportEqualsDeclaration') { if (absoluteFirst) { - if (/^\./.test(node.source.value)) { + if (/^\./.test(getImportValue(node))) { anyRelative = true; } else if (anyRelative) { context.report({ - node: node.source, + node: node.type === 'ImportDeclaration' ? node.source : node.moduleReference, message: 'Absolute imports should come before relative imports.', }); } diff --git a/tests/src/rules/first.js b/tests/src/rules/first.js index e8b40eb98..3f7301319 100644 --- a/tests/src/rules/first.js +++ b/tests/src/rules/first.js @@ -1,4 +1,4 @@ -import { test } from '../utils'; +import { test, getTSParsers } from '../utils'; import { RuleTester } from 'eslint'; @@ -66,3 +66,51 @@ ruleTester.run('first', rule, { }), ], }); + +context('TypeScript', function () { + getTSParsers() + .filter((parser) => parser !== require.resolve('typescript-eslint-parser')) + .forEach((parser) => { + const parserConfig = { + parser: parser, + settings: { + 'import/parsers': { [parser]: ['.ts'] }, + 'import/resolver': { 'eslint-import-resolver-typescript': true }, + }, + }; + + ruleTester.run('order', rule, { + valid: [ + test( + { + code: ` + import y = require('bar'); + import { x } from 'foo'; + import z = require('baz'); + `, + parser, + }, + parserConfig, + ), + ], + invalid: [ + test( + { + code: ` + import { x } from './foo'; + import y = require('bar'); + `, + options: ['absolute-first'], + parser, + errors: [ + { + message: 'Absolute imports should come before relative imports.', + }, + ], + }, + parserConfig, + ), + ], + }); + }); +});