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.js does not pick up external eslint config #67596

Closed
EliasVal opened this issue Jul 9, 2024 · 18 comments · Fixed by #71298
Closed

Next.js does not pick up external eslint config #67596

EliasVal opened this issue Jul 9, 2024 · 18 comments · Fixed by #71298
Labels
bug Issue was opened via the bug report template. Developer Experience Issues related to Next.js logs, Error overlay, etc. Linting Related to `next lint` or ESLint with Next.js. locked

Comments

@EliasVal
Copy link

EliasVal commented Jul 9, 2024

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/serene-napier-go8s7s

To Reproduce

  1. Set up monorepo (pnpm workspaces)
  2. Have a root eslint config file (with settings.next.rootDir set as per docs)
  3. Run next lint

Current vs. Expected behavior

Currently, when running next lint with the above reproduction steps, next tries to go through eslint config setup.
Expected Behaviour: For next lint to pick up the root eslint config, possibly through an option in next.config.js

Provide environment information

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Pro
  Available memory (MB): 32457
  Available CPU cores: 24
Binaries:
  Node: 20.12.2
  npm: N/A
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 15.0.0-canary.53 // There is a newer canary version (15.0.0-canary.59) available, please upgrade!
  eslint-config-next: 15.0.0-canary.54
  react: 19.0.0-rc-58af67a8f8-20240628
  react-dom: 19.0.0-rc-58af67a8f8-20240628
  typescript: 5.4.5
Next.js Config:
  output: N/A

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

Developer Experience, Linting

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

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

Additional context

Unfortunately, I can't link to a reproduction environment, since company policy is tight on keeping the repo private, and setting a monorepo again is gonna be hell for me 😅

@EliasVal EliasVal added the bug Issue was opened via the bug report template. label Jul 9, 2024
@github-actions github-actions bot added Developer Experience Issues related to Next.js logs, Error overlay, etc. Linting Related to `next lint` or ESLint with Next.js. labels Jul 9, 2024
@EliasVal
Copy link
Author

EliasVal commented Jul 9, 2024

I think it'd be a good idea to display the file structure of the repo:

/
  - apps
    - next-project
    
  eslint.config.mjs
  tsconfig.json

@devjiwonchoi
Copy link
Member

devjiwonchoi commented Oct 14, 2024

Hi, are you using ESLint v9 newly added eslint.config.mjs?

@EliasVal
Copy link
Author

Hi, yes I am. Now it says that "⚠ The Next.js plugin was not detected in your ESLint configuration. See https://nextjs.org/docs/basic-features/eslint#migrating-existing-config".

This is (part of) my eslint.config.mjs:

export default [
  includeIgnoreFile(gitignorePath)
  , ...compat.extends(
    'plugin:react/recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:@next/next/recommended',
    'plugin:jsx-a11y/recommended',
    'plugin:react-hooks/recommended',
    'plugin:tailwindcss/recommended'
  ), {
    plugins: {
      react,
      '@typescript-eslint': typescriptEslint,
      'simple-import-sort': simpleImportSort,
      'jsx-a11y': jsxA11Y,
      '@next/next': nextEslintPluginNext,
      '@stylistic': stylistic,
      'unused-imports': unusedImports,
      'node-import': nodeImport,
      'react-compiler': reactCompiler,
    }
  }
]

@devjiwonchoi
Copy link
Member

We shipped support for ESLint v9 at #71218 https://github.com/vercel/next.js/releases/tag/v15.0.0-canary.191 could you check if it works on that version? The next release will include this change.

@EliasVal
Copy link
Author

EliasVal commented Oct 15, 2024

I am using ESLint v9 in my project with latest canary, just haven't updated the reproduction repo

@devjiwonchoi
Copy link
Member

devjiwonchoi commented Oct 15, 2024

You mean installed version >= v15.0.0-canary.191 (release) does not pick up eslint.config.mjs?

@EliasVal
Copy link
Author

That's correct! I have Next.js v15.0.0-canary.191, along with @next/eslint-plugin-next and it does not pick up eslint.config.mjs in the root of the monorepo

@aXenDeveloper
Copy link

@EliasVal
Copy link
Author

I'm getting that exact error, for now, I opted into not running next lint, setting eslint.ignoreDuringBuilds: true in the next config file, and instead just running ESlint directly

@devjiwonchoi
Copy link
Member

Thank you so much for reporting! Identified the issue, will fix ASAP!

@devjiwonchoi
Copy link
Member

devjiwonchoi commented Oct 15, 2024

Hi, v15.0.0-canary.192 (release) works on mine, could you guys try if it works? Thank you!

@aXenDeveloper
Copy link

Works fine. Thanks @devjiwonchoi !

@ajayvignesh01
Copy link

ajayvignesh01 commented Oct 21, 2024

I have this issue still in my turborepo with root eslint.config.mjs on next15.0.0-canary.201:

import { FlatCompat } from '@eslint/eslintrc'
import reactCompiler from 'eslint-plugin-react-compiler'
import path from 'path'
import { fileURLToPath } from 'url'

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

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

/** @type {import('eslint').Linter.Config[]} */
const config = [
  ...compat.extends('next/core-web-vitals', 'next/typescript', 'prettier'),
  {
    languageOptions: {
      parserOptions: {
        project: ['./apps/*/tsconfig.json', './packages/*/tsconfig.json'],
      },
    },
    settings: {
      next: {
        rootDir: ['./apps/*'],
      },
      'import/resolver': {
        typescript: {
          project: ['./apps/*/tsconfig.json', './packages/*/tsconfig.json'],
        },
      },
    },

    plugins: {
      'react-compiler': reactCompiler,
    },
    rules: {
      'react-compiler/react-compiler': 'error',
    },
  },
  {
    ignores: [
      '**/node_modules/',
      '**/.git/',
      '**/eslint.config.mjs',
      '**/prettier.config.mjs',
      '**/postcss.config.mjs',
      '**/.next/',
      '**/.turbo',
      '**/dist/',
    ],
  },
]

export default config

Notice that I have the ignore in a separate config object. This is because it needs to act as a global ignore pattern (more details on eslint docs & eslint/eslint#18304) , and the only way to do so is by having it separate. I need this so that I can run eslint as a root task and correctly ignore all necessary files. When I place ignores within the main object along with languageSettings & import/resolver , some .next files are not ignored and throw eslint errors. Additionally, postcss.config.mjs needs to be ignored in all apps/packages, and this requires it to be defined in the global ignore config object.

With this though, The Next.js plugin was not detected in your ESLint configuration. issue comes back. I tried rearranging my ignore config object order, but that didn't do anything. Removing the config object with ignore resolves the issue, but then my root eslint task throws errors as mentioned earlier.

@ajayvignesh01
Copy link

Quick follow up after today's Next.js 15 stable release. Updated deps, and now getting one additional warning.

  1. The Next.js plugin was not detected in your ESLint configuration. See https://nextjs.org/docs/basic-features/eslint#migrating-existing-config
  2. Pages directory cannot be found at . If using a custom path, please configure with the no-html-link-for-pages rule in your eslint

./apps/dashboard/package.json

"next": "^15.0.0",
"react": "19.0.0-rc-65a56d0e-20241020",
"react-dom": "19.0.0-rc-65a56d0e-20241020"

./package.json

"@eslint/eslintrc": "^3.1.0",
"eslint": "^9.13.0",
"eslint-config-next": "^15.0.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-react-compiler": "^19.0.0-beta-8a03594-20241020",

turbo.json

{
  "$schema": "https://turbo.build/schema.json",
  "ui": "tui",
  "tasks": {
    "build": {
      "dependsOn": ["^build"],
      "inputs": ["$TURBO_DEFAULT$", ".env*"],
      "outputs": [".next/**", "!.next/cache/**"]
    },
    "lint": {
      "dependsOn": ["^lint"],
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

When I run turbo run lint. I get the following output:

ajay@Ajays-MacBook-Air lydar % turbo run lint
turbo 2.2.3

• Packages in scope: @lydar/typescript-config, @lydar/ui, dashboard
• Running lint in 3 packages
• Remote caching disabled
┌ @lydar/ui#lint > cache bypass, force executing 819aca1c10819e08
│
│ $ eslint .
│ Pages directory cannot be found at . If using a custom path, please configure with the `no-html-link-for-pages` rule in your eslint
│  config file.
└────>
┌ dashboard#lint > cache bypass, force executing ef97ccb46db11590
│
│ $ next lint
│
│  ⚠ The Next.js plugin was not detected in your ESLint configuration. See https://nextjs.org/docs/basic-features/eslint#migrating-ex
│ isting-config
│ Pages directory cannot be found at . If using a custom path, please configure with the `no-html-link-for-pages` rule in your eslint
│  config file.
│ ✔ No ESLint warnings or errors
└────>

 Tasks:    2 successful, 2 total
Cached:    0 cached, 2 total
  Time:    3.088s

Removing the ignore config object gets rid of both warnings for apps/dashboad but still shows the one warning for packages/ui
If I additionally remove this as well...

next: {
      rootDir: ['./apps/*'],
    },

No warnings are shown in entire lint process

@devjiwonchoi
Copy link
Member

Hey @ajayvignesh01, thank you for reporting! Though the issue seems to need some setups to reproduce, can you open a new issue with a minimum reproduction? Feel free to ping me there, I'm happy to help!

@ajayvignesh01
Copy link

Sure @devjiwonchoi. I will try to get one out later tonight!

@ajayvignesh01
Copy link

Hey @devjiwonchoi

So I created a reproduction - https://github.com/ajayvignesh01/turborepo-next-15

And it looks like customizing the @next/next/no-html-link-for-pages with that ['.'] seems to fix things. Not sure if this is hacky or if that's how it is intended to be. Relevant docs - https://nextjs.org/docs/messages/no-html-link-for-pages#options

eslint.config.mjs

import { FlatCompat } from '@eslint/eslintrc'
import eslintConfigPrettier from 'eslint-config-prettier'
import reactCompiler from 'eslint-plugin-react-compiler'

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

/** @type {import('eslint').Linter.Config[]} */
const config = [
  // defaults
  ...compat.extends('next/core-web-vitals', 'next/typescript'),

  // typescript-eslint
  {
    files: ['**/*.ts?(x)'],
    languageOptions: {
      parserOptions: {
        // project: ['./apps/*/tsconfig.json', './packages/*/tsconfig.json'],
        projectService: true, // achieves same thing as above
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },

  // next & import-resolver-typescript
  {
    settings: {
      next: {
        rootDir: ['./apps/*'],
      },
      'import/resolver': {
        typescript: {
          project: ['./apps/*/tsconfig.json', './packages/*/tsconfig.json'],
        },
      },
    },

    rules: {
      '@next/next/no-html-link-for-pages': ['error', ['.']],
    },
  },

  // react-compiler
  {
    plugins: {
      'react-compiler': reactCompiler,
    },
    rules: {
      'react-compiler/react-compiler': 'error',
    },
  },

  // prettier
  eslintConfigPrettier,

  // global ignores
  {
    ignores: ['**/node_modules/', '**/.git/', '**/.next/', '**/dist/', '**/.turbo'],
  },
]

export default config

Lmk if you want me to open a new issue still!

Copy link
Contributor

github-actions bot commented Nov 8, 2024

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot added the locked label Nov 8, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. Developer Experience Issues related to Next.js logs, Error overlay, etc. Linting Related to `next lint` or ESLint with Next.js. locked
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants