-
-
Notifications
You must be signed in to change notification settings - Fork 70
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
feat: Directive to Skip File Parsing #118
Conversation
this seems like a security attack vector. why would i want to permit someone to add a file to my codebase that, unbeknownst to me, isn't verified by eslint? |
The file would be generated code, such as an API client generated by
How is this different from files self-ignoring with |
Fair question, and there's https://www.npmjs.com/package/eslint-plugin-eslint-comments for that, but I'd expect generated code to output into a single folder, which could easily be ignored with |
I must respectfully disagree with you on that point, and evidently many others. In most codebases I've seen so far, generated code is not hosted in a single directory. Instead, consider the following GraphQL/Tsoa backend:
A collective |
you can ignore |
You're right, I missed that. Regardless, this propsal is not about the functional ability to skip certain files from being parsed. Instead, it's about the file skipping itself fully. Files with |
I agree with your assessment - however, my experience managing linter settings in large codebases tells me that files overriding eslint themselves is an antipattern (albeit sometimes necessary for some kinds of overrides) and that eslint config is best managed centrally in a root config file. Adding this feature would thus require me to waste further resources banning its use in every project I manage. |
Could you please elaborate on the difference between I don't have the experience of working in large codebases you do, and in no scenario I can think of, would disable work, but skip-file not. |
The difference is that with this new proposal, parse errors can go undetected. |
I don't see how that is a bad thing. It's not in the interest of the application developer to experience ESLint crashes over files that are ignored anyway. Other than for reporting issues to the library developer, parsing eslint-disabled files has no value to the application developer. If your experience tells otherwise, that would resolve this discussion, I myself don't see when this would not be the case. |
A syntax error in production that's not caught in CI can break your entire application; just because you don't want eslint rules on a file doesn't mean you want syntax errors in it. Can you help me understand a use case where you do NOT care that there's syntax errors in a lintable file? |
Oh, we might be talking about slightly different things. 😅 With "ESLint crashes", I mean that as a consequence a bug in an ESLint rule, such as here. This caused ESLint to crash on files automatically generated by Tsoa, which the application developer practically has no control over. When you talk about syntax errors, do you regard ESLint as a syntax checker? I did not at all consider that. To me, ESLint is purely about code style, and syntactic checks are done by the TypeScript compiler. Or concretely, your concern is that ESLint would no longer catch syntax errors in a self-ignoring file, which would cause that file to go to production otherwise unverified? |
Yes, eslint even with no rules enabled is a syntax checker, and this is a very important function it serves. Not everyone uses TypeScript. Yes, that is my concern. |
|
||
Many libraries that generate code generate code with leading `/* eslint-disable */` directives at the top of generated files. However, those files are still parsed and validated, which slows down the linting process needlessly. Potentially large and complex files are processed, even though their results are useless to the application developer. In the worst case, bugs in linting rules (see [this issue about a broken linting rule](https://github.com/eslint/eslint/issues/18022)) crash the entire ESLint process over artifacts an application developer has no control over. The problem is that `/* eslint-disable */` merely mutes linting results. | ||
|
||
This directive will work alongside the `.eslintignore` file in that it too will indicate which file be parsed or not. It extends the concept of ignoring source files by allowing files (specifically generated files) to exclude themselves. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The .eslintignore
file is deprecated. All ignores are now in the eslint.config.js
file.
|
||
This directive will work alongside the `.eslintignore` file in that it too will indicate which file be parsed or not. It extends the concept of ignoring source files by allowing files (specifically generated files) to exclude themselves. | ||
|
||
Lastly, library devlopers seldom actually mean "parse, but mute errors" when `/* eslint-disable */` is added at the top of files. While it the best option currently available, "completely skip this file" is actually meant. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious if you have any data to back up this assertion?
In my experience, I don't believe this is true. ESLint will still validate the syntax in this case.
|
||
A more sophisticated algorithm may be chosen at a later point in the lifecycle of this RFC. | ||
|
||
In practice, the imaginary |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please look at the actual source code to determine where changes should be made. This is part of the RFC process.
declare function parseFileImpl(fileContent: string): AST; | ||
``` | ||
|
||
How the rest of the system deals with `null` results from parsing a source file is not in the scope of this RFC. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it is. We need a complete understanding of how such a change would function inside of ESLint.
|
||
How the rest of the system deals with `null` results from parsing a source file is not in the scope of this RFC. | ||
|
||
If an `/* eslint-ignore-file */` directive is encountered while parsing a file, a non-fatal error shall be raised, and the directive shall have no further effect. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought the point was that we wouldn't parse the file? But here you're saying we will in order to find the comment? Can you clarify?
And what does it mean for a non-fatal error to be raised? Do you mean it would be look like a lint violation? Would the user get any output?
|
||
## Documentation | ||
|
||
TBD. The primary audience is a library author. The point **Drawbacks > Bardwards Compatibility** shall be highlighted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please look through our docs and find what would need to be updated.
|
||
Library authors will need to prefix their generated code with both `/* eslint-ignore-file */` and `/* eslint-disable */` directives in order to not break existing projects that have not upgraded their ESLint core to a version that supports the `/* eslint-ignore-file */` directive. Otherwise, updating libraries without updating ESLint accordingly will lead to possible linging errors on generated source files that were previously muted. | ||
|
||
2. Primitive Parser |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would we parse at all? Why not just use a regular expression to see if the text exists in the source?
/* eslint-ignore-file */ | ||
``` | ||
|
||
This is an intentional middleground between keeping the analysis as simple (and fast) as reasonable and correctness, which would require parsing read comments to some degree. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per your motivation, shouldn't the directive always be first in a generated file?
|
||
## Alternatives | ||
|
||
1. As highlighted in **Motivation**, everything described in this RPC is functionally already possible with `.eslintignore` files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is already possible using an ignore file, then why would we add another way to do the same thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that this is no longer possible with a local ignore file and strict unused-directive check is on by default I'd like to revisit this, should I open an new proposal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's possible with ignorePatterns
in a config, which is a replacement for .eslintignore
. Why isn't that sufficient?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's hard to locate and modify the top-level eslint.config.js programmatically for a tool that generates files, but easy to add a directive to the generated file or stick an .eslintignore file next to the files.
Currently tools like TanStack Router generate files in a codebase with ignore directives but eslint 9 makes these less useful because they may trigger unused ignore directive warnings. It'd be useful to 0reserve a way to ignore a file from the file itself that doesn't trigger these unused disable warnings which are now enabled by default.
@jeengbe are you still working on this? There is feedback to address. |
Yes, apologies, no, I completely forgot about this issue. The comments are valid points and I don't have a strong enough commitment to this proposal to advocate for it further. I would also need some help with the internal effect of this change since I do not know how ESLint functions internally. I propose we close this PR unless you think otherwise. |
That sounds good. I think using the current approach of ignoring files is probably the best way to go to address this use case. Thanks for your time and thoughtfulness. |
Summary
A new
/* eslint-ignore-file */
directive that gives files the ability to ignore themselves.Related Issues
related GitHub Issue