vercel / next.js

The React Framework
https://nextjs.org
MIT License
126.75k stars 26.95k forks source link

New ESLint "flat" configuration file does not work with `next/core-web-vitals` #64114

Closed hb20007 closed 2 weeks ago

hb20007 commented 7 months ago

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/pensive-star-go8s7s

To Reproduce

  1. Run npm run dev and observe the error showing that ...compat.extends("next/core-web-vitals") does not work.

Current vs. Expected behavior

Current behavior: It is impossible to use the new ESLint "flat config" in a Next.js project (due to next/core-web-vitals).

Expected behavior: It should work.

Which area(s) are affected? (Select all that apply)

ESLint (eslint-config-next)

Additional context

In case it is not clear, I have imported ...compat.extends("next/core-web-vitals") in page.tsx only for the purpose of showing that it does not work. The file with the actual ESLint configuration is eslint.config.js.

I have followed the official ESLint Configuration Migration Guide, where it is mentioned that FlatCompat should be used for an npm package which is in eslintrc format. In this case, I believe that the problem is that next/core-web-vitals is not an npm package. I also tried ...compat.extends("eslint-config-next"), but that does not work either.

For extra context, ESLint is moving from .eslintrc.json to eslint.config.js, and all other shareable ESLint configs I am using (e.g., typescript-eslint, eslint-config-prettier) already support this, even without needing to use FlatCompat.

NEXT-3293

devjiwonchoi commented 7 months ago

Hi, IMHO we need to wait until all the deps of esling-config-next support eslint 9 since it just have been released, will need some patches before we call it stable.

The deps:

"dependencies": {
  "@next/eslint-plugin-next": "14.2.0-canary.60",
  "@rushstack/eslint-patch": "^1.3.3",
  "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0",
  "eslint-import-resolver-node": "^0.3.6",
  "eslint-import-resolver-typescript": "^3.5.2",
  "eslint-plugin-import": "^2.28.1",
  "eslint-plugin-jsx-a11y": "^6.7.1",
  "eslint-plugin-react": "^7.33.2",
  "eslint-plugin-react-hooks": "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705"
},
immdraselkhan commented 6 months ago

Until the fixed version of ESLint needs to downgrade to v8.57.0

Remove the ESLint v9 yarn remove eslint

Install the v8.57.0 yarn add -D eslint@8.57.0

QuentinScDS commented 6 months ago

Until the fixed version of ESLint needs to downgrade to v8.57.0

Remove the ESLint v9 yarn remove eslint

Install the v8.57.0 yarn add -D eslint@8.57.0

Thank you !

hdaum commented 6 months ago

Support for the "new" config format shouldn't be tied to version 9 support. 8.57.0 can also use the flat config format and my company would like to migrate our configurations to the new format in preparation for moving to eslint 9.

This is the only plugin that we use that doesn't work with the newer format.

daanvosdewael commented 5 months ago

ESLint published a new package to help with dependency plugins that are not yet converted to the Flat config: @eslint/compat. Details about how this works is in their blogpost: https://eslint.org/blog/2024/05/eslint-compatibility-utilities/

Could this help with the migration of the eslint-config-next package to ESLint v9?

poksme commented 3 months ago

@daanvosdewael yes this helps, I was able to use ESLint 9 with core-web-vitals on my project, here is a guide on how to implement it

Also for a TLDR; check my comment here

Adesh-Pandey commented 2 months ago

Has anyone successfully converted their code to use flat config format? I m still not able to even with this. I do want to use common js. Edit: I get Error: Failed to patch ESLint because the calling module was not recognized.

Screenshot 2024-08-28 at 8 14 52 PM

As this does not work as well.

  ...compat.extends(
    "next"
    )
kevinlaw91 commented 2 months ago

Has anyone successfully converted their code to use flat config format?

@Adesh-Pandey try this see if it works. i setup using tseslint.config() via module export it worked

import { FlatCompat } from "@eslint/eslintrc";
import { fixupConfigRules } from "@eslint/compat";
const flatCompat = new FlatCompat();

= [
  ...fixupConfigRules(
    flatCompat.extends('next/core-web-vitals')
  ),
]
TechQuery commented 1 week ago

  ...fixupConfigRules(
    flatCompat.extends('next/core-web-vitals')
  ),

@kevinlaw91 your resolution failed in Next.js 15: https://github.com/kaiyuanshe/kaiyuanshe.github.io/pull/345#discussion_r1811261950

barrenechea commented 1 week ago

The following worked for me:

  ...fixupConfigRules(
    flatCompat.extends("plugin:@next/next/core-web-vitals")
  ),
devjiwonchoi commented 5 days ago

Could you try this?

Before Node v20.11.0:

import { dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
import { FlatCompat } from '@eslint/eslintrc'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

const compat = new FlatCompat({
  baseDirectory: __dirname,
})

const eslintConfig = [
  ...compat.extends('next/core-web-vitals', 'next/typescript'),
]

export default eslintConfig

After Node v20.11.0:

import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  baseDirectory: import.meta.dirname,
})

const eslintConfig = [
  ...compat.extends('next/core-web-vitals', 'next/typescript'),
]

export default eslintConfig
yanush commented 3 days ago

what should be the syntax for a mono-repo project using several directories in config?