-
-
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
New: Add resolveRelativeToConfigFile setting #46
Conversation
|
0aaf391
to
3c458ec
Compare
This would not be sufficient for the airbnb config, because users would have to be told to add it as a top-level config. Any solution - temporary or otherwise - must be doable without further action from the user. |
@ljharb If AirBNB is the first config that gets loaded that needs this feature, then the flag will probably get set in time. I can test that and follow up. However given that this is an "experimental" feature, I would prefer to instruct users to copy+paste the option into their top-level eslinrc.js. It is only one extra config line, so that doesn't seem to be a cumbersome requirement, and this makes it explicit that they are using a special resolution mode. For example if one of their dependencies is incompatible, they might not realize that AirBNB had "opted in" behind the scenes. Does that make sense? |
An experimental feature isn’t one that shared configs can risk making a requirement. |
I had been using
So far, no issues with AirBnB package |
That is an extremely strange restriction you're imposing here. An opt-in setting should require no action from the user? That defeats the whole point of opting in.
Shared configs should not make this a requirement, the decision should be left to the end-user whether to opt-in to this feature or not. Users can choose to either set the |
@siric the whole problem that needs solving is that users need to do extra stuff. The solution will only be something that removes that burden - ie, something that the shared config can opt into on its own. |
I feel like there's a difference between copy+pasting That said, @ljharb lemme see if we can support your approach. |
I tested this, and it actually works fine to put I had misremembered the details a bit: ESLint visits extended config files one at a time, collecting options and resolving referenced plugins/configs. It doesn't merge/evaluate the options until the very end. Thus if None of this matters for my intended usage, where @ljharb BTW if you're seriously interested in this feature, could you test the PR branch with your own use case? I'm most interested in hearing about any real-world (versus speculative) situations where the behavior is confusing or incorrect. Thanks! |
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.
Hi. Thank you for your contribution! I really appreciate your work to advance this long-standing issue. But please mind that this problem is not simple and we have more work to land your proposal.
But because that RFC seeks to design a comprehensive solution, its discussion has been open for a long time without encouraging progress.
Because nobody is active to solve that issue currently, rather than seeking a comprehensive solution.
I have a plan to retry my old proposal then solve the problem in the future (after I have finish eslint/eslint#12274, #39, #40, #42, and #45). However, I'm a volunteer and busy in my job, so if you get active to solve this problem, it's really great.
Now, as you know, the plugin loading is the base of the ESLint core, then the change of the plugin loading has many side-effects. And some CLI options affect the plugin loading. This RFC has to describe how your design addresses the side-effects and collaborating with other options.
The most important of my request is "don't be broken silently!" At least, when ESLint encountered unexpected configuration/structure, ESLint must print what happened to users. This is important even if it's "experimental" because users should be able to distinguish what is expected behaviors and what is not.
Let's discuss this.
● What does it happen if two shareable configs depended on different versions of the same plugin?
The reason that ESLint loads plugins from the current working directory is the identification of rules.
plugins:
- foo
rules:
foo/a-rule: error
In the above, ESLint has to identify foo/a-rule
to exactly one rule. This is an essential requirement. However, in your proposal, shareable configs can have own version of plugins. What does it happen if two shareable configs depended on different versions of the same plugin? (please mind "don't be broken silently!")
● What does it happen if config files that are in subdirectories have resolveRelativeToConfigFile
option?
ESLint merges multiple config files in ancestor directories. For example, if the following file structure existed,
<root>
├ src
│ └ foo.js
├ test
│ ├ foo.js
│ └ .eslintrc.yml
└ .eslintrc.yml
ESLint merges test/.eslintrc.yml
and ./.eslintrc.yml
when it lints test/foo.js
. At the time, ESLint reuses the parsed result of ./.eslintrc.yml
with the linting of src/foo.js
. Is there a mix of two plugin loading strategy? (please mind "don't be broken silently!")
● What does it happen if plugin configs have resolveRelativeToConfigFile
option?
Plugin configs can have shared configs.
extends: "plugin:foo/recommended"
If the plugin config has the resolveRelativeToConfigFile
option, what does it happen? Is there a mix of two plugin loading strategy? (please mind "don't be broken silently!")
● What does it happen if --resolve-plugins-relative-to
option along with resolveRelativeToConfigFile
option?
If --resolve-plugins-relative-to
is present and a config has the resolveRelativeToConfigFile
option, what does it happen? (please mind "don't be broken silently!")
On the whole, I feel that the option should not be in config files. Similar to --resolve-plugins-relative-to
CLI option, it should be a CLI option. And it should throw fatal errors on plugin conflictions.
|
||
## Alternatives | ||
|
||
If RFC #14 can be completed and implemented within a reasonable timeframe, then this workaround would not be needed. |
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'd like to see more details of the "Alternative" section.
I have described four alternatives and there are multiple proposals around this: #5, #9, a part of #7, #14, a derivation of #14.
Please describe the pros and cons of this proposal that are relative to those.
|
||
## Open Questions | ||
|
||
Since a PR has already been created, please provide feedback on the implementation details. |
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.
No. The place to discuss design is here.
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.
🤔 design != implementation, right?
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's not clear how the implementation change affects user-facing behavior. Even if the change is one line, it may be many side-effects. The purpose of RFCs is to clarify how the proposed changes ESLint from the user's perspective. Then the "Open Questions" section describes the open questions about design decisions.
@mysticatea Thanks for your feedback! The answer to all those what-if questions is "Nobody wants to do that. It's not supported with this workaround. We should report an error." But let me think about the individual questions and see how easy it is to implement error reporting.
I might consider this, but let's first focus on getting people unblocked ASAP. The full solution will probably be a breaking change, so if it gets implemented it should wait and ship with a major release of ESLint.
@mysticatea In my view ESLint has a very problematic reliance on CLI options. This topic probably warrants its own RFC, but let me try to summarize it here, since you brought it up. Consider these options which (as far as I understand) can only be specified using CLI parameters:
If you want to lint all the files in your project, you can't do it without knowing this information. Now, what happens when I open VS Code in the project folder? The ESLint add-in reads But how is VS Code supposed to find the All this awkwardness would go away if ESLint allowed important config information to be stored in the config file, rather than insisting on passing it via CLI. |
(The |
OK. Therefore, would you update RFC with the decision? Please keep mind to describe user-facing behaviors rather than implementation. I feel the current "Detailed Design" section describes implementation rather than specification. The implementation is worthful to confirm feasibility, but it should be an appendix. The goal of RFCs is to clarify what user-facing changes are. I think we need the following stuff.
I don't think the current implementation has enough quality for public beta. I think that the goal of the public beta is to find potential problems. However, the current spec/implementation has many problems clearly and it's too early to advance. Also, this proposal doesn't look to need a major release.
I know. Therefore, we have been reducing the settings that config files cannot configure. For example, #20 lets us configure additional kinds of files (similar However, there are some options that we cannot set in config files. One is the setting that changes how ESLint loads config files. We cannot change the loading strategy of config files by the config files because we must decide the loading strategy before loading config files. The |
This is stated as a requirement, but it's not. It's just a technical hitch that we need to hack around (until the temporary setting is no longer needed). The requirement is: "ESLint users need to opt-in to a different loading strategy, and it must be specified in eslintrc." Otherwise, editors can't discover the setting easily (far as I can tell), which is not the experience we want.
Can anyone step forward and say: "Here is a real world project where I tried to use So far the objections seem to be mostly speculations. |
I would love to have the ability to control the loader. For us, there is no magic, it had been |
What if we drop @ljharb's requirement about the We could say that You gave this example:
Is it always easy to identify the root-level If we impose this constraint, it would eliminate all the concerns about mixed loading strategies. To further harden things, we could also provide a way for a package like
....and then ESLint would report an error if someone tries to load Then your design questions are really easy to answer:
Error.
Error.
Error.
Error.
Error. |
Unlike TSLint, ESLint doesn't trust plugin authors to avoid naming collisions. For example, if This means you can't simply use NodeJS This is solvable, but not without a major redesign of the config file loader. Frankly the world would be much simpler if ESLint reported an error when two plugins try to use the same name, rather than inventing a complex disambiguation that produces very long rule names. |
And we are fine with it, we decide to opt-in for those issues as long as it means we remove 7+ dependencies per package, the maintains burden is too much as the organization grows. It is better for us to rely on our organization config to figure out these edge-cases in one place. |
That's a requirement. Or, it's a technical constraint. If we ignore this constraint, ESLint will enter infinite looping in some situations or just go broken. It will be called a spec bug.
It's a fortune. They had not encountered the spec bug.
It sounds like our good common ground. But we need another mechanism to realize it. Because we cannot determine the first
No. In This is the reason that #22 didn't bring some CLI options to config files. If we want to determine the top-level config file, we have to add the setting that disables config files of subdirectories. And I thought that the setting should be discussed in another RFC than #22 to land #22 ASAP. As you may have noticed, changing the loading strategy is not a simple way. It conflicts with many other parts of ESLint. Even if we solved the problem of the loading strategy mix, there is one more matter. Instead, would you consider another simple way? I think that either |
@mysticatea Ok cool, lemme take some time this weekend to read all those issues and think about it. These are some good insights. (BTW looks like you are in Japan. I will be in Tokyo later this month. If it's not far away possibly we could meet up and chat about the broader design. 🙂) |
Yes, I live in Japan. I can go to Tokyo on a weekend. But... I cannot listen to English in most. My English ability is poor that I cannot act on GitHub without Google Translate. 😅 |
I'm closing this RFC and the associated PR. We ultimately decided to publish our workaround as an NPM package, rather than trying to integrate it into ESLint. You can find it here: @rushstack/eslint-patch Thanks all! |
Summary
RFC #14 proposes a way for a shared ESLint config package to supply its own plugin dependencies, rather than imposing that responsibility on every consumer of the package. But because that RFC seeks to design a comprehensive solution, its discussion has been open for a long time without encouraging progress. In the interim, RFC 46 proposes a temporary workaround. It will allow users to opt-in to a resolution behavior that works well in practice (despite having some known limitations). This this new
resolveRelativeToConfigFile
option would be designated as experimental, with the intent to remove it when/if the ideal solution finally ships.Related Issues