From b743a650e9d474fcd5a4252b01c522adcc11b65c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Fermann?= Date: Mon, 6 Jul 2020 10:02:53 +0200 Subject: [PATCH] [New] `max-dependencies`: add option `ignoreTypeImports` --- CHANGELOG.md | 2 + src/rules/max-dependencies.js | 18 ++++++--- tests/src/rules/max-dependencies.js | 57 ++++++++++++++++++++++++++++- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45aacceb7..d4163b8fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel - [`no-dynamic-require`]: add option `esmodule` ([#1223], thanks [@vikr01]) - [`named`]: add `commonjs` option ([#1222], thanks [@vikr01]) - [`no-namespace`]: Add `ignore` option ([#2112], thanks [@aberezkin]) +- [`max-dependencies`]: add option `ignoreTypeImports` ([#1847], thanks [@rfermann]) ### Fixed - [`no-duplicates`]: ensure autofix avoids excessive newlines ([#2028], thanks [@ertrzyiks]) @@ -853,6 +854,7 @@ for info on changes for earlier releases. [#1878]: https://github.com/benmosher/eslint-plugin-import/pull/1878 [#1860]: https://github.com/benmosher/eslint-plugin-import/pull/1860 [#1848]: https://github.com/benmosher/eslint-plugin-import/pull/1848 +[#1847]: https://github.com/benmosher/eslint-plugin-import/pull/1847 [#1846]: https://github.com/benmosher/eslint-plugin-import/pull/1846 [#1836]: https://github.com/benmosher/eslint-plugin-import/pull/1836 [#1835]: https://github.com/benmosher/eslint-plugin-import/pull/1835 diff --git a/src/rules/max-dependencies.js b/src/rules/max-dependencies.js index c8e1b3ab1..f9bdd12e5 100644 --- a/src/rules/max-dependencies.js +++ b/src/rules/max-dependencies.js @@ -2,15 +2,14 @@ import moduleVisitor from 'eslint-module-utils/moduleVisitor'; import docsUrl from '../docsUrl'; const DEFAULT_MAX = 10; +const DEFAULT_IGNORE_TYPE_IMPORTS = false; +const TYPE_IMPORT = 'type'; const countDependencies = (dependencies, lastNode, context) => { const { max } = context.options[0] || { max: DEFAULT_MAX }; if (dependencies.size > max) { - context.report( - lastNode, - `Maximum number of dependencies (${max}) exceeded.` - ); + context.report(lastNode, `Maximum number of dependencies (${max}) exceeded.`); } }; @@ -26,6 +25,7 @@ module.exports = { 'type': 'object', 'properties': { 'max': { 'type': 'number' }, + 'ignoreTypeImports': { 'type': 'boolean' }, }, 'additionalProperties': false, }, @@ -33,6 +33,10 @@ module.exports = { }, create: context => { + const { + ignoreTypeImports = DEFAULT_IGNORE_TYPE_IMPORTS, + } = context.options[0] || {}; + const dependencies = new Set(); // keep track of dependencies let lastNode; // keep track of the last node to report on @@ -40,8 +44,10 @@ module.exports = { 'Program:exit': function () { countDependencies(dependencies, lastNode, context); }, - }, moduleVisitor((source) => { - dependencies.add(source.value); + }, moduleVisitor((source, { importKind }) => { + if (importKind !== TYPE_IMPORT || !ignoreTypeImports) { + dependencies.add(source.value); + } lastNode = source; }, { commonjs: true })); }, diff --git a/tests/src/rules/max-dependencies.js b/tests/src/rules/max-dependencies.js index f4e5f9a97..1251af97e 100644 --- a/tests/src/rules/max-dependencies.js +++ b/tests/src/rules/max-dependencies.js @@ -1,6 +1,8 @@ -import { test } from '../utils'; +import { test, getTSParsers } from '../utils'; import { RuleTester } from 'eslint'; +import eslintPkg from 'eslint/package.json'; +import semver from 'semver'; const ruleTester = new RuleTester(); const rule = require('rules/max-dependencies'); @@ -74,5 +76,58 @@ ruleTester.run('max-dependencies', rule, { 'Maximum number of dependencies (1) exceeded.', ], }), + + test({ + code: 'import type { x } from \'./foo\'; import type { y } from \'./bar\'; import type { z } from \'./baz\'', + parser: require.resolve('babel-eslint'), + options: [{ + max: 2, + ignoreTypeImports: false, + }], + errors: [ + 'Maximum number of dependencies (2) exceeded.', + ], + }), ], }); + +context('TypeScript', { skip: semver.satisfies(eslintPkg.version, '>5.0.0') }, () => { + getTSParsers().forEach((parser) => { + ruleTester.run(`max-dependencies (${parser.replace(process.cwd(), '.')})`, rule, { + valid: [ + test({ + code: 'import type { x } from \'./foo\'; import { y } from \'./bar\';', + parser: parser, + options: [{ + max: 1, + ignoreTypeImports: true, + }], + }), + ], + invalid: [ + test({ + code: 'import type { x } from \'./foo\'; import type { y } from \'./bar\'', + parser: parser, + options: [{ + max: 1, + }], + errors: [ + 'Maximum number of dependencies (1) exceeded.', + ], + }), + + test({ + code: 'import type { x } from \'./foo\'; import type { y } from \'./bar\'; import type { z } from \'./baz\'', + parser: parser, + options: [{ + max: 2, + ignoreTypeImports: false, + }], + errors: [ + 'Maximum number of dependencies (2) exceeded.', + ], + }), + ], + }); + }); +});