Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: add react config in flat config? #282

Closed
3 tasks done
promise96319 opened this issue Oct 11, 2023 · 16 comments · Fixed by #326
Closed
3 tasks done

Question: add react config in flat config? #282

promise96319 opened this issue Oct 11, 2023 · 16 comments · Fixed by #326
Labels
enhancement New feature or request

Comments

@promise96319
Copy link
Contributor

Clear and concise description of the problem

Should we add a react config?

There already have JSX configuration in Stylistic, which helps us format the basic JSX. However, when it comes to React, there are additional coding style considerations. Do we need to implement a new React configuration?

If necessary, I'm willing to submit a PR.

Suggested solution

Add eslint-plugin-react's recommended rules in react config.

Alternative

No response

Additional context

No response

Validations

@promise96319 promise96319 added the enhancement New feature or request label Oct 11, 2023
@antfu
Copy link
Owner

antfu commented Oct 12, 2023

I don't mind having React configs built-in if someone would be interested in helping maintain it.

However, my main concern is that the dependencies of eslint-plugin-react are quite bloated (https://pkg-size.dev/eslint-plugin-react), and I don't want to introduce that to every project using my eslint config.

Not sure if having it as an optional peer deps and detect automatically would be helpful. But that would increase the implicitness.

@promise96319
Copy link
Contributor Author

promise96319 commented Oct 12, 2023

I believe you're correct. Each additional built-in configuration will introduce extra dependencies, causing the package to become bulky. This not only applies to React but also to when we want to add some other configurations like Solid or Svelte.

Perhaps it can offer users a choice through a cli (#274 ).

When running npx @antfu/eslint-config init, it could prompt users to select the desired configuration, such as React or Vue. Subsequently, it would generate the corresponding eslint.config.js file and install the relevant dependencies based on the user's choice.

Additionally, we could provide the command npx @antfu/eslint-config add react to separately add the React configuration and its dependencies.

I'm not certain if this is a sound idea, just offering it as a suggestion. @antfu/eslint-config has already performed admirably, Maybe we also can create our own eslint config based on it as an alternative approach.

@antfu
Copy link
Owner

antfu commented Oct 12, 2023

Let me think about the implementation a bit.

On the other hand, do you have any good config recommendations?

@promise96319
Copy link
Contributor Author

In my work, I primarily use React, and it's config can refer to the config of eslint-config-next .

I believe there are two rules here that are particularly useful:

  • react/prop-types: off:In the case of using TypeScript, TypeScript can statically check prop type issues, and using prop-types for runtime validation is not very important.

  • react/react-in-jsx-scope: off: After React 17, there's no need to include import React from 'react' anymore. (react docs)

Other rules can be considered as optional references.

So, here's a rough config:

[
  {
    name: 'antfu:react:setup',
    plugins: {
      'react': pluginReact,
      'react-hooks': pluginReactHooks,
    },
  },
  {
    files: [GLOB_JSX, GLOB_TSX],
    languageOptions: {
      parserOptions: {
        ecmaFeatures: {
          jsx: true,
        },
      },
    },
    name: 'antfu:react:rules',
    rules: {
      ...pluginReact.configs.recommended.rules,
      ...pluginReactHooks.configs.recommended.rules,

      'react/prop-types': 'off',
      'react/react-in-jsx-scope': 'off',

      ...overrides,
    },
    settings: {
      react: {
        version: 'detect',
      },
    },
  },
]

@rost-git
Copy link
Contributor

rost-git commented Nov 3, 2023

@antfu if cli is too much effort - framework specific linting can be something like:

import antfu from '@antfu/eslint-config'
import vue from '@antfu/eslint-config-vue'
// import react from '@antfu/eslint-config-react'
// import svelte from '@antfu/eslint-config-svelte'

const config = antfu({
  framework: vue()
})

@antfu
Copy link
Owner

antfu commented Nov 4, 2023

Yeah, but I don't really want to maintain multiple packages as we just migrate from monorepo. It also make less sense for me to maintain @antfu/eslint-config-react or @antfu/eslint-config-svelte as I don't really use them. If those can not be provided out-of-box, I guess it might be better to have someone else maintain packages like that as @someone/eslint-config-react

@usercao
Copy link

usercao commented Nov 14, 2023

Perhaps it is possible to divide @antfu/eslint-config-vue or @antfu/eslint-config-react or @antfu/eslint-config-styled-components into eslint-stylistic organizations with a rough framework and wait for someone to maintain it?

@antfu
Copy link
Owner

antfu commented Nov 14, 2023

Ideally framework specific rules should be maintained by their own plugins/repos. It would be out-of-scope of ESLint Stylistic

@usercao
Copy link

usercao commented Nov 14, 2023

I understand what you mean. My idea is to integrate @antfu/eslint-config with eslint-stylistic, just like the Vite organization, to provide some common and foundational styles. The rest is to establish different warehouses (such as @eslint-stylistic/eslint-config-vue and @eslint-stylistic/eslint-config-react and @eslint-stylistic/eslint-config-styled-components) and be maintained by volunteers on their own, so that you can only be responsible for eslint-stylistic and reduce your workload.

@pnodet
Copy link

pnodet commented Nov 17, 2023

Hi,

I recently created another eslint config because my tech stack was quite different (react over vue, nextjs, tailwindcss over unocss, etc.). I used this repository as a starting point. Today I had an issue where some unused plugins were throwing errors.

In my case I decided to try using dynamic imports instead of the plugin.ts file in this repo.

Maybe it could be helpful also in your case to avoid bloating the config?
Not sure if this help, here is the PR I made on our repo: https://github.com/nivalis-studio/eslint-config/pull/9

@pnodet
Copy link

pnodet commented Nov 17, 2023

However, my main concern is that the dependencies of eslint-plugin-react are quite bloated (https://pkg-size.dev/eslint-plugin-react), and I don't want to introduce that to every project using my eslint config.

Not sure if having it as an optional peer deps and detect automatically would be helpful. But that would increase the implicitness.

In think it's possible to achieve this by including react as an optional deps, and leveraging lazy imports.

const hasReact = isPackageExists('react')

if (hasReact) config.push(...(await reactConfig())

// react-config.ts

export const reactConfig = async () => {
  try {
    const pluginReact = await import('eslint-plugin-react')
    return [
      {
        plugins: {
          react: reactPlugin
        },
        rules: {
          // rules...
        }
      }
    ]
  } catch (error) {
    console.error('eslint-plugin-react dependency is not available:', error);
}

@antfu
Copy link
Owner

antfu commented Nov 17, 2023

I'd love that idea of dynamically importing eslint-plugin-react! But I am not so sure how far ESLint supports async config resolving. While we could do top-level await in ESM, it might break the CJS usage. If that end up working, I am happy to have them in the repo to support so.

@pnodet
Copy link

pnodet commented Nov 17, 2023

fwiw I now use dynamic imports with an await config through this PR: https://github.com/nivalis-studio/eslint-config/pull/9
It does not use optionalPeerDependencies though.

I have tested it in a cjs project using

// eslint.config.js
const {nivalis} = require('@nivalis/eslint-config');

module.exports = nivalis();

I can come back in a few days / weeks after we have more history but we don't seem to have any issue for the moment

@antfu
Copy link
Owner

antfu commented Nov 17, 2023

Yeah I think you are right, ESLint seems to support exporting a promise. In that regards, I am happy to migrate my config over to use dynamic imported plugins

@thenbe
Copy link
Contributor

thenbe commented Nov 19, 2023

Yeah, but I don't really want to maintain multiple packages as we just migrate from monorepo. It also make less sense for me to maintain @antfu/eslint-config-react or @antfu/eslint-config-svelte as I don't really use them. If those can not be provided out-of-box, I guess it might be better to have someone else maintain packages like that as @someone/eslint-config-react

If there is a recommended approach for maintaining a hypothetical @someone/eslint-config-{react|svelte|.*} I'd be happy to work on the svelte variant.

I've already forked this repo just to add svelte support, but did not want to open a PR because as you said, it wouldn't make sense for you to have to maintain a svelte config when you never use svelte.

I had originally intended to have the fork auto-rebase and release to be in sync with upstream (a pattern I originally saw on https://github.com/un-es/eslint-plugin-i), but then wasn't sure how to juggle semversions (upstream version vs fork version). If anyone can point me in the direction of a better pattern to maintain something like this, I'm happy to work on it. Ideally, it'd be one where users of @antfu/eslint-config can easily adopt eslint-config-svelte config but without requiring the initial @antfu/eslint-config repo of having to maintain that eslint-config-svelte.

@antfu
Copy link
Owner

antfu commented Nov 19, 2023

If we end up having #326, I am ok to have svelte config with similar approach, as long as someone can help me maintain them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants