[eprh] Prepare for 7.0.0 (#34757)

For 7.0.0:

Slim down presets to just 2 configurations:

- `recommended`: legacy and flat config with all recommended rules, and
- `recommended-latest`: legacy and flat config with all recommended
rules plus new bleeding edge experimental compiler rules

Removed:
- `recommended-latest-legacy`
- `flat/recommended`

Please see the README for new install instructions.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34757).
* #34783
* #34782
* __->__ #34757
This commit is contained in:
lauren 2025-10-08 15:17:31 -04:00 committed by GitHub
parent 9724e3e66e
commit 7568e71854
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 60 additions and 74 deletions

View File

@ -33,7 +33,7 @@ const canaryChannelLabel = 'canary';
const rcNumber = 0; const rcNumber = 0;
const stablePackages = { const stablePackages = {
'eslint-plugin-react-hooks': '6.2.0', 'eslint-plugin-react-hooks': '7.0.0',
'jest-react': '0.18.0', 'jest-react': '0.18.0',
react: ReactVersion, react: ReactVersion,
'react-art': ReactVersion, 'react-art': ReactVersion,

View File

@ -1,6 +1,6 @@
{ {
"root": true, "root": true,
"extends": ["plugin:react-hooks/recommended-latest-legacy"], "extends": ["plugin:react-hooks/recommended"],
"parserOptions": { "parserOptions": {
"ecmaVersion": 2020, "ecmaVersion": 2020,
"sourceType": "module", "sourceType": "module",

View File

@ -1,6 +1,6 @@
{ {
"root": true, "root": true,
"extends": ["plugin:react-hooks/recommended-latest-legacy"], "extends": ["plugin:react-hooks/recommended"],
"parserOptions": { "parserOptions": {
"ecmaVersion": 2020, "ecmaVersion": 2020,
"sourceType": "module", "sourceType": "module",

View File

@ -1,6 +1,6 @@
{ {
"root": true, "root": true,
"extends": ["plugin:react-hooks/recommended-latest-legacy"], "extends": ["plugin:react-hooks/recommended"],
"parserOptions": { "parserOptions": {
"ecmaVersion": 2020, "ecmaVersion": 2020,
"sourceType": "module", "sourceType": "module",

View File

@ -1,3 +1,9 @@
## 7.0.0
This release slims down presets to just 2 configurations (`recommended` and `recommended-latest`), and all compiler rules are enabled by default.
- **Breaking:** Removed `recommended-latest-legacy` and `flat/recommended` configs. The plugin now provides `recommended` (legacy and flat configs with all recommended rules), and `recommended-latest` (legacy and flat configs with all recommended rules plus new bleeding edge experimental compiler rules). ([@poteto](https://github.com/poteto) in [#34757](https://github.com/facebook/react/pull/34757))
## 6.1.1 ## 6.1.1
**Note:** 6.1.0 accidentally allowed use of `recommended` without flat config, causing errors when used with ESLint v9's `defineConfig()` helper. This has been fixed in 6.1.1. **Note:** 6.1.0 accidentally allowed use of `recommended` without flat config, causing errors when used with ESLint v9's `defineConfig()` helper. This has been fixed in 6.1.1.

View File

@ -4,8 +4,6 @@ The official ESLint plugin for [React](https://react.dev) which enforces the [Ru
## Installation ## Installation
**Note: If you're using Create React App, please use `react-scripts` >= 3 instead of adding it directly.**
Assuming you already have ESLint installed, run: Assuming you already have ESLint installed, run:
```sh ```sh
@ -18,9 +16,7 @@ yarn add eslint-plugin-react-hooks --dev
### Flat Config (eslint.config.js|ts) ### Flat Config (eslint.config.js|ts)
#### >= 6.0.0 Add the `recommended` config for all recommended rules:
For users of 6.0 and beyond, add the `recommended` config.
```js ```js
// eslint.config.js // eslint.config.js
@ -28,61 +24,32 @@ import reactHooks from 'eslint-plugin-react-hooks';
import { defineConfig } from 'eslint/config'; import { defineConfig } from 'eslint/config';
export default defineConfig([ export default defineConfig([
{ reactHooks.configs.flat.recommended,
files: ["src/**/*.{js,jsx,ts,tsx}"],
plugins: {
'react-hooks': reactHooks,
},
extends: ['react-hooks/recommended'],
},
]); ]);
``` ```
#### 5.2.0 If you want to try bleeding edge experimental compiler rules, use `recommended-latest`.
For users of 5.2.0 (the first version with flat config support), add the `recommended-latest` config.
```js ```js
// eslint.config.js
import reactHooks from 'eslint-plugin-react-hooks'; import reactHooks from 'eslint-plugin-react-hooks';
import { defineConfig } from 'eslint/config'; import { defineConfig } from 'eslint/config';
export default defineConfig([ export default defineConfig([
{ reactHooks.configs.flat['recommended-latest'],
files: ["src/**/*.{js,jsx,ts,tsx}"],
plugins: {
'react-hooks': reactHooks,
},
extends: ['react-hooks/recommended-latest'],
},
]); ]);
``` ```
### Legacy Config (.eslintrc) ### Legacy Config (.eslintrc)
#### >= 5.2.0 If you are still using ESLint below 9.0.0, the `recommended` preset can also be used to enable all recommended rules.
If you are still using ESLint below 9.0.0, you can use `recommended-legacy` for accessing a legacy version of the recommended config.
```js ```js
{ {
"extends": [ "extends": ["plugin:react-hooks/recommended"],
// ... // ...
"plugin:react-hooks/recommended-legacy"
]
} }
```
#### < 5.2.0
If you're using a version earlier than 5.2.0, the legacy config was simply `recommended`.
```js
{
"extends": [
// ...
"plugin:react-hooks/recommended"
]
}
``` ```
### Custom Configuration ### Custom Configuration
@ -92,7 +59,7 @@ If you want more fine-grained configuration, you can instead choose to enable sp
#### Flat Config (eslint.config.js|ts) #### Flat Config (eslint.config.js|ts)
```js ```js
import * as reactHooks from 'eslint-plugin-react-hooks'; import reactHooks from 'eslint-plugin-react-hooks';
export default [ export default [
{ {
@ -100,8 +67,26 @@ export default [
plugins: { 'react-hooks': reactHooks }, plugins: { 'react-hooks': reactHooks },
// ... // ...
rules: { rules: {
// Core hooks rules
'react-hooks/rules-of-hooks': 'error', 'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn', 'react-hooks/exhaustive-deps': 'warn',
// React Compiler rules
'react-hooks/config': 'error',
'react-hooks/error-boundaries': 'error',
'react-hooks/component-hook-factories': 'error',
'react-hooks/gating': 'error',
'react-hooks/globals': 'error',
'react-hooks/immutability': 'error',
'react-hooks/preserve-manual-memoization': 'error',
'react-hooks/purity': 'error',
'react-hooks/refs': 'error',
'react-hooks/set-state-in-effect': 'error',
'react-hooks/set-state-in-render': 'error',
'react-hooks/static-components': 'error',
'react-hooks/unsupported-syntax': 'warn',
'react-hooks/use-memo': 'error',
'react-hooks/incompatible-library': 'warn',
} }
}, },
]; ];
@ -116,8 +101,26 @@ export default [
], ],
"rules": { "rules": {
// ... // ...
// Core hooks rules
"react-hooks/rules-of-hooks": "error", "react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn" "react-hooks/exhaustive-deps": "warn",
// React Compiler rules
"react-hooks/config": "error",
"react-hooks/error-boundaries": "error",
"react-hooks/component-hook-factories": "error",
"react-hooks/gating": "error",
"react-hooks/globals": "error",
"react-hooks/immutability": "error",
"react-hooks/preserve-manual-memoization": "error",
"react-hooks/purity": "error",
"react-hooks/refs": "error",
"react-hooks/set-state-in-effect": "error",
"react-hooks/set-state-in-render": "error",
"react-hooks/static-components": "error",
"react-hooks/unsupported-syntax": "warn",
"react-hooks/use-memo": "error",
"react-hooks/incompatible-library": "warn"
} }
} }
``` ```

View File

@ -1,7 +1,7 @@
{ {
"name": "eslint-plugin-react-hooks", "name": "eslint-plugin-react-hooks",
"description": "ESLint rules for React Hooks", "description": "ESLint rules for React Hooks",
"version": "5.2.0", "version": "7.0.0",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/facebook/react.git", "url": "https://github.com/facebook/react.git",

View File

@ -44,55 +44,32 @@ const allRuleConfigs: Linter.RulesRecord = {
const plugins = ['react-hooks']; const plugins = ['react-hooks'];
type ReactHooksFlatConfig = { type ReactHooksFlatConfig = {
plugins: Record<string, any>; plugins: {react: any};
rules: Linter.RulesRecord; rules: Linter.RulesRecord;
}; };
const configs = { const configs = {
'recommended-legacy': { recommended: {
plugins,
rules: basicRuleConfigs,
},
'recommended-latest-legacy': {
plugins, plugins,
rules: allRuleConfigs, rules: allRuleConfigs,
}, },
'flat/recommended': {
plugins,
rules: basicRuleConfigs,
},
'recommended-latest': { 'recommended-latest': {
plugins, plugins,
rules: allRuleConfigs, rules: allRuleConfigs,
}, },
recommended: {
plugins,
rules: basicRuleConfigs,
},
flat: {} as Record<string, ReactHooksFlatConfig>, flat: {} as Record<string, ReactHooksFlatConfig>,
}; };
const plugin = { const plugin = {
meta: { meta: {
name: 'eslint-plugin-react-hooks', name: 'eslint-plugin-react-hooks',
version: '7.0.0',
}, },
rules, rules,
configs, configs,
}; };
Object.assign(configs.flat, { Object.assign(configs.flat, {
'recommended-legacy': {
plugins: {'react-hooks': plugin},
rules: configs['recommended-legacy'].rules,
},
'recommended-latest-legacy': {
plugins: {'react-hooks': plugin},
rules: configs['recommended-latest-legacy'].rules,
},
'flat/recommended': {
plugins: {'react-hooks': plugin},
rules: configs['flat/recommended'].rules,
},
'recommended-latest': { 'recommended-latest': {
plugins: {'react-hooks': plugin}, plugins: {'react-hooks': plugin},
rules: configs['recommended-latest'].rules, rules: configs['recommended-latest'].rules,