From 17858beeedaaf5d0eb4fd1cc292fb34d07f9f659 Mon Sep 17 00:00:00 2001 From: jjangga0214 Date: Sat, 10 Sep 2022 21:51:54 +0900 Subject: [PATCH] [New] support new config system - add configs/ entry points for recommended configs - add documentation to readme --- CHANGELOG.md | 2 + README.md | 206 ++++++++++++++++++++++++++++++++++------- configs/all.js | 124 +++++++++++++++++++++++++ configs/jsx-runtime.js | 15 +++ configs/recommended.js | 30 ++++++ index.js | 180 ++++------------------------------- 6 files changed, 360 insertions(+), 197 deletions(-) create mode 100644 configs/all.js create mode 100644 configs/jsx-runtime.js create mode 100644 configs/recommended.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d8a066c34..ca108097f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,12 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange ## Unreleased ### Added +* support new config system ([#3429][] @jjangga0214) * [`hook-use-state`]: add `allowDestructuredState` option ([#3449][] @ljharb) * add [`sort-default-props`] and deprecate [`jsx-sort-default-props`] ([#1861][] @alexzherdev) [#3449]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3449 +[#3424]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3429 [#1861]: https://github.com/jsx-eslint/eslint-plugin-react/pull/1861 ## [7.31.9] - 2022.10.09 diff --git a/README.md b/README.md index 2862f522b4..aa80406357 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ React specific linting rules for `eslint` npm install eslint eslint-plugin-react --save-dev ``` -It is also possible to install ESLint globally rather than locally (using npm install eslint --global). However, this is not recommended, and any plugins or shareable configs that you use must be installed locally in either case. +It is also possible to install ESLint globally rather than locally (using `npm install -g eslint`). However, this is not recommended, and any plugins or shareable configs that you use must be installed locally in either case. -## Configuration +## Configuration (legacy: `.eslintrc*`) Use [our preset](#recommended) to get reasonable defaults: @@ -109,6 +109,174 @@ Enable the rules that you would like to use. } ``` +### Shareable configs + +#### Recommended + +This plugin exports a `recommended` configuration that enforces React good practices. + +To enable this configuration use the `extends` property in your `.eslintrc` config file: + +```json +{ + "extends": ["eslint:recommended", "plugin:react/recommended"] +} +``` + +See [`eslint` documentation](https://eslint.org/docs/user-guide/configuring/configuration-files#extending-configuration-files) for more information about extending configuration files. + +#### All + +This plugin also exports an `all` configuration that includes every available rule. +This pairs well with the `eslint:all` rule. + +```json +{ + "plugins": [ + "react" + ], + "extends": ["eslint:all", "plugin:react/all"] +} +``` + +**Note**: These configurations will import `eslint-plugin-react` and enable JSX in [parser options](https://eslint.org/docs/user-guide/configuring/language-options#specifying-parser-options). + +## Configuration (new: `eslint.config.js`) + +From [`v8.21.0`](https://github.com/eslint/eslint/releases/tag/v8.21.0), eslint announced a new config system. +In the new system, `.eslintrc*` is no longer used. `eslint.config.js` would be the default config file name. +In eslint `v8`, the legacy system (`.eslintrc*`) would still be supported, while in eslint `v9`, only the new system would be supported. + +And from [`v8.23.0`](https://github.com/eslint/eslint/releases/tag/v8.23.0), eslint CLI starts to look up `eslint.config.js`. +**So, if your eslint is `>=8.23.0`, you're 100% ready to use the new config system.** + +You might want to check out the official blog posts, + +- +- +- + +and the [official docs](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new). + +### Plugin + +The default export of `eslint-plugin-react` is a plugin object. + +```js +const react = require('eslint-plugin-react'); +const globals = require('globals'); + +module.exports = [ + … + { + files: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'], + plugins: { + react, + }, + languageOptions: { + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + globals: { + ...globals.browser, + }, + }, + rules: { + // ... any rules you want + 'react/jsx-uses-react': 'error', + 'react/jsx-uses-vars': 'error', + }, + // ... others are omitted for brevity + }, + … +]; +``` + +### Configuring shared settings + +Refer to the [official docs](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#configuring-shared-settings). + +The schema of the `settings.react` object would be identical to that of what's already described above in the legacy config section. + + +### Shareable configs + +There're also 3 shareable configs. + +- `eslint-plugin-react/configs/all` +- `eslint-plugin-react/configs/recommended` +- `eslint-plugin-react/configs/jsx-runtime` + +If your eslint.config.js is ESM, include the `.js` extension (e.g. `eslint-plugin-react/recommended.js`). Note that the next semver-major will require omitting the extension for these imports. + +**Note**: These configurations will import `eslint-plugin-react` and enable JSX in [`languageOptions.parserOptions`](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#configuration-objects). + +In the new config system, `plugin:` protocol(e.g. `plugin:react/recommended`) is no longer valid. +As eslint does not automatically import the preset config (shareable config), you explicitly do it by yourself. + +```js +const reactRecommended = require('eslint-plugin-react/configs/recommended'); + +module.exports = [ + … + reactRecommended, // This is not a plugin object, but a shareable config object + … +]; +``` + +You can of course add/override some properties. + +**Note**: Our shareable configs does not preconfigure `files` or [`languageOptions.globals`](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#configuration-objects). +For most of the cases, you probably want to configure some properties by yourself. + +```js +const reactRecommended = require('eslint-plugin-react/configs/recommended'); +const globals = require('globals'); + +module.exports = [ + … + { + files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'], + ...reactRecommended, + languageOptions: { + ...reactRecommended.languageOptions, + globals: { + ...globals.serviceworker, + ...globals.browser; + }, + }, + }, + … +]; +``` + +The above example is same as the example below, as the new config system is based on chaining. + +```js +const reactRecommended = require('eslint-plugin-react/configs/recommended'); +const globals = require('globals'); + +module.exports = [ + … + { + files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'], + ...reactRecommended, + }, + { + files: ['**/*.{js,mjs,cjs,jsx,mjsx,ts,tsx,mtsx}'], + languageOptions: { + globals: { + ...globals.serviceworker, + ...globals.browser, + }, + }, + }, + … +]; +``` + ## List of supported rules ✔: Enabled in the [`recommended`](#recommended) configuration.\ @@ -226,44 +394,12 @@ Enable the rules that you would like to use. | | 🔧 | | [react/jsx-wrap-multilines](docs/rules/jsx-wrap-multilines.md) | Disallow missing parentheses around multiline JSX | -### Other useful plugins +## Other useful plugins - Rules of Hooks: [eslint-plugin-react-hooks](https://github.com/facebook/react/tree/master/packages/eslint-plugin-react-hooks) - JSX accessibility: [eslint-plugin-jsx-a11y](https://github.com/evcohen/eslint-plugin-jsx-a11y) - React Native: [eslint-plugin-react-native](https://github.com/Intellicode/eslint-plugin-react-native) -## Shareable configurations - -### Recommended - -This plugin exports a `recommended` configuration that enforces React good practices. - -To enable this configuration use the `extends` property in your `.eslintrc` config file: - -```json -{ - "extends": ["eslint:recommended", "plugin:react/recommended"] -} -``` - -See [`eslint` documentation](https://eslint.org/docs/user-guide/configuring/configuration-files#extending-configuration-files) for more information about extending configuration files. - -### All - -This plugin also exports an `all` configuration that includes every available rule. -This pairs well with the `eslint:all` rule. - -```json -{ - "plugins": [ - "react" - ], - "extends": ["eslint:all", "plugin:react/all"] -} -``` - -**Note**: These configurations will import `eslint-plugin-react` and enable JSX in [parser options](https://eslint.org/docs/user-guide/configuring/language-options#specifying-parser-options). - ## License `eslint-plugin-react` is licensed under the [MIT License](https://opensource.org/licenses/mit-license.php). diff --git a/configs/all.js b/configs/all.js new file mode 100644 index 0000000000..e44f2ca52e --- /dev/null +++ b/configs/all.js @@ -0,0 +1,124 @@ +'use strict'; + +const react = require('../index'); + +const plugin = Object.assign({}, react); +delete plugin.configs; + +/* eslint-disable global-require */ +const allRules = { + 'boolean-prop-naming': require('../lib/rules/boolean-prop-naming'), + 'button-has-type': require('../lib/rules/button-has-type'), + 'default-props-match-prop-types': require('../lib/rules/default-props-match-prop-types'), + 'destructuring-assignment': require('../lib/rules/destructuring-assignment'), + 'display-name': require('../lib/rules/display-name'), + 'forbid-component-props': require('../lib/rules/forbid-component-props'), + 'forbid-dom-props': require('../lib/rules/forbid-dom-props'), + 'forbid-elements': require('../lib/rules/forbid-elements'), + 'forbid-foreign-prop-types': require('../lib/rules/forbid-foreign-prop-types'), + 'forbid-prop-types': require('../lib/rules/forbid-prop-types'), + 'function-component-definition': require('../lib/rules/function-component-definition'), + 'hook-use-state': require('../lib/rules/hook-use-state'), + 'iframe-missing-sandbox': require('../lib/rules/iframe-missing-sandbox'), + 'jsx-boolean-value': require('../lib/rules/jsx-boolean-value'), + 'jsx-child-element-spacing': require('../lib/rules/jsx-child-element-spacing'), + 'jsx-closing-bracket-location': require('../lib/rules/jsx-closing-bracket-location'), + 'jsx-closing-tag-location': require('../lib/rules/jsx-closing-tag-location'), + 'jsx-curly-spacing': require('../lib/rules/jsx-curly-spacing'), + 'jsx-curly-newline': require('../lib/rules/jsx-curly-newline'), + 'jsx-equals-spacing': require('../lib/rules/jsx-equals-spacing'), + 'jsx-filename-extension': require('../lib/rules/jsx-filename-extension'), + 'jsx-first-prop-new-line': require('../lib/rules/jsx-first-prop-new-line'), + 'jsx-handler-names': require('../lib/rules/jsx-handler-names'), + 'jsx-indent': require('../lib/rules/jsx-indent'), + 'jsx-indent-props': require('../lib/rules/jsx-indent-props'), + 'jsx-key': require('../lib/rules/jsx-key'), + 'jsx-max-depth': require('../lib/rules/jsx-max-depth'), + 'jsx-max-props-per-line': require('../lib/rules/jsx-max-props-per-line'), + 'jsx-newline': require('../lib/rules/jsx-newline'), + 'jsx-no-bind': require('../lib/rules/jsx-no-bind'), + 'jsx-no-comment-textnodes': require('../lib/rules/jsx-no-comment-textnodes'), + 'jsx-no-constructed-context-values': require('../lib/rules/jsx-no-constructed-context-values'), + 'jsx-no-duplicate-props': require('../lib/rules/jsx-no-duplicate-props'), + 'jsx-no-leaked-render': require('../lib/rules/jsx-no-leaked-render'), + 'jsx-no-literals': require('../lib/rules/jsx-no-literals'), + 'jsx-no-script-url': require('../lib/rules/jsx-no-script-url'), + 'jsx-no-target-blank': require('../lib/rules/jsx-no-target-blank'), + 'jsx-no-useless-fragment': require('../lib/rules/jsx-no-useless-fragment'), + 'jsx-one-expression-per-line': require('../lib/rules/jsx-one-expression-per-line'), + 'jsx-no-undef': require('../lib/rules/jsx-no-undef'), + 'jsx-curly-brace-presence': require('../lib/rules/jsx-curly-brace-presence'), + 'jsx-pascal-case': require('../lib/rules/jsx-pascal-case'), + 'jsx-fragments': require('../lib/rules/jsx-fragments'), + 'jsx-props-no-multi-spaces': require('../lib/rules/jsx-props-no-multi-spaces'), + 'jsx-props-no-spreading': require('../lib/rules/jsx-props-no-spreading'), + 'jsx-sort-default-props': require('../lib/rules/jsx-sort-default-props'), + 'jsx-sort-props': require('../lib/rules/jsx-sort-props'), + 'jsx-space-before-closing': require('../lib/rules/jsx-space-before-closing'), + 'jsx-tag-spacing': require('../lib/rules/jsx-tag-spacing'), + 'jsx-uses-react': require('../lib/rules/jsx-uses-react'), + 'jsx-uses-vars': require('../lib/rules/jsx-uses-vars'), + 'jsx-wrap-multilines': require('../lib/rules/jsx-wrap-multilines'), + 'no-invalid-html-attribute': require('../lib/rules/no-invalid-html-attribute'), + 'no-access-state-in-setstate': require('../lib/rules/no-access-state-in-setstate'), + 'no-adjacent-inline-elements': require('../lib/rules/no-adjacent-inline-elements'), + 'no-array-index-key': require('../lib/rules/no-array-index-key'), + 'no-arrow-function-lifecycle': require('../lib/rules/no-arrow-function-lifecycle'), + 'no-children-prop': require('../lib/rules/no-children-prop'), + 'no-danger': require('../lib/rules/no-danger'), + 'no-danger-with-children': require('../lib/rules/no-danger-with-children'), + 'no-deprecated': require('../lib/rules/no-deprecated'), + 'no-did-mount-set-state': require('../lib/rules/no-did-mount-set-state'), + 'no-did-update-set-state': require('../lib/rules/no-did-update-set-state'), + 'no-direct-mutation-state': require('../lib/rules/no-direct-mutation-state'), + 'no-find-dom-node': require('../lib/rules/no-find-dom-node'), + 'no-is-mounted': require('../lib/rules/no-is-mounted'), + 'no-multi-comp': require('../lib/rules/no-multi-comp'), + 'no-namespace': require('../lib/rules/no-namespace'), + 'no-set-state': require('../lib/rules/no-set-state'), + 'no-string-refs': require('../lib/rules/no-string-refs'), + 'no-redundant-should-component-update': require('../lib/rules/no-redundant-should-component-update'), + 'no-render-return-value': require('../lib/rules/no-render-return-value'), + 'no-this-in-sfc': require('../lib/rules/no-this-in-sfc'), + 'no-typos': require('../lib/rules/no-typos'), + 'no-unescaped-entities': require('../lib/rules/no-unescaped-entities'), + 'no-unknown-property': require('../lib/rules/no-unknown-property'), + 'no-unsafe': require('../lib/rules/no-unsafe'), + 'no-unstable-nested-components': require('../lib/rules/no-unstable-nested-components'), + 'no-unused-class-component-methods': require('../lib/rules/no-unused-class-component-methods'), + 'no-unused-prop-types': require('../lib/rules/no-unused-prop-types'), + 'no-unused-state': require('../lib/rules/no-unused-state'), + 'no-will-update-set-state': require('../lib/rules/no-will-update-set-state'), + 'prefer-es6-class': require('../lib/rules/prefer-es6-class'), + 'prefer-exact-props': require('../lib/rules/prefer-exact-props'), + 'prefer-read-only-props': require('../lib/rules/prefer-read-only-props'), + 'prefer-stateless-function': require('../lib/rules/prefer-stateless-function'), + 'prop-types': require('../lib/rules/prop-types'), + 'react-in-jsx-scope': require('../lib/rules/react-in-jsx-scope'), + 'require-default-props': require('../lib/rules/require-default-props'), + 'require-optimization': require('../lib/rules/require-optimization'), + 'require-render-return': require('../lib/rules/require-render-return'), + 'self-closing-comp': require('../lib/rules/self-closing-comp'), + 'sort-comp': require('../lib/rules/sort-comp'), + 'sort-default-props': require('../lib/rules/sort-default-props'), + 'sort-prop-types': require('../lib/rules/sort-prop-types'), + 'state-in-constructor': require('../lib/rules/state-in-constructor'), + 'static-property-placement': require('../lib/rules/static-property-placement'), + 'style-prop-object': require('../lib/rules/style-prop-object'), + 'void-dom-elements-no-children': require('../lib/rules/void-dom-elements-no-children'), +}; +/* eslint-enable global-require */ + +module.exports = { + plugins: { + react: plugin, + }, + languageOptions: { + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + }, + }, + rules: allRules, +}; diff --git a/configs/jsx-runtime.js b/configs/jsx-runtime.js new file mode 100644 index 0000000000..3caf18965c --- /dev/null +++ b/configs/jsx-runtime.js @@ -0,0 +1,15 @@ +'use strict'; + +const all = require('./all'); + +module.exports = Object.assign({}, all, { + languageOptions: Object.assign({}, all.languageOptions, { + parserOptions: Object.assign({}, all.languageOptions.parserOptions, { + jsxPragma: null, // for @typescript/eslint-parser + }), + }), + rules: { + 'react/react-in-jsx-scope': 0, + 'react/jsx-uses-react': 0, + }, +}); diff --git a/configs/recommended.js b/configs/recommended.js new file mode 100644 index 0000000000..09189a2199 --- /dev/null +++ b/configs/recommended.js @@ -0,0 +1,30 @@ +'use strict'; + +const all = require('./all'); + +module.exports = Object.assign({}, all, { + rules: { + 'react/display-name': 2, + 'react/jsx-key': 2, + 'react/jsx-no-comment-textnodes': 2, + 'react/jsx-no-duplicate-props': 2, + 'react/jsx-no-target-blank': 2, + 'react/jsx-no-undef': 2, + 'react/jsx-uses-react': 2, + 'react/jsx-uses-vars': 2, + 'react/no-children-prop': 2, + 'react/no-danger-with-children': 2, + 'react/no-deprecated': 2, + 'react/no-direct-mutation-state': 2, + 'react/no-find-dom-node': 2, + 'react/no-is-mounted': 2, + 'react/no-render-return-value': 2, + 'react/no-string-refs': 2, + 'react/no-unescaped-entities': 2, + 'react/no-unknown-property': 2, + 'react/no-unsafe': 0, + 'react/prop-types': 2, + 'react/react-in-jsx-scope': 2, + 'react/require-render-return': 2, + }, +}); diff --git a/index.js b/index.js index 12c60874b3..e9f2802e91 100644 --- a/index.js +++ b/index.js @@ -3,109 +3,11 @@ const fromEntries = require('object.fromentries'); const entries = require('object.entries'); -/* eslint-disable global-require */ -const allRules = { - 'boolean-prop-naming': require('./lib/rules/boolean-prop-naming'), - 'button-has-type': require('./lib/rules/button-has-type'), - 'default-props-match-prop-types': require('./lib/rules/default-props-match-prop-types'), - 'destructuring-assignment': require('./lib/rules/destructuring-assignment'), - 'display-name': require('./lib/rules/display-name'), - 'forbid-component-props': require('./lib/rules/forbid-component-props'), - 'forbid-dom-props': require('./lib/rules/forbid-dom-props'), - 'forbid-elements': require('./lib/rules/forbid-elements'), - 'forbid-foreign-prop-types': require('./lib/rules/forbid-foreign-prop-types'), - 'forbid-prop-types': require('./lib/rules/forbid-prop-types'), - 'function-component-definition': require('./lib/rules/function-component-definition'), - 'hook-use-state': require('./lib/rules/hook-use-state'), - 'iframe-missing-sandbox': require('./lib/rules/iframe-missing-sandbox'), - 'jsx-boolean-value': require('./lib/rules/jsx-boolean-value'), - 'jsx-child-element-spacing': require('./lib/rules/jsx-child-element-spacing'), - 'jsx-closing-bracket-location': require('./lib/rules/jsx-closing-bracket-location'), - 'jsx-closing-tag-location': require('./lib/rules/jsx-closing-tag-location'), - 'jsx-curly-spacing': require('./lib/rules/jsx-curly-spacing'), - 'jsx-curly-newline': require('./lib/rules/jsx-curly-newline'), - 'jsx-equals-spacing': require('./lib/rules/jsx-equals-spacing'), - 'jsx-filename-extension': require('./lib/rules/jsx-filename-extension'), - 'jsx-first-prop-new-line': require('./lib/rules/jsx-first-prop-new-line'), - 'jsx-handler-names': require('./lib/rules/jsx-handler-names'), - 'jsx-indent': require('./lib/rules/jsx-indent'), - 'jsx-indent-props': require('./lib/rules/jsx-indent-props'), - 'jsx-key': require('./lib/rules/jsx-key'), - 'jsx-max-depth': require('./lib/rules/jsx-max-depth'), - 'jsx-max-props-per-line': require('./lib/rules/jsx-max-props-per-line'), - 'jsx-newline': require('./lib/rules/jsx-newline'), - 'jsx-no-bind': require('./lib/rules/jsx-no-bind'), - 'jsx-no-comment-textnodes': require('./lib/rules/jsx-no-comment-textnodes'), - 'jsx-no-constructed-context-values': require('./lib/rules/jsx-no-constructed-context-values'), - 'jsx-no-duplicate-props': require('./lib/rules/jsx-no-duplicate-props'), - 'jsx-no-leaked-render': require('./lib/rules/jsx-no-leaked-render'), - 'jsx-no-literals': require('./lib/rules/jsx-no-literals'), - 'jsx-no-script-url': require('./lib/rules/jsx-no-script-url'), - 'jsx-no-target-blank': require('./lib/rules/jsx-no-target-blank'), - 'jsx-no-useless-fragment': require('./lib/rules/jsx-no-useless-fragment'), - 'jsx-one-expression-per-line': require('./lib/rules/jsx-one-expression-per-line'), - 'jsx-no-undef': require('./lib/rules/jsx-no-undef'), - 'jsx-curly-brace-presence': require('./lib/rules/jsx-curly-brace-presence'), - 'jsx-pascal-case': require('./lib/rules/jsx-pascal-case'), - 'jsx-fragments': require('./lib/rules/jsx-fragments'), - 'jsx-props-no-multi-spaces': require('./lib/rules/jsx-props-no-multi-spaces'), - 'jsx-props-no-spreading': require('./lib/rules/jsx-props-no-spreading'), - 'jsx-sort-default-props': require('./lib/rules/jsx-sort-default-props'), - 'jsx-sort-props': require('./lib/rules/jsx-sort-props'), - 'jsx-space-before-closing': require('./lib/rules/jsx-space-before-closing'), - 'jsx-tag-spacing': require('./lib/rules/jsx-tag-spacing'), - 'jsx-uses-react': require('./lib/rules/jsx-uses-react'), - 'jsx-uses-vars': require('./lib/rules/jsx-uses-vars'), - 'jsx-wrap-multilines': require('./lib/rules/jsx-wrap-multilines'), - 'no-invalid-html-attribute': require('./lib/rules/no-invalid-html-attribute'), - 'no-access-state-in-setstate': require('./lib/rules/no-access-state-in-setstate'), - 'no-adjacent-inline-elements': require('./lib/rules/no-adjacent-inline-elements'), - 'no-array-index-key': require('./lib/rules/no-array-index-key'), - 'no-arrow-function-lifecycle': require('./lib/rules/no-arrow-function-lifecycle'), - 'no-children-prop': require('./lib/rules/no-children-prop'), - 'no-danger': require('./lib/rules/no-danger'), - 'no-danger-with-children': require('./lib/rules/no-danger-with-children'), - 'no-deprecated': require('./lib/rules/no-deprecated'), - 'no-did-mount-set-state': require('./lib/rules/no-did-mount-set-state'), - 'no-did-update-set-state': require('./lib/rules/no-did-update-set-state'), - 'no-direct-mutation-state': require('./lib/rules/no-direct-mutation-state'), - 'no-find-dom-node': require('./lib/rules/no-find-dom-node'), - 'no-is-mounted': require('./lib/rules/no-is-mounted'), - 'no-multi-comp': require('./lib/rules/no-multi-comp'), - 'no-namespace': require('./lib/rules/no-namespace'), - 'no-set-state': require('./lib/rules/no-set-state'), - 'no-string-refs': require('./lib/rules/no-string-refs'), - 'no-redundant-should-component-update': require('./lib/rules/no-redundant-should-component-update'), - 'no-render-return-value': require('./lib/rules/no-render-return-value'), - 'no-this-in-sfc': require('./lib/rules/no-this-in-sfc'), - 'no-typos': require('./lib/rules/no-typos'), - 'no-unescaped-entities': require('./lib/rules/no-unescaped-entities'), - 'no-unknown-property': require('./lib/rules/no-unknown-property'), - 'no-unsafe': require('./lib/rules/no-unsafe'), - 'no-unstable-nested-components': require('./lib/rules/no-unstable-nested-components'), - 'no-unused-class-component-methods': require('./lib/rules/no-unused-class-component-methods'), - 'no-unused-prop-types': require('./lib/rules/no-unused-prop-types'), - 'no-unused-state': require('./lib/rules/no-unused-state'), - 'no-will-update-set-state': require('./lib/rules/no-will-update-set-state'), - 'prefer-es6-class': require('./lib/rules/prefer-es6-class'), - 'prefer-exact-props': require('./lib/rules/prefer-exact-props'), - 'prefer-read-only-props': require('./lib/rules/prefer-read-only-props'), - 'prefer-stateless-function': require('./lib/rules/prefer-stateless-function'), - 'prop-types': require('./lib/rules/prop-types'), - 'react-in-jsx-scope': require('./lib/rules/react-in-jsx-scope'), - 'require-default-props': require('./lib/rules/require-default-props'), - 'require-optimization': require('./lib/rules/require-optimization'), - 'require-render-return': require('./lib/rules/require-render-return'), - 'self-closing-comp': require('./lib/rules/self-closing-comp'), - 'sort-comp': require('./lib/rules/sort-comp'), - 'sort-default-props': require('./lib/rules/sort-default-props'), - 'sort-prop-types': require('./lib/rules/sort-prop-types'), - 'state-in-constructor': require('./lib/rules/state-in-constructor'), - 'static-property-placement': require('./lib/rules/static-property-placement'), - 'style-prop-object': require('./lib/rules/style-prop-object'), - 'void-dom-elements-no-children': require('./lib/rules/void-dom-elements-no-children'), -}; -/* eslint-enable */ +const configAll = require('./configs/all'); +const configRecommended = require('./configs/recommended'); +const configRuntime = require('./configs/jsx-runtime'); + +const allRules = configAll.rules; function filterRules(rules, predicate) { return fromEntries(entries(rules).filter((entry) => predicate(entry[1]))); @@ -120,69 +22,23 @@ const activeRulesConfig = configureAsError(activeRules); const deprecatedRules = filterRules(allRules, (rule) => rule.meta.deprecated); +const eslintrcPlugins = [ + 'react', +]; + module.exports = { deprecatedRules, rules: allRules, configs: { - recommended: { - plugins: [ - 'react', - ], - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - }, - rules: { - 'react/display-name': 2, - 'react/jsx-key': 2, - 'react/jsx-no-comment-textnodes': 2, - 'react/jsx-no-duplicate-props': 2, - 'react/jsx-no-target-blank': 2, - 'react/jsx-no-undef': 2, - 'react/jsx-uses-react': 2, - 'react/jsx-uses-vars': 2, - 'react/no-children-prop': 2, - 'react/no-danger-with-children': 2, - 'react/no-deprecated': 2, - 'react/no-direct-mutation-state': 2, - 'react/no-find-dom-node': 2, - 'react/no-is-mounted': 2, - 'react/no-render-return-value': 2, - 'react/no-string-refs': 2, - 'react/no-unescaped-entities': 2, - 'react/no-unknown-property': 2, - 'react/no-unsafe': 0, - 'react/prop-types': 2, - 'react/react-in-jsx-scope': 2, - 'react/require-render-return': 2, - }, - }, - all: { - plugins: [ - 'react', - ], - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - }, + recommended: Object.assign({}, configRecommended, { + plugins: eslintrcPlugins, + }), + all: Object.assign({}, configAll, { + plugins: eslintrcPlugins, rules: activeRulesConfig, - }, - 'jsx-runtime': { - plugins: [ - 'react', - ], - parserOptions: { - ecmaFeatures: { - jsx: true, - }, - jsxPragma: null, // for @typescript/eslint-parser - }, - rules: { - 'react/react-in-jsx-scope': 0, - 'react/jsx-uses-react': 0, - }, - }, + }), + 'jsx-runtime': Object.assign({}, configRuntime, { + plugins: eslintrcPlugins, + }), }, };