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

next-lint Doesn't Support ESLint 9 #64409

Open
Tracked by #12 ...
dylandignan opened this issue Apr 12, 2024 · 61 comments
Open
Tracked by #12 ...

next-lint Doesn't Support ESLint 9 #64409

dylandignan opened this issue Apr 12, 2024 · 61 comments
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. Linting Related to `next lint` or ESLint with Next.js.

Comments

@dylandignan
Copy link

dylandignan commented Apr 12, 2024

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/vigilant-pine-6wmz8y

To Reproduce

  1. Add next lint script to package.json per https://nextjs.org/docs/app/building-your-application/configuring/eslint
  2. Add .eslintrc.json to project per https://nextjs.org/docs/app/building-your-application/configuring/eslint
{
  "extends": "next/core-web-vitals"
}
  1. Run lint and get an error
➜  /workspace git:(master) ✗ npm run lint

> lint
> next lint

Invalid Options:
- Unknown options: useEslintrc, extensions, resolvePluginsRelativeTo, rulePaths, ignorePath, reportUnusedDisableDirectives
- 'extensions' has been removed.
- 'resolvePluginsRelativeTo' has been removed.
- 'ignorePath' has been removed.
- 'rulePaths' has been removed. Please define your rules using plugins.
- 'reportUnusedDisableDirectives' has been removed. Please use the 'overrideConfig.linterOptions.reportUnusedDisableDirectives' option instead.

Current vs. Expected behavior

Expected lint to run successfully, but it failed with errors.

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sun Aug  6 20:05:33 UTC 2023
  Available memory (MB): 4102
  Available CPU cores: 2
Binaries:
  Node: 20.9.0
  npm: 9.8.1
  Yarn: 1.22.19
  pnpm: 8.10.2
Relevant Packages:
  next: 14.2.1-canary.0 // Latest available version is detected (14.2.1-canary.0).
  eslint-config-next: 14.1.4
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.1.3
Next.js Config:
  output: N/A

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

ESLint (eslint-config-next)

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

next dev (local), next build (local), next start (local)

Additional context

It looks like this is coming from https://github.com/vercel/next.js/blob/canary/packages/next/src/cli/next-lint.ts. This needs to be changed to support ESLint 9's flat config https://eslint.org/docs/latest/use/migrate-to-9.0.0#flat-config. The migration guide is at https://eslint.org/docs/latest/use/configure/migration-guide

NEXT-3112

@dylandignan dylandignan added the bug Issue was opened via the bug report template. label Apr 12, 2024
@davidjulakidze
Copy link

davidjulakidze commented Apr 13, 2024

Bumping this for visibility, it does not seem to prevent build but unsure of the impact.

✓ Compiled successfully
   Linting and checking validity of types  .. 
⨯ ESLint: Invalid Options: - Unknown options: useEslintrc, extensions - 'extensions' has been removed.
✓ Linting and checking validity of type
"next": "^14.2.0",
"eslint-config-next": "^14.2.0",
"eslint": "^9.0.0",
{
  "extends": "next/core-web-vitals"
}

@elmarsto
Copy link

Bumping this, it is breaking package update automation at my corp

@GabenGar
Copy link
Contributor

GabenGar commented Apr 16, 2024

Yeah it's breaking change because ESLint 9.0.0 is a major release with a ton of breaking changes. You better hope NextJS didn't adhoc around every single ESLint implementation detail, so the migration to the newest version wouldn't take forever on their end.
For now a "fix" is to update next and eslint-config-next to 14.2.1 which limits the range of required ESLint version to eslint@"^7.23.0 || ^8.0.0" and therefore will crash on install/update instead.

@SukkaW
Copy link
Contributor

SukkaW commented Apr 17, 2024

IMHO, the adoption should be done gradually in the following steps:

  • Migrate eslint-config-next, so it exposes both the legacy eslintrc config and the new flat config.
  • Change Next.js internal ESLint implementation, allows it to accept both the legacy config .eslintrc and the new flat config eslint.config.js.
  • Change next lint so that it can accept eslint.config.js
  • Change create-next-app built-in template to use eslint.config.js
  • Change Next.js example to use eslint.config.js

@BnAmN
Copy link

BnAmN commented Apr 17, 2024

IMHO, the adoption should be done gradually in the following steps:

  • Migrate eslint-config-next, so it exposes both the legacy eslintrc config and the new flat config.

  • Change Next.js internal ESLint implementation, allows it to accept both the legacy config .eslintrc and the new flat config eslint.config.js.

  • Change next lint so that it can accept eslint.config.js

  • Change create-next-app built-in template to use eslint.config.js

  • Change Next.js example to use eslint.config.js

I would like to add that the new flat config file can have multiple names:

  • eslint.config.js
  • eslint.config.mjs
  • eslint.config.cjs

Source: https://eslint.org/docs/latest/use/configure/configuration-files#configuration-file

@JJozef
Copy link

JJozef commented Apr 21, 2024

Same error

image

package.json

"dependencies": {
    "next": "14.2.2"
},
"devDependencies": {
    "eslint": "^9.1.0",
    "eslint-config-next": "14.2.2"
}

.eslintrc.json

{
  "extends": ["next/core-web-vitals", "./node_modules/standard/eslintrc.json"],
  "rules": {
    "space-before-function-paren": "off"
  }
}

deploy

image

@Willem-Jaap
Copy link
Contributor

Not a fix but you can ignore eslint during build like so:

// next.config.js
module.exports = {
  eslint: {
    // Warning: This allows production builds to successfully complete even if
    // your project has ESLint errors.
    ignoreDuringBuilds: true,
  },
}

This way you have manual control over eslint, you can run a custom linting config before build.

@JJozef
Copy link

JJozef commented Apr 21, 2024

Not a fix but you can ignore eslint during build like so:

// next.config.js
module.exports = {
  eslint: {
    // Warning: This allows production builds to successfully complete even if
    // your project has ESLint errors.
    ignoreDuringBuilds: true,
  },
}

This way you have manual control over eslint, you can run a custom linting config before build.

I went back to version "eslint": "^8.41.0" and the error stopped.

@mirasayon
Copy link
Contributor

Same error

Screenshot 2024-04-22 204334

.eslintrc.json :
{ "extends": "next/core-web-vitals" }

I updated all the packages to the latest version but this still does not solve the problem

I don’t want to go back to the old version to fix it. If anyone knows how to solve the problem without going to the old version, please help me 🙏

@GabenGar
Copy link
Contributor

The only package update of relevance is eslint-config-next, which is tied to the version of next, aka wait for one of the newest nextjs versions. Until then you have to stick to old one.

@dalindev
Copy link

dalindev commented Apr 25, 2024

Same issue here, I thought I was crazy. Downgrade to an old version for now... 🤖 😸

devDependencies:
- eslint 9.1.1
+ eslint 8.57.0 (9.1.1 is available)

@sebalaini
Copy link

having the same problem here, I have a custom-shared lint config and my latest PR when linked locally to test it it fails, sebalaini/sebalaini-lints-config#6

@GabenGar
Copy link
Contributor

You will have the same "lock-in" in any hybrid render framework. How do you think server rendering works if not by running a nodejs server to turn the templates into html?

@AlbinoGeek
Copy link

AlbinoGeek commented Aug 11, 2024

You will have the same "lock-in" in any hybrid render framework. How do you think server rendering works if not by running a nodejs server to turn the templates into html?

While the specifics aren't useful to this ticket specifically (I'd be more than happy to move this to gitter.im or whichever platform to discuss in detail) our use-case is not that of server rendering, we never needed that feature to begin with.

We just needed a compile-time rendered React framework, of which there are many options. We deploy PWAs (Progressive Web Apps) and app store applications written in React, which use export type build, which continues to be road-blocked by these server features being opt-out instead of opt-in.

We avoided the nextjs-server features for this reason. So, when we run next export (or set the build type to output: export etc, whatever the syntax happens to be in this version, it changes from version to version); we get static HTML and JS files, which can easily be deployed to run on a CDN itself, inside an APK on a device, inside an EXE on Windows (think: Electron, WailsJS specifically in our case), etc etc etc.

For those following this later: https://nextjs.org/docs/pages/building-your-application/deploying/static-exports

Remember, according to the Docs, this is a supported use-case. Just, half the features do not work when doing so (and this is adaquately documented, I don't have any complaints there specifically.)

@frattaro
Copy link

Maybe the deploy target could be specified up front in the configuration rather than as a build command. That way, a linter can tell you "hey, don't use Image since you don't plan on running the server."

But anyway, I don't feel any pressure to update to eslint 9 so I'd rather wait for the next team than force a workaround.

@SmashingQuasar
Copy link

I have an ESlint configuration that works without problem on Next. The only thing is that it does not embark Next's configuration as it is currently broken. I'm not even sure what is in their configuration and mine enumerates all rules anyways so it's not really a concern. Upgrade to ESlint 9.x is critical in my opinion as the community is moving to it rather quickly and configurations will most likely rely on ESlint 9. This version resolves so many problems with managing configurations that I don't think people will bother maintaining legacy versions for a long time.

@AlbinoGeek
Copy link

AlbinoGeek commented Aug 13, 2024

@AlbinoGeek I don't get it, if you don't need any SSR, why even use an isomorphic framework in the first place? While static export is an officially supported feature, it's also known and pointed out in the docs that a lot of basic features will not work. (Also note that you linked the docs of the pages router, since this is deprecated make sure to switch to the app router.)

We will not be switching to the App Router for existing sites any time soon, as that requires a complete recode. Likewise, as you say, we don't have a reason to use NextJS for future projects, as our use-case is no longer a first-party feature, to be blunt.

@GabenGar
Copy link
Contributor

@tobi1220
Nice try, but app router is less suited for static export than pages router.

@lorand-horvath
Copy link

How could eslint 9 and its configuration get so complicated? It's mind-boggling.

@lyleunderwood
Copy link

lyleunderwood commented Aug 16, 2024

@lorand-horvath That is just the nature of all complex systems. The capacity to fight against this fundamental inertia toward complexity is entirely exceptional.

@SalahAdDin
You did well man, do you have any configuration file or migration tutorial?

Because my strategy was to give up on all next-specific features, it's really just a stock biome setup. Biome has tools to migrate from eslint and prettier that work pretty well. I used that as a starting point, and turned on a bunch more rules from there.

The main thing to note about biome is that it does not yet have any support for custom rules. There are strategies in the planning phase, but still just on the roadmap.

@SalahAdDin
Copy link

@lorand-horvath That is just the nature of all complex systems. The capacity to fight against this fundamental inertia toward complexity is entirely exceptional.

@SalahAdDin
You did well man, do you have any configuration file or migration tutorial?

Because my strategy was to give up on all next-specific features, it's really just a stock biome setup. Biome has tools to migrate from eslint and prettier that work pretty well. I used that as a starting point, and turned on a bunch more rules from there.

The main thing to note about biome is that it does not yet have any support for custom rules. There are strategies in the planning phase, but still just on the roadmap.

Do you recommend biome/oxlint over ESLint? Is it less painful migrating to them than migrating to ESLint 9?

@controversial
Copy link
Contributor

The set of lint rules available in Biome is a tiny fraction of what’s available in the eslint ecosystem, so most people switching have to be ok with dramatically reducing the coverage/effectiveness of their linting (as a tradeoff for lint speed).

@lyleunderwood
Copy link

Yes, that's very true. Because there is no plugin or custom rule support of any kind, biome has no real ecosystem to speak of. The only rules that exist are those that are built into biome.

I would argue, however, that most people switch have to be okay with less available rules as tradeoff for simplicity and speed. I think that complexity vs simplicity is much more a locus of discourse here than slow vs fast (though that's obviously nice as well).

The question is, of course, as always, what is the right tool for the job? And that can only be answered on a case-by-case basis. In my case, I am working on a project with no real frontend team to speak of so I don't have a bunch of complex requirements or custom rules or anything. But I'm sure I will in the future when the team grows further. On the previous project I worked on, which had more frontend team members, I definitely needed all of eslint's functionality. We had plenty of custom rules to help team members write code with consistent style and avoid common pitfalls, which was invaluable. But now, being essentially a one-man frontend team, the main things I need from linting/formatting are speed and simplicity.

I care more about the formatting anyway, as I'm basically familiar with all the relevant linting rules myself already and for some reason getting prettier to work consistently and not thrash in my IDE was a constant struggle.

So for me, at this exact moment in time, with this project, with this team, biome is a great fit.

If I were not in this exact situation or one very much like it, I would just pin eslint to 8 for now and wait for either 1. the eslint 9 mess to be sorted out, or 2. biome to become more mature.

YMMV

@SalahAdDin
Copy link

Yes, that's very true. Because there is no plugin or custom rule support of any kind, biome has no real ecosystem to speak of. The only rules that exist are those that are built into biome.

I would argue, however, that most people switch have to be okay with less available rules as tradeoff for simplicity and speed. I think that complexity vs simplicity is much more a locus of discourse here than slow vs fast (though that's obviously nice as well).

The question is, of course, as always, what is the right tool for the job? And that can only be answered on a case-by-case basis. In my case, I am working on a project with no real frontend team to speak of so I don't have a bunch of complex requirements or custom rules or anything. But I'm sure I will in the future when the team grows further. On the previous project I worked on, which had more frontend team members, I definitely needed all of eslint's functionality. We had plenty of custom rules to help team members write code with consistent style and avoid common pitfalls, which was invaluable. But now, being essentially a one-man frontend team, the main things I need from linting/formatting are speed and simplicity.

I care more about the formatting anyway, as I'm basically familiar with all the relevant linting rules myself already and for some reason getting prettier to work consistently and not thrash in my IDE was a constant struggle.

So for me, at this exact moment in time, with this project, with this team, biome is a great fit.

If I were not in this exact situation or one very much like it, I would just pin eslint to 8 for now and wait for either 1. the eslint 9 mess to be sorted out, or 2. biome to become more mature.

YMMV

Did you guys try OXLint?

@sacru2red
Copy link

sacru2red commented Aug 23, 2024

I recently updated my guide here to use fixupConfigRules instead of fixupPluginRules + a map + a list of deps to patch. This results in a more simple migration & catch-all strategy.

TLDR; Updated minimum necessary changes to run eslint 9 with next.js build flow

  1. npm install -D eslint@latest
  2. Override eslint version and add the necessary changes to scripts in package.json
 ...
   "scripts": {
     "dev": "next dev",
+    "prebuild": "npm run lint",
     "build": "next build",
     "start": "next start",
-    "lint": "next lint"
+    "lint": "eslint ."
   },
   ...
   "devDependencies": {
     ...
     "eslint": "^9.9.0",
     ...
   },
+  "overrides": {
+    "eslint": "^9.9.0"
+  }
  1. Configure next.config.mjs to skip linting phase in next build
/** @type {import('next').NextConfig} */
const nextConfig = {
  eslint: {
    ignoreDuringBuilds: true,
  },
};

export default nextConfig;
  1. npm install @eslint/js @eslint/eslintrc @eslint/compat eslint-plugin-react-hooks@latest -D
  2. Generate your eslint.config.mjs file with npx @eslint/migrate-config .eslintrc.json and call fixupConfigRules
import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";
import { fixupConfigRules } from "@eslint/compat"

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
    baseDirectory: __dirname,
    recommendedConfig: js.configs.recommended,
    allConfig: js.configs.all
});

export default fixupConfigRules([...compat.extends("next/core-web-vitals")]);

Now both npm run lint and npm run build should work using the latest eslint version.

  • This is a starting point for your migration, I recommend adding ignore files, typescript and prettier support as detailed here
  • You might have specific dependency on type compilation, if so you can run next build --experimental-build-mode compile before linting.

This way, you can avoid some headaches.
for followers.

  "overrides": {
-  "eslint": "^9.9.0",
+   "eslint": "$eslint" <-- this means using dependency's value
  }

@hqw567
Copy link

hqw567 commented Aug 26, 2024

@ztanner , is Next.js 15 considering supporting Eslint v9?

@GabenGar
Copy link
Contributor

As long as there green checkmarks in this comment (and the purple ones are not closed with won't fix), the framework is blocked from updating to ESLint 9.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. Linting Related to `next lint` or ESLint with Next.js.
Projects
None yet
Development

No branches or pull requests