diff --git a/CHANGELOG.md b/CHANGELOG.md index 3102fc8691..23c5d19eef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,12 +20,13 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange - [`order`]: leave more space in rankings for consecutive path groups ([#2506], thanks [@Pearce-Ropion]) ### Changed -- [Tests] `named`: Run all TypeScript test ([#2427], thanks [@ProdigySim]) +- [Tests] [`named`]: Run all TypeScript test ([#2427], thanks [@ProdigySim]) - [readme] note use of typescript in readme `import/extensions` section ([#2440], thanks [@OutdatedVersion]) -- [Docs] `order`: use correct default value ([#2392], thanks [@hyperupcall]) +- [Docs] [`order`]: use correct default value ([#2392], thanks [@hyperupcall]) - [meta] replace git.io link in comments with the original URL ([#2444], thanks [@liby]) - [Docs] remove global install in readme ([#2412], thanks [@aladdin-add]) - [readme] clarify `eslint-import-resolver-typescript` usage ([#2503], thanks [@JounQin]) +- [Refactor] [`no-cycle`]: Improve performance by using caching ([#2419], thanks [@nokel81]) ## [2.26.0] - 2022-04-05 @@ -1004,6 +1005,7 @@ for info on changes for earlier releases. [#2466]: https://github.com/import-js/eslint-plugin-import/pull/2466 [#2440]: https://github.com/import-js/eslint-plugin-import/pull/2440 [#2427]: https://github.com/import-js/eslint-plugin-import/pull/2427 +[#2419]: https://github.com/import-js/eslint-plugin-import/pull/2419 [#2417]: https://github.com/import-js/eslint-plugin-import/pull/2417 [#2411]: https://github.com/import-js/eslint-plugin-import/pull/2411 [#2399]: https://github.com/import-js/eslint-plugin-import/pull/2399 diff --git a/src/rules/no-cycle.js b/src/rules/no-cycle.js index 0aa3626827..e76b889574 100644 --- a/src/rules/no-cycle.js +++ b/src/rules/no-cycle.js @@ -9,6 +9,8 @@ import { isExternalModule } from '../core/importType'; import moduleVisitor, { makeOptionsSchema } from 'eslint-module-utils/moduleVisitor'; import docsUrl from '../docsUrl'; +const traversed = new Set(); + // todo: cache cycles / deep relationships for faster repeat evaluation module.exports = { meta: { @@ -40,8 +42,8 @@ module.exports = { }, })], }, - - create(context) { + _traversed: traversed, + create: (context) => { const myPath = context.getPhysicalFilename ? context.getPhysicalFilename() : context.getFilename(); if (myPath === '') return {}; // can't cycle-check a non-file @@ -87,7 +89,6 @@ module.exports = { } const untraversed = [{ mget: () => imported, route:[] }]; - const traversed = new Set(); function detectCycle({ mget, route }) { const m = mget(); if (m == null) return; diff --git a/tests/src/rules/no-cycle.js b/tests/src/rules/no-cycle.js index ad29292c23..a85055c08b 100644 --- a/tests/src/rules/no-cycle.js +++ b/tests/src/rules/no-cycle.js @@ -2,6 +2,7 @@ import { parsers, test as _test, testFilePath, testVersion as _testVersion } fro import { RuleTester } from 'eslint'; import flatMap from 'array.prototype.flatmap'; +import { beforeEach } from 'mocha'; const ruleTester = new RuleTester(); const rule = require('rules/no-cycle'); @@ -17,6 +18,10 @@ const testVersion = (specifier, t) => _testVersion(specifier, () => Object.assig const testDialects = ['es6']; +beforeEach(() => { + rule._traversed.clear(); +}); + ruleTester.run('no-cycle', rule, { valid: [].concat( // this rule doesn't care if the cycle length is 0