jsx-eslint / eslint-plugin-react

React-specific linting rules for ESLint
MIT License
8.97k stars 2.77k forks source link

[Bug]: flat config crash when using manual plugin def and recommended config #3693

Closed bradzacher closed 2 months ago

bradzacher commented 7 months ago

Is there an existing issue for this?

Description Overview

Repro

// eslint.config.js
import eslintReact from 'eslint-plugin-react';
import eslintReactRecommended from 'eslint-plugin-react/configs/recommended.js';

export default [
    {
        plugins: {
            react: eslintReact,
        },
    },
    eslintReactRecommended,
];

npx eslint eslint.config.js

Expected

No errors

Actual

Oops! Something went wrong! :(

ESLint: 8.56.0

Error: Key "plugins": Cannot redefine plugin "react".

More Info

When defining a plugin key in the flat config ESLint enforces that you only ever redefine they key with the same plugin. This check is done by comparing by reference -- i.e. configA.plugin.react === configB.plugin.react

eslint-plugin-react fails this check because it defines its "plugin" in two locations: https://github.com/jsx-eslint/eslint-plugin-react/blob/36e791de784e7fa1edd5b6d232fbcaf2dd7cf9bf/index.js#L14-L31 https://github.com/jsx-eslint/eslint-plugin-react/blob/36e791de784e7fa1edd5b6d232fbcaf2dd7cf9bf/configs/all.js#L23-L26

For this to work there needs to be exactly 1 copy of the "plugin" defined by the package. For example:

const plugin = { ... };
plugin.configs = {
  recommended: {
    plugins: { react: plugin },
    rules: { ... },
  },
  all: {
    plugins: { react: plugin },
    rules: { ... },
  },
});

eslint-plugin-react version

v7.33.2

eslint version

v8.56.0

node version

v20.11.0

me4502 commented 3 months ago

It's also worth noting that this affects using multiple configurations from this plugin too. It prevents using both the flat recommended and jsx-runtime configurations at the time time for example, which is the recommended configuration when using the React 17 JSX transform.

ljharb commented 3 months ago

@me4502 at the moment we don't support flat config at all, but indeed it needs to be fixed.

michaelfaith commented 3 months ago

I believe this is actually to do with the fact that the recommended config defines the plugin, and your config which uses the recommended config is also defining the plugin. It shouldn't have anything to do with plugins being defined in other places in the package. Can you try removing from your config?

{
  plugins: {
    react: eslintReact,
  },
},