Skip to content

Commit ca12911

Browse files
michaelfaithpoteto
andauthored
feat(eslint-plugin-react-hooks): make flat config the recommended config (#32457)
This change swaps which config `recommended` is aliasing. In 5.2.0, the new flat config was introduced as `recommended-latest`, while `recommended` still pointed at the legacy rc-based config, with a note that in the next major version `recommended` would be updated to point at `recommend-latest`. This change makes that swap, and make the default `recommended` experience the flat config. To continue using the legacy rc recommended config, please make the following change in your config ```diff - extends: ['plugin:react-hooks/recommended'] + extends: ['plugin:react-hooks/recommended-legacy'] ``` This change also deprecates `recommended-latest` in favor of `recommended`. `recommended-latest` will be removed in a future major version. The README has been updated to reflect the new usage, and to put the flat config sections before the legacy config sections. I also took the opportunity to change the v9 fixture to use a typescript config, serving as a demonstration for usage as well as a way to validate the types are correct. BREAKING CHANGE --------- Co-authored-by: lauren <poteto@users.noreply.github.com>
1 parent d55cc79 commit ca12911

File tree

6 files changed

+91
-91
lines changed

6 files changed

+91
-91
lines changed

fixtures/eslint-v9/eslint.config.mjs renamed to fixtures/eslint-v9/eslint.config.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type {Linter} from 'eslint';
12
import * as reactHooks from 'eslint-plugin-react-hooks';
23

34
export default [
@@ -12,10 +13,10 @@ export default [
1213
},
1314
},
1415
},
15-
reactHooks.configs['recommended-latest'],
16+
reactHooks.configs['recommended'],
1617
{
1718
rules: {
1819
'react-hooks/exhaustive-deps': 'error',
1920
},
2021
},
21-
];
22+
] satisfies Linter.Config[];

fixtures/eslint-v9/package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
"private": true,
33
"name": "eslint-v9",
44
"dependencies": {
5-
"eslint": "^9",
6-
"eslint-plugin-react-hooks": "link:../../build/oss-stable/eslint-plugin-react-hooks"
5+
"eslint": "^9.18.0",
6+
"eslint-plugin-react-hooks": "link:../../build/oss-stable/eslint-plugin-react-hooks",
7+
"jiti": "^2.4.2"
78
},
89
"scripts": {
910
"build": "node build.mjs && yarn",

fixtures/eslint-v9/tsconfig.json

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
{
2+
}

fixtures/eslint-v9/yarn.lock

+37-39
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0"
1515
integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==
1616

17-
"@eslint/config-array@^0.19.0":
17+
"@eslint/config-array@^0.19.2":
1818
version "0.19.2"
1919
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.2.tgz#3060b809e111abfc97adb0bb1172778b90cb46aa"
2020
integrity sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==
@@ -23,24 +23,17 @@
2323
debug "^4.3.1"
2424
minimatch "^3.1.2"
2525

26-
"@eslint/core@^0.10.0":
27-
version "0.10.0"
28-
resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.10.0.tgz#23727063c21b335f752dbb3a16450f6f9cbc9091"
29-
integrity sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==
26+
"@eslint/core@^0.12.0":
27+
version "0.12.0"
28+
resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.12.0.tgz#5f960c3d57728be9f6c65bd84aa6aa613078798e"
29+
integrity sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==
3030
dependencies:
3131
"@types/json-schema" "^7.0.15"
3232

33-
"@eslint/core@^0.11.0":
34-
version "0.11.0"
35-
resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.11.0.tgz#7a9226e850922e42cbd2ba71361eacbe74352a12"
36-
integrity sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==
37-
dependencies:
38-
"@types/json-schema" "^7.0.15"
39-
40-
"@eslint/eslintrc@^3.2.0":
41-
version "3.2.0"
42-
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c"
43-
integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==
33+
"@eslint/eslintrc@^3.3.0":
34+
version "3.3.0"
35+
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.0.tgz#96a558f45842989cca7ea1ecd785ad5491193846"
36+
integrity sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==
4437
dependencies:
4538
ajv "^6.12.4"
4639
debug "^4.3.2"
@@ -52,22 +45,22 @@
5245
minimatch "^3.1.2"
5346
strip-json-comments "^3.1.1"
5447

55-
"@eslint/js@9.20.0":
56-
version "9.20.0"
57-
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.20.0.tgz#7421bcbe74889fcd65d1be59f00130c289856eb4"
58-
integrity sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==
48+
"@eslint/js@9.21.0":
49+
version "9.21.0"
50+
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.21.0.tgz#4303ef4e07226d87c395b8fad5278763e9c15c08"
51+
integrity sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==
5952

6053
"@eslint/object-schema@^2.1.6":
6154
version "2.1.6"
6255
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f"
6356
integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==
6457

65-
"@eslint/plugin-kit@^0.2.5":
66-
version "0.2.5"
67-
resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz#ee07372035539e7847ef834e3f5e7b79f09e3a81"
68-
integrity sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==
58+
"@eslint/plugin-kit@^0.2.7":
59+
version "0.2.7"
60+
resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz#9901d52c136fb8f375906a73dcc382646c3b6a27"
61+
integrity sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==
6962
dependencies:
70-
"@eslint/core" "^0.10.0"
63+
"@eslint/core" "^0.12.0"
7164
levn "^0.4.1"
7265

7366
"@humanfs/core@^0.19.1":
@@ -93,10 +86,10 @@
9386
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a"
9487
integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==
9588

96-
"@humanwhocodes/retry@^0.4.1":
97-
version "0.4.1"
98-
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b"
99-
integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==
89+
"@humanwhocodes/retry@^0.4.2":
90+
version "0.4.2"
91+
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.2.tgz#1860473de7dfa1546767448f333db80cb0ff2161"
92+
integrity sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==
10093

10194
"@types/estree@^1.0.6":
10295
version "1.0.6"
@@ -231,21 +224,21 @@ eslint-visitor-keys@^4.2.0:
231224
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45"
232225
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
233226

234-
eslint@^9:
235-
version "9.20.1"
236-
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.20.1.tgz#923924c078f5226832449bac86662dd7e53c91d6"
237-
integrity sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==
227+
eslint@^9.18.0:
228+
version "9.21.0"
229+
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.21.0.tgz#b1c9c16f5153ff219791f627b94ab8f11f811591"
230+
integrity sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==
238231
dependencies:
239232
"@eslint-community/eslint-utils" "^4.2.0"
240233
"@eslint-community/regexpp" "^4.12.1"
241-
"@eslint/config-array" "^0.19.0"
242-
"@eslint/core" "^0.11.0"
243-
"@eslint/eslintrc" "^3.2.0"
244-
"@eslint/js" "9.20.0"
245-
"@eslint/plugin-kit" "^0.2.5"
234+
"@eslint/config-array" "^0.19.2"
235+
"@eslint/core" "^0.12.0"
236+
"@eslint/eslintrc" "^3.3.0"
237+
"@eslint/js" "9.21.0"
238+
"@eslint/plugin-kit" "^0.2.7"
246239
"@humanfs/node" "^0.16.6"
247240
"@humanwhocodes/module-importer" "^1.0.1"
248-
"@humanwhocodes/retry" "^0.4.1"
241+
"@humanwhocodes/retry" "^0.4.2"
249242
"@types/estree" "^1.0.6"
250243
"@types/json-schema" "^7.0.15"
251244
ajv "^6.12.4"
@@ -399,6 +392,11 @@ isexe@^2.0.0:
399392
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
400393
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
401394

395+
jiti@^2.4.2:
396+
version "2.4.2"
397+
resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.4.2.tgz#d19b7732ebb6116b06e2038da74a55366faef560"
398+
integrity sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==
399+
402400
js-yaml@^4.1.0:
403401
version "4.1.0"
404402
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"

packages/eslint-plugin-react-hooks/README.md

+29-30
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,22 @@ npm install eslint-plugin-react-hooks --save-dev
1818
yarn add eslint-plugin-react-hooks --dev
1919
```
2020

21+
### Flat Config (eslint.config.js|ts)
22+
23+
For [ESLint 9.0.0 and above](https://eslint.org/blog/2024/04/eslint-v9.0.0-released/), add the `recommended` config.
24+
25+
```js
26+
import * as reactHooks from 'eslint-plugin-react-hooks';
27+
28+
export default [
29+
// ...
30+
reactHooks.configs['recommended'],
31+
];
32+
```
33+
2134
### Legacy Config (.eslintrc)
2235

23-
If you are still using ESLint below 9.0.0, please continue to use `recommended-legacy`. To avoid breaking changes, we still support `recommended` as well, but note that this will be changed to alias the flat recommended config in v6.
36+
If you are still using ESLint below 9.0.0, you can use `recommended-legacy` for accessing the recommended config.
2437

2538
```js
2639
{
@@ -31,25 +44,29 @@ If you are still using ESLint below 9.0.0, please continue to use `recommended-l
3144
}
3245
```
3346

34-
### Flat Config (eslint.config.js)
47+
### Custom Configuration
3548

36-
For [ESLint 9.0.0 and above](https://eslint.org/blog/2024/04/eslint-v9.0.0-released/) users, add the `recommended-latest` config.
49+
If you want more fine-grained configuration, you can instead add a snippet like this to your ESLint configuration file:
50+
51+
#### Flat Config (eslint.config.js|ts)
3752

3853
```js
3954
import * as reactHooks from 'eslint-plugin-react-hooks';
4055

4156
export default [
42-
// ...
43-
reactHooks.configs['recommended-latest'],
57+
{
58+
files: ['**/*.{js,jsx}'],
59+
plugins: { 'react-hooks': reactHooks },
60+
// ...
61+
rules: {
62+
'react-hooks/rules-of-hooks': 'error',
63+
'react-hooks/exhaustive-deps': 'warn',
64+
}
65+
},
4466
];
4567
```
4668

47-
### Custom Configuration
48-
49-
If you want more fine-grained configuration, you can instead add a snippet like this to your ESLint configuration file:
50-
5169
#### Legacy Config (.eslintrc)
52-
5370
```js
5471
{
5572
"plugins": [
@@ -64,35 +81,17 @@ If you want more fine-grained configuration, you can instead add a snippet like
6481
}
6582
```
6683

67-
#### Flat Config (eslint.config.js)
68-
69-
```js
70-
import * as reactHooks from 'eslint-plugin-react-hooks';
71-
72-
export default [
73-
{
74-
files: ['**/*.{js,jsx}'],
75-
plugins: { 'react-hooks': reactHooks },
76-
// ...
77-
rules: {
78-
'react-hooks/rules-of-hooks': 'error',
79-
'react-hooks/exhaustive-deps': 'warn',
80-
}
81-
},
82-
];
83-
```
84-
8584
## Advanced Configuration
8685

8786
`exhaustive-deps` can be configured to validate dependencies of custom Hooks with the `additionalHooks` option.
8887
This option accepts a regex to match the names of custom Hooks that have dependencies.
8988

9089
```js
9190
{
92-
"rules": {
91+
rules: {
9392
// ...
9493
"react-hooks/exhaustive-deps": ["warn", {
95-
"additionalHooks": "(useMyCustomHook|useMyOtherCustomHook)"
94+
additionalHooks: "(useMyCustomHook|useMyOtherCustomHook)"
9695
}]
9796
}
9897
}

packages/eslint-plugin-react-hooks/src/index.ts

+17-18
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,16 @@ const configRules = {
2020
'react-hooks/exhaustive-deps': 'warn',
2121
} satisfies Linter.RulesRecord;
2222

23-
// Legacy config
24-
const legacyRecommendedConfig = {
25-
plugins: ['react-hooks'],
23+
// Flat config
24+
const recommendedConfig = {
25+
name: 'react-hooks/recommended',
26+
plugins: {
27+
get 'react-hooks'(): ESLint.Plugin {
28+
return plugin;
29+
},
30+
},
2631
rules: configRules,
27-
} satisfies Linter.LegacyConfig;
32+
};
2833

2934
// Plugin object
3035
const plugin = {
@@ -34,24 +39,18 @@ const plugin = {
3439
rules,
3540
configs: {
3641
/** Legacy recommended config, to be used with rc-based configurations */
37-
'recommended-legacy': legacyRecommendedConfig,
42+
'recommended-legacy': {
43+
plugins: ['react-hooks'],
44+
rules: configRules,
45+
},
3846

3947
/**
40-
* 'recommended' is currently aliased to the legacy / rc recommended config) to maintain backwards compatibility.
41-
* This is deprecated and in v6, it will switch to alias the flat recommended config.
48+
* Recommended config, to be used with flat configs.
4249
*/
43-
recommended: legacyRecommendedConfig,
50+
recommended: recommendedConfig,
4451

45-
/** Latest recommended config, to be used with flat configurations */
46-
'recommended-latest': {
47-
name: 'react-hooks/recommended',
48-
plugins: {
49-
get 'react-hooks'(): ESLint.Plugin {
50-
return plugin;
51-
},
52-
},
53-
rules: configRules,
54-
},
52+
/** @deprecated please use `recommended`; will be removed in v7 */
53+
'recommended-latest': recommendedConfig,
5554
},
5655
} satisfies ESLint.Plugin;
5756

0 commit comments

Comments
 (0)