Skip to content
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

Change Request: [flat config] re-read the eslint.config.js file if it has been changed #16576

Closed
1 task
alexander-doroshko opened this issue Nov 23, 2022 · 12 comments · Fixed by #16608
Closed
1 task
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion archived due to age This issue has been archived; please open a new issue for any further discussion core Relates to ESLint's core APIs and features enhancement This change enhances an existing feature of ESLint
Projects

Comments

@alexander-doroshko
Copy link

ESLint version

8.28.0

What problem do you want to solve?

Hi from JetBrains! WebStorm ESLint integration has a wrapper Node.js process that lives for a long time and calls ESLint.lintText() as needed. ESLint config files might be edited between ESLint.lintText() calls.

In the 'flat config' mode, the eslint.config.js files are never re-read from disk. The reason is that they are loaded using import(), which caches the result forever.

So, the problem is that the ESLint results that WebStorm users see do not match the current configuration (eslint.config.js files).

Cleaning require.cache doesn't help. It looks like there's no way to drop the internal cache of import().

What do you think is the correct solution?

It would be great if the loadFlatConfigFile() function returned up-to-date result each time even if the config file has been edited between loadFlatConfigFile() invocations. Thank you!

Participation

  • I am willing to submit a pull request for this change.

Additional comments

No response

@alexander-doroshko alexander-doroshko added core Relates to ESLint's core APIs and features enhancement This change enhances an existing feature of ESLint triage An ESLint team member will look at this issue soon labels Nov 23, 2022
@eslint-github-bot eslint-github-bot bot added this to Needs Triage in Triage Nov 23, 2022
@mdjermanovic
Copy link
Member

Hi @alexander-doroshko, thanks for the issue!

In the 'flat config' mode, the eslint.config.js files are never re-read from disk. The reason is that they are loaded using import(), which caches the result forever.

It would be great if the loadFlatConfigFile() function returned up-to-date result each time even if the config file has been edited between loadFlatConfigFile() invocations. Thank you!

Any ideas on how we could do this? I'm not sure if there's already built-in support for this use case in Node.js.

Maybe we could check if the config file's mtime has changed, and then add a query to force reloading.

@mdjermanovic mdjermanovic removed the triage An ESLint team member will look at this issue soon label Nov 23, 2022
@mdjermanovic mdjermanovic moved this from Needs Triage to Feedback Needed in Triage Nov 23, 2022
@alexander-doroshko
Copy link
Author

The first idea that came to my mind is based on this article. Maybe it will work if you change

import("file:///path/to/eslint.config.js")

to

import("file:///path/to/eslint.config.js?mod=12345")

where 12345 is the file modification stamp?

@alexander-doroshko
Copy link
Author

alexander-doroshko commented Nov 23, 2022

I don't know how probable it is that eslint.config.js imports/requires other files that might also have been edited since they have been loaded. The trick with ?mod=12345 will probably work only for the eslint.config.js file itself.

@mdjermanovic
Copy link
Member

The first idea that came to my mind is based on this article. Maybe it will work if you change

import("file:///path/to/eslint.config.js")

to

import("file:///path/to/eslint.config.js?mod=12345")

where 12345 is the file modification stamp?

I think this would work. And if we always append the file modification stamp, then we don't need to keep the previous one and check if it has changed. fileURL we're passing to import() is an URL object, so we could do something like fileURL.searchParams.append("mod", "12345").

I don't know how probable it is that eslint.config.js imports/requires other files that might also have been edited since they have been loaded. The trick with ?mod=12345 will probably work only for the eslint.config.js file itself.

That case most likely wouldn't be covered, but if we manage to reload eslint.config.js, that would at least match the current functionality of eslintrc . In eslintrc, we're using import-fresh to load JS config files. It removes the config module (.eslintrc.js) from the require cache, but doesn't remove modules that are required from it so they're not reloaded.

@alexander-doroshko
Copy link
Author

Thanks, being on par with eslintrc sounds reasonable.
Complete reloading probably requires running it in a separate context.

@alexander-doroshko
Copy link
Author

Hi, I see the Feedback Needed tag, do you need any info from me to proceed with the request? Thank you.

Triage automation moved this from Feedback Needed to Complete Nov 30, 2022
Triage automation moved this from Complete to Evaluating Nov 30, 2022
@alexander-doroshko
Copy link
Author

Oops, sorry, I pressed the wrong button, and bots have updated the labels. Sorry about that. I'm afraid I don't have permissions to restore the correct issue state.

@mdjermanovic mdjermanovic moved this from Evaluating to Feedback Needed in Triage Nov 30, 2022
@mdjermanovic
Copy link
Member

I'm in favor of appending a query with file modification stamp in order to force reloading eslint.config.js.

@nzakas what do you think?

@nzakas
Copy link
Member

nzakas commented Dec 1, 2022

Appending a time stamp query string seems like an easy way to do this. 👍

@alexander-doroshko by the way, we would love to have your feedback on this discussion:
#16557

We are rethinking our API and would love feedback from integrators on what the current API isn’t doing for you. (Kind of like in this thread.)

@nzakas nzakas added the accepted There is consensus among the team that this change meets the criteria for inclusion label Dec 1, 2022
@nzakas nzakas moved this from Feedback Needed to Ready to Implement in Triage Dec 1, 2022
@mdjermanovic
Copy link
Member

PR #16608. Unfortunatelly, this approach doesn't seem to work when the config file is a CJS module.

nodejs/node#29812

nodejs/modules#417

@nzakas
Copy link
Member

nzakas commented Dec 8, 2022

I'm assuming the issue is that Node.js always caches a CommonJS config file when using import()?

@mdjermanovic
Copy link
Member

Yes, per comments from the issues I linked, when import-ing a CJS module Node.js gets file path from the URL and then passes it to the require infrastructure, which then loads and caches the module per the file path. Query strings are lost in the process.

I'll try the solution @fasttime suggested in #16608 (comment), just had to contemplate whether we should reload CJS configs always, like in the eslintrc config system, or only if they've changed. I think we should do the latter, so that the behavior is the same as with ESM configs.

Triage automation moved this from Ready to Implement to Complete Dec 29, 2022
@eslint-github-bot eslint-github-bot bot locked and limited conversation to collaborators Jun 28, 2023
@eslint-github-bot eslint-github-bot bot added the archived due to age This issue has been archived; please open a new issue for any further discussion label Jun 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion archived due to age This issue has been archived; please open a new issue for any further discussion core Relates to ESLint's core APIs and features enhancement This change enhances an existing feature of ESLint
Projects
Archived in project
Triage
Complete
Development

Successfully merging a pull request may close this issue.

3 participants