-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
no-cycle
hangs since v2.23.0
#2076
Comments
I suspect this might be due to #2077, but I'll leave this open pending confirmation that it's still an issue with v0.23.2 (not yet released). Either way, does the issue still occur with |
It's fine with In v2.32.2 |
Does it hang running on the CLI, or only in vscode? |
As mentioned above, both the
|
This is a critical issue. Can we please fix or revert? |
Does this still occur with v2.23.4? I’d love to fix it, but without a repro repo, it’s very difficult to debug. |
Haven't checked 2.23.4 yet, but the issue was still present in 2.23.3. Later edit: 2.23.4 is also affected. |
Also having issue. Eslint hangs after printing warnings and errors. Mine is caused by |
It seems that on one of my project the |
Yes. I can't publish my repo, and can't really reproduce it outside my repo. But it works well on |
Possibly related to #1408. Running
And after a long pause:
|
We recently tried to upgrade a large codebase from After profiling, it looks like almost all of the time is being spent here: And if I change our config from this: "import/no-cycle": [
"error",
{
ignoreExternal: true,
maxDepth: 2,
},
], to this: "import/no-cycle": [
"error",
{
ignoreExternal: false,
maxDepth: 2,
},
], Short circuiting the call to We similarly can't publish the codebase, but I'd be happy to test out any proposed changes and report back. |
@walkerburgin thanks, that's very helpful. is there any chance you could confirm on your codebase what the value of |
@ljharb I logged this out to the console and then counted duplicates in the output: console.log("" + name + "@" + context.getPhysicalFilename()); Here were the top 10 counts (I dropped the context file names):
There were 384,783 unique calls, the max count was 184, and the median was 1. If I drop the context file path and just log out the name I get 6,103 unique calls, a max count of 8,741, and a median count of 32.
|
I suspect the filename is required, because of the potential for repeated dependencies, but that does suggest that memoizing based on both would provide some improvement. |
any update here? In trying to upgrade to ESLint 8 internally, it looks like the first version of this plugin that supports ESLint 8 is 2.23.0, but because of this issue we are unable to upgrade. |
@styu if you need to update eslint quickly, you can disable the |
@alumni if there's a tool like madge that could replace our ExportMap, and do it faster - or even just be used in no-cycle - i'd consider a PR adding that as well. |
@ljharb madge is using dependency-tree, which does its own memoization (the I'm not sure things like |
For what it's worth, applying some simple caching (patch below) top of v2.25.4 makes quite a difference. There are probably some unexpected side-effects though. Timing measured with
Note that this patch already improved things a lot on v2.22.1 (57s → 10s). diff --git a/src/rules/no-cycle.js b/src/rules/no-cycle.js
index e61c3be..d338a79 100644
--- a/src/rules/no-cycle.js
+++ b/src/rules/no-cycle.js
@@ -11,2 +11,5 @@ import docsUrl from '../docsUrl';
+const traversed = new Set();
// todo: cache cycles / deep relationships for faster repeat evaluation
@@ -77,3 +80,2 @@ module.exports = {
const untraversed = [{ mget: () => imported, route:[] }];
- const traversed = new Set();
function detectCycle({ mget, route }) { |
@Rogdham hm, interesting. That makes sense, and seems like a good change, but it might break editor/eslintd integrations that sometimes do long-running eslint runs. |
Yes I agree. If for example in later runs, the But at the same times, the time improvements show that adding caching to avoid scanning the same files again and again is a good optimisation. Maybe this means that performing cycle checks at the rule level is not the good place to do it in eslint (where rules seems to be made to work on a file independently of others), but I am not familiar with eslint enough to offer a better solution. In any case, this discussion may be better suited for an other ticket, I only wanted to mention something that seemed to solve the current issue (although creating other problems) to help people that know better with making a proper fix. |
Post-install patches or forks aren’t a solution, so if the change works, it’s worth trying to upstream it. Would you be willing to make a PR? |
After some thinking, I don't feel confident enough to make a PR, I don't know the codebase at all and this is no simple issue. Here are some thoughts for the next person that works on it:
And again, maybe an eslint rule is not the best place to do the no-cycle check as I explained in my last comment. But I'm not familiar with eslint internals enough to tell. Best of luck! |
Thanks for the tips @walkerburgin and @ljharb - This matches exactly what I found doing some digging in a medium sized repo of ~2k modules. Saw total lint times cut from 5m to 2m 15s by. Opened #2612 |
Here's an idea for how to make |
An optimization to |
Closing; please file a new issue if you're still seeing perf issues in v2.30+. |
I can confirm it no longer hangs. 🎉 Note: Adding the rule increases the runtime of eslint from 7s to 47s. This might not be related to the "no-cycle" rule in particular though, as I've noticed in the past a similar increase when enabling just the "namespace" rule or just "no-duplicates". |
that’s still not bad - I’ve seen a large codebase take 20 minutes to lint, but reduced it to 2 with jest-eslint-runner - but if your TIMING output implicates a rule (and disabling that rule doesn’t just shift the slowness to another rule), please file an issue. |
With both v2.23.0 and v2.23.1, running
eslint
on the entire project hangs. Also, it will make vscode eslint plugin hang as well when saving a file (with fix on save enabled)..eslintrc
:tsconfig.json
:The text was updated successfully, but these errors were encountered: