Repository navigation
feat!: migrate to ESLint 10 native flat config #95
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
Open
uPaymeiFixit
wants to merge
22
commits into
main
Choose a base branch
from
feat/eslint-10-flat-config
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
5a2af35
⬆️ eslint 10 toolchain: manifests to ESM + exports maps, peer eslint …
uPaymeiFixit 3993dee
♻️ eslint-plugin-nest: flat-first configs, ESM, retarget no-barreling…
uPaymeiFixit cc3c50b
♻️ rewrite all 10 eslint config packages as ESLint 10 flat configs
uPaymeiFixit 5a74b3d
♻️ repo self-lint on flat config: eslint.config.mjs per root/package,…
uPaymeiFixit 23487d3
♻️ test harness + package tests on flat config ESLint 10
uPaymeiFixit 5ae0927
🐛 scope typescript-eslint's eslint-recommended disables to TS files only
uPaymeiFixit 30251cc
♻️ create-configs emits eslint.config.mjs
uPaymeiFixit 87178e4
👷 CI: node 20.19/22/24 test matrix + scaffolder e2e smoke job
uPaymeiFixit 02f1c7f
📝 docs for the v3 flat-config line: migration guide, README snippets,…
uPaymeiFixit 88f9295
🐛 build eslint-plugin-nest before the workspaces that import it
uPaymeiFixit 9c1e95c
⏪ revert changes outside the ESLint migration's scope
uPaymeiFixit e434c1a
⬆️ rebuild the lockfile incrementally from main's
uPaymeiFixit 8bbfb05
♻️ restore the original package layout and export configs by name
uPaymeiFixit 6668a91
🐛 re-apply the testing override to all of utils' test globs
uPaymeiFixit 5d5bd87
🐛 stop tracking the remaining tsbuildinfo build state
uPaymeiFixit 9ea9ff9
🐛 keep typescript-eslint out of single-run mode in tests
uPaymeiFixit ac7cd48
🐛 no-barreling: only delete the `export *` declarations
uPaymeiFixit b711e47
🐛 put each test/lenient relaxation in the package that owns the rule
uPaymeiFixit d1a1df0
✨ create-configs carries local eslintrc settings into eslint.config.mjs
uPaymeiFixit 91af996
👷 publish prereleases under the `next` dist-tag
uPaymeiFixit 9f88e63
✨ export the typescript & jest configs' file globs; document customizing
uPaymeiFixit 97e4722
🐛 create-configs: fix verify_missing's delete race and ignored results
uPaymeiFixit File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,3 +11,4 @@ code-style-*-*.*.*.tgz | |
|
|
||
| # caches | ||
| .eslintcache | ||
| *.tsbuildinfo | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Customizing the ESLint configs | ||
|
|
||
| Add your own changes after the `@code-style` configs in your `eslint.config.mjs`. Later configs win. | ||
|
|
||
| ```js | ||
| import { defineConfig, globalIgnores } from 'eslint/config'; | ||
|
|
||
| import { config as base } from '@code-style/eslint-config'; | ||
| import { config as node } from '@code-style/eslint-config-node'; | ||
| import { | ||
| config as typescript, | ||
| files as typescript_files, | ||
| } from '@code-style/eslint-config-typescript'; | ||
|
|
||
| export default defineConfig( | ||
| globalIgnores(['generated/']), | ||
| base, | ||
| node, | ||
| typescript, | ||
| { | ||
| rules: { | ||
| 'max-lines': ['error', { max: 500 }], | ||
| }, | ||
| }, | ||
| { | ||
| files: typescript_files, | ||
| rules: { | ||
| '@typescript-eslint/no-explicit-any': 'warn', | ||
| }, | ||
| }, | ||
| ); | ||
| ``` | ||
|
|
||
| - **Scope changes to `@typescript-eslint/*` and `jest/*` rules with the config's `files`.** `@code-style/eslint-config-typescript` and `@code-style/eslint-config-jest` only load their plugins for the files they lint, so changing one of their rules for every file fails with `Could not find plugin`. Both packages export their `files`. Turning a rule `'off'` works without them. | ||
| - **Setting only a severity keeps the rule's options, but setting options replaces all of them.** `'max-lines': 'warn'` keeps `max: 2000`, while `['error', { max: 500 }]` also drops `skipBlankLines` and `skipComments`, so restate any options you want to keep. | ||
| - **Order matters.** Put each `/lenient` config right after the config it relaxes, and `@code-style/eslint-config-esmodule` after `@code-style/eslint-config-node`. [create-configs](../packages/create-configs/README.md) writes them in the right order. | ||
| - **To find where a rule's setting comes from**, run `npx eslint --inspect-config`. Each config is named after its package (eg: `@code-style/eslint-config/rule-sets/footguns`). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # Migrating from v2 to v3 | ||
|
|
||
| v3 replaces the `.eslintrc` configs with [flat configs](https://eslint.org/docs/latest/use/configure/configuration-files) for **ESLint 10**, which requires Node `^20.19.0 || ^22.13.0 || >=24`. | ||
|
|
||
| The easiest way to migrate is to re-run [create-configs](../packages/create-configs/README.md) with `overwrite` enabled. It replaces your `.eslintrc` & `.eslintignore` with an `eslint.config.mjs`, carrying over your rules, ignore patterns, and overrides' rules. It warns about any other settings (eg: `env`), which you'll need to add yourself. | ||
|
|
||
| To migrate by hand: | ||
|
|
||
| 1. Replace your `.eslintrc.yaml` with an `eslint.config.mjs` that layers the same configs in the same order. | ||
|
|
||
| ```js | ||
| import { defineConfig } from 'eslint/config'; | ||
|
|
||
| import { config as base } from '@code-style/eslint-config'; | ||
| import { config as node } from '@code-style/eslint-config-node'; | ||
| import { config as node_lenient } from '@code-style/eslint-config-node/lenient'; | ||
|
|
||
| export default defineConfig(base, node, node_lenient); | ||
| ``` | ||
|
|
||
| 1. Move any `.eslintignore` patterns into `globalIgnores([...])` from `eslint/config`. | ||
| 1. Install `eslint` as a dev dependency, and remove `@rushstack/eslint-patch`, `@types/eslint`, `eslint-plugin-import`, `@typescript-eslint/eslint-plugin`, and `@typescript-eslint/parser`. | ||
| 1. Remove `--ext` from your `eslint` scripts. | ||
|
|
||
| `eslint-plugin-react` and `eslint-plugin-jsx-a11y` don't yet declare ESLint 10 support, so if you use `@code-style/eslint-config-react`, add the following to your `package.json`: | ||
|
|
||
| ```json | ||
| "overrides": { | ||
| "eslint-plugin-react": { "eslint": "$eslint" }, | ||
| "eslint-plugin-jsx-a11y": { "eslint": "$eslint" } | ||
| } | ||
| ``` |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import { defineConfig, globalIgnores } from 'eslint/config'; | ||
|
|
||
| import { config as base } from '@code-style/eslint-config'; | ||
| import { config as node } from '@code-style/eslint-config-node'; | ||
| import { config as cli } from '@code-style/eslint-config-cli'; | ||
| import { config as jest } from '@code-style/eslint-config-jest'; | ||
| import { config as typescript } from '@code-style/eslint-config-typescript'; | ||
| import { config as esmodule } from '@code-style/eslint-config-esmodule'; | ||
|
|
||
| export default defineConfig( | ||
| globalIgnores([ | ||
| '.prettierrc.mjs', | ||
| '**/test/*/**', | ||
| // these packages lint themselves with their own eslint.config.mjs | ||
| 'packages/code-style/', | ||
| 'packages/create-configs/', | ||
| 'packages/eslint-config/', | ||
| 'packages/eslint-config-typescript/', | ||
| 'packages/eslint-plugin-nest/', | ||
| 'packages/jest-configs/', | ||
| 'utils/', | ||
| ]), | ||
| base, | ||
| node, | ||
| cli, | ||
| jest, | ||
| typescript, | ||
| esmodule, | ||
| ); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Maybe we should add a migration script to automate this
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.
Agreed. create-configs already does most of it: re-running it with
overwritewriteseslint.config.mjsand removes the old.eslintrc*and.eslintignore. The gap is rules you've added to your own.eslintrc.yaml, which it drops. I'd rather teach create-configs to carry those over than add a separate script, but I'll do that in a follow-up so this PR stays focused. I've also cut this doc down to just the steps (8bbfb05).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.
Update: done in create-configs instead of a separate script. When
overwritereplaces an old.eslintrc, it now carries over the project's rules, ignore patterns, overrides' rules, and.eslintignoreintoeslint.config.mjs, and warns about anything it can't migrate (eg:env) (d1a1df0).