From 61e713c1d31976175316c8256f4be14ba8bbdb29 Mon Sep 17 00:00:00 2001 From: michael faith Date: Thu, 16 Jan 2025 17:39:11 -0600 Subject: [PATCH] feat(eslint-plugin-react-hooks): support flat config (#30774) --- packages/eslint-plugin-react-hooks/README.md | 38 ++++++++++++- .../eslint-plugin-react-hooks/src/index.js | 55 ++++++++++++++++--- 2 files changed, 82 insertions(+), 11 deletions(-) diff --git a/packages/eslint-plugin-react-hooks/README.md b/packages/eslint-plugin-react-hooks/README.md index d7a3e7d39cdee..36f63722f7268 100644 --- a/packages/eslint-plugin-react-hooks/README.md +++ b/packages/eslint-plugin-react-hooks/README.md @@ -18,21 +18,38 @@ npm install eslint-plugin-react-hooks --save-dev yarn add eslint-plugin-react-hooks --dev ``` -Then extend the recommended eslint config: +### Legacy Config (.eslintrc) + +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. ```js { "extends": [ // ... - "plugin:react-hooks/recommended" + "plugin:react-hooks/recommended-legacy" ] } ``` +### Flat Config (eslint.config.js) + +For [ESLint 9.0.0 and above](https://eslint.org/blog/2024/04/eslint-v9.0.0-released/) users, add the `recommended-latest` config. + +```js +import reactHooks from 'eslint-plugin-react-hooks'; + +export default [ + // ... + reactHooks.configs['recommended-latest'], +]; +``` + ### Custom Configuration If you want more fine-grained configuration, you can instead add a snippet like this to your ESLint configuration file: +#### Legacy Config (.eslintrc) + ```js { "plugins": [ @@ -47,6 +64,23 @@ If you want more fine-grained configuration, you can instead add a snippet like } ``` +#### Flat Config (eslint.config.js) + +```js +import reactHooks from 'eslint-plugin-react-hooks'; + +export default [ + { + files: ['**/*.{js,jsx}'], + plugins: { 'react-hooks': reactHooks }, + // ... + rules: { + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'warn', + } + }, +]; +``` ## Advanced Configuration diff --git a/packages/eslint-plugin-react-hooks/src/index.js b/packages/eslint-plugin-react-hooks/src/index.js index d8ff02e7b144f..c9da639a4fff6 100644 --- a/packages/eslint-plugin-react-hooks/src/index.js +++ b/packages/eslint-plugin-react-hooks/src/index.js @@ -10,17 +10,54 @@ import RulesOfHooks from './RulesOfHooks'; import ExhaustiveDeps from './ExhaustiveDeps'; -export const configs = { - recommended: { - plugins: ['react-hooks'], - rules: { - 'react-hooks/rules-of-hooks': 'error', - 'react-hooks/exhaustive-deps': 'warn', - }, - }, -}; +const {name, version} = require('../package.json'); +// All rules export const rules = { 'rules-of-hooks': RulesOfHooks, 'exhaustive-deps': ExhaustiveDeps, }; + +// Config rules +const configRules = { + 'react-hooks/rules-of-hooks': 'error', + 'react-hooks/exhaustive-deps': 'warn', +}; + +// Legacy config +const legacyRecommendedConfig = { + plugins: ['react-hooks'], + rules: configRules, +}; + +// Base plugin object +const reactHooksPlugin = { + meta: {name, version}, + rules, +}; + +// Flat config +const flatRecommendedConfig = { + name: 'react-hooks/recommended', + plugins: {'react-hooks': reactHooksPlugin}, + rules: configRules, +}; + +export const configs = { + /** Legacy recommended config, to be used with rc-based configurations */ + 'recommended-legacy': legacyRecommendedConfig, + + /** Latest recommended config, to be used with flat configurations */ + 'recommended-latest': flatRecommendedConfig, + + /** + * 'recommended' is currently aliased to the legacy / rc recommended config) to maintain backwards compatibility. + * This is deprecated and in v6, it will switch to alias the flat recommended config. + */ + recommended: legacyRecommendedConfig, +}; + +export default { + ...reactHooksPlugin, + configs, +};