-
-
Notifications
You must be signed in to change notification settings - Fork 187
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: support flat config system #592
Conversation
🦋 Changeset detectedLatest commit: 9c45c5d The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Any early input in this one @JounQin? |
Sorry for forgetting this, I'll review recently ASAP. |
Would love to use it as it will be available! @filiptammergard thank you! |
Some new docs on how to migrate to flat config format just came out: https://eslint.org/docs/latest/extend/plugin-migration-flat-config. Did some updates to align with those recommendations. |
@filiptammergard don't stop in your idea to support it) |
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 https://eslint.org/blog/2023/10/flat-config-rollout-plans/
You should also make sure that your rules aren’t using context.parserOptions and context.parserPath. Instead, you should be using context.languageOptions and context.languageOptions.parser, which also work when ESLint is run in eslintrc mode. See our previous post for more information.
Looking at https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/, it seems we need to update our usage of the now-deprecated:
context.getSourceCode
context.getFilename
context.getPhysicalFilename
We will need to identify when the replacements for these functions were added, and update our minimum supported version of eslint accordingly.
Any change to the minimum supported version will be a breaking change (Which is fine, but we'll need to update the changeset).
Good input @BPScott! Looks like the methods you're mentioning are becoming properties (added in v8.40.0): https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/#context-methods-becoming-properties The methods will be removed in ESLint v10 (not v9), so there's no rush here. The blog post also suggests supporting both versions like this: const sourceCode = context.sourceCode ?? context.getSourceCode(); If the property is undefined (as per before ESLint v8.40.0), the method is used instead, and no breaking change needs to be considered. However, I think those changes can be considered separately from supporting flat config format, so I made a separate PR for it: #594 |
@JounQin @BPScott Updated now to avoid mutations and to align with the recommendation to always provide meta information: https://eslint.org/docs/latest/extend/plugin-migration-flat-config#adding-plugin-meta-information I needed to bump Also renamed from |
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.
Thanks for fighting through this!
https://eslint.org/docs/latest/extend/plugin-migration-flat-config#backwards-compatibility makes it seem like it would be totally fine to have both a regular and flat config defined within the configs key of eslint-plugin-prettier.js
instead of needing a whole new file for this.
It seems like it should be possible to add a new "recommended-flat" key to the configs object and define the config there and use it like so, instead of needing to add a new file to the repo:
// in some consuming apps eslint.config.mjs file that is authored in the flat config style
import eslintPluginPrettier from 'eslint-plugin-prettier';
export default [
eslintPluginPrettier.configs['recommended-flat'],
{/* the app's own config goes here */}
]
The linked blogpost suggested having a flat config called "BLAH" and the legacy equivalent is named named "BLAH-legacy". That seems like a nice idea eventually, but I like the idea of of avoiding a backwards compatibility break now by adding a new config that is flat-compatible and leaving the current one as-is. We can swap the names around in some future major version.
Could you please add the new flat compatible config to the configs key in eslint-plugin-prettier.js
with the name"recommended-flat", instead of adding a new entrypoint to the package.
We'll also need to update the README to talk about how to use the flat config, but hold off on that till we are happy with the the implementation and how people would consume it.
@BPScott I think both ways work, and for example But since ESLint recommends doing as you said, I think it might be a good idea to lean on that. The downside with having them in the same file is that I can't reference the plugin from the config like this: const eslintPluginPrettier = {
configs: {
recommended: {
extends: ['prettier'],
plugins: ['prettier'],
rules: {
'prettier/prettier': 'error',
'arrow-body-style': 'off',
'prefer-arrow-callback': 'off',
},
},
'recommended-flat': {
plugins: {
prettier: eslintPluginPrettier, // Error "Block-scoped variable 'eslintPluginPrettier' used before its declaration.ts(2448)"
},
rules: {
'prettier/prettier': 'error',
'arrow-body-style': 'off',
'prefer-arrow-callback': 'off',
},
},
},
rules: {
prettier: {/* ... */},
},
}; That makes Thoughts on this? |
@BPScott I saw you pushed a commit for using |
@JounQin could you please review it? Very important feature |
'prefer-arrow-callback': 'off', | ||
}, | ||
}, | ||
['recommended-flat']: { |
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.
Should we use camelCase 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.
looks like config names should be as rules with dashes also eslint have config naming convention for eslint plugins with dashes too
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 previous rules are for legacy configs, for flat configs, we're using js object reference instead, so camelCase is preferred IMO. And I think flatRecommended
makes more sense than recommendedFlat
.
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.
recommended-flat
is all based on direction from the ESLint team:
Export both eslintrc and flat configs. The configs key is only validated when a config is used, so you can provide both formats of configs in the configs key. We recommend that you append older format configs with -legacy to make it clear that these configs will not be supported in the future. For example, if your primary config is called recommended and is in flat config format, then you can also have a config named recommended-legacy that is the eslintrc config format.
https://eslint.org/docs/latest/extend/plugin-migration-flat-config#backwards-compatibility
They're recommending appending -legacy
for legacy configs (to make it recommended-legacy
for example), which means -flat
is the equivalent. Should we not go for that?
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.
That strategy is an unnecessary breaking change IMO, and it can be made in next major version.
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, that's why the suggestion is to add recommended-flat
now (non-breaking) and swap them around in next major.
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.
My suggestion is to add flatRecommended
config key instead of recommended-flat
.
Ah sorry, I thought I added a comment after pushing up that change at the weekend. I've been thinking about this for the last few days, and now I've had a chance to play with what the eslint suggested approach looks like, I actually kinda hate it. Having to do object reassignment in This PR's original approach of mimicking eslint-plugin-react and creating a new @JounQin I think my previous request of "lets follow eslint recommendations" was a bad idea (well, good for learning what it looks like, bad for actually using), and instead am preferring having the "recommended.js" file that was proposed at the start of this PR. Now you've saw both approaches, do you have on preference on which one feels better? |
In my view I'd like to have a const prettier = require("eslint-plugin-prettier/flat");
module.exports = [
{
// usage 1, use plugin manually
plugins: {
prettier,
},
},
// usage 2, enable rules automatically
prettier.configs.recommended,
]; |
I think "flat plugin" is a bit of a misnomer. Reading https://eslint.org/docs/latest/extend/plugin-migration-flat-config, I get the impression that if we add the const prettier = require("eslint-plugin-prettier");
module.exports = [
{
// usage 1, use plugin manually
plugins: {
prettier,
},
},
]; And then usage 2 can be const prettierRecommended = require("eslint-plugin-prettier/recommended");
module.exports = [
{
...prettierRecommended
},
]; |
@BPScott Fair enough, I'm fine with that approach. |
A suggestion is to bump Sounds good? |
And same for this one: #603 |
I dropped the commit where |
```js | ||
const prettier = require('eslint-plugin-prettier'); | ||
|
||
module.exports = [prettier.configs['recommended-flat']]; |
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.
module.exports = [prettier.configs['recommended-flat']]; | |
module.exports = [prettier.config.flatRecommended]; |
I still recommend this config name.
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.
But even better with a separate flat.js
file, 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.
I don't have such preference, a clear document is enough IMO.
Co-authored-by: JounQin <admin@1stg.me>
Waiting for input by @BPScott on what direction to take before I proceed. I'll vote for using a separate file |
Do you have any input @BPScott? |
I think the deadline could be this weekend, otherwise I'll help to refactor and release in my view. |
Aah sorry I totally missed this and the updates from the eslint discord. I was planning to come back to this PR last week but needing a break got to me. @filiptammergard thank you for pushing on with this, and asking for opinions from the eslint discord. It's great to know that they're not pushing hard on the approach suggested in https://eslint.org/docs/latest/extend/plugin-migration-flat-config. Doing a little audit of other popular plugins:
With three popular packages diverging from the recommendations I don't feel bad about diverging. We have a single rule so we won't ever need multiple configs (ignoring the legacy vs flat distinction) so I think placing that in a configs folder is overkill. The root of the repo is fine and good. I think I still prefer creating a new separate file and usage being I would prefer that new file be named My request is annoyingly "back to what we had originally before I opened my mouth":
|
I've made a the above changes in #616. Notably in contains a rewrite of the readme file's configuration section. |
Resolves #591.
Wanted to open this for review to get some early feedback. This seems to work fine, if I create an
eslint.config.js
in the root with this content:I get ESLint errors accordingly.
The idea here is that the flat config file could be imported this way in other projects:
The reason not to change the main export is that the eslintrc format needs to have continued support. Eslintrc will be deprecated in v9 of ESLint and removed in v10, so to introduce a minimal amount of breaking changes, the flat config support can be purely additive and when ESLint v10 is released, the flat config could be made the main export in a new major version of this plugin.
Thoughts? If you think it's a good approach, I can continue adding documentation add changeset etc.