Plugin de ESLint

Next.js proporciona un plugin de ESLint, eslint-plugin-next, incluido en la configuración base que permite detectar problemas comunes en una aplicación Next.js.

Referencia

Los conjuntos de reglas recomendados de los siguientes plugins de ESLint se utilizan dentro de eslint-config-next:

Esto tendrá prioridad sobre la configuración de next.config.js.

Reglas

El conjunto completo de reglas es el siguiente:

Habilitado en configuración recomendadaReglaDescripción
Check Icon@next/next/google-font-displayExige el comportamiento de font-display con Google Fonts.
Check Icon@next/next/google-font-preconnectAsegura que se use preconnect con Google Fonts.
Check Icon@next/next/inline-script-idExige el atributo id en componentes next/script con contenido inline.
Check Icon@next/next/next-script-for-gaPrefiere el componente next/script al usar scripts inline para Google Analytics.
Check Icon@next/next/no-assign-module-variablePreviene la asignación a la variable module.
Check Icon@next/next/no-async-client-componentPreviene que los Componentes Cliente sean funciones asíncronas.
Check Icon@next/next/no-before-interactive-script-outside-documentPreviene el uso de la estrategia beforeInteractive de next/script fuera de pages/_document.js.
Check Icon@next/next/no-css-tagsPreviene etiquetas manuales de hojas de estilo.
Check Icon@next/next/no-document-import-in-pagePreviene importar next/document fuera de pages/_document.js.
Check Icon@next/next/no-duplicate-headPreviene el uso duplicado de <Head> en pages/_document.js.
Check Icon@next/next/no-head-elementPreviene el uso del elemento <head>.
Check Icon@next/next/no-head-import-in-documentPreviene el uso de next/head en pages/_document.js.
Check Icon@next/next/no-html-link-for-pagesPreviene el uso de elementos <a> para navegar a páginas internas de Next.js.
Check Icon@next/next/no-img-elementPreviene el uso del elemento <img> debido a un LCP más lento y mayor ancho de banda.
Check Icon@next/next/no-page-custom-fontPreviene fuentes personalizadas solo para páginas.
Check Icon@next/next/no-script-component-in-headPreviene el uso de next/script en el componente next/head.
Check Icon@next/next/no-styled-jsx-in-documentPreviene el uso de styled-jsx en pages/_document.js.
Check Icon@next/next/no-sync-scriptsPreviene scripts síncronos.
Check Icon@next/next/no-title-in-document-headPreviene el uso de <title> con el componente Head de next/document.
Check Icon@next/next/no-typosPreviene errores comunes en funciones de obtención de datos de Next.js
Check Icon@next/next/no-unwanted-polyfillioPreviene polyfills duplicados de Polyfill.io.

Recomendamos usar una integración adecuada para ver advertencias y errores directamente en tu editor de código durante el desarrollo.

Ejemplos

Linting en directorios y archivos personalizados

Por defecto, Next.js ejecutará ESLint para todos los archivos en los directorios pages/, app/, components/, lib/ y src/. Sin embargo, puedes especificar qué directorios usar con la opción dirs en la configuración eslint de next.config.js para builds de producción:

next.config.js
module.exports = {
  eslint: {
    dirs: ['pages', 'utils'], // Solo ejecuta ESLint en los directorios 'pages' y 'utils' durante builds de producción (next build)
  },
}

De manera similar, se pueden usar las banderas --dir y --file con next lint para linting en directorios y archivos específicos:

Terminal
next lint --dir pages --dir utils --file bar.js

Especificando un directorio raíz en un monorepo

Si estás usando eslint-plugin-next en un proyecto donde Next.js no está instalado en tu directorio raíz (como en un monorepo), puedes indicarle a eslint-plugin-next dónde encontrar tu aplicación Next.js usando la propiedad settings en tu .eslintrc:

eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname está disponible desde Node.js v20.11.0
  baseDirectory: import.meta.dirname,
})

const eslintConfig = [
  ...compat.config({
    extends: ['next'],
    settings: {
      next: {
        rootDir: 'packages/my-app/',
      },
    },
  }),
]

export default eslintConfig

rootDir puede ser una ruta (relativa o absoluta), un glob (ej. "packages/*/") o un array de rutas y/o globs.

Deshabilitando la caché

Para mejorar el rendimiento, la información de los archivos procesados por ESLint se almacena en caché por defecto. Esto se guarda en .next/cache o en tu directorio de build definido. Si incluyes reglas de ESLint que dependen de más que el contenido de un solo archivo fuente y necesitas deshabilitar la caché, usa la bandera --no-cache con next lint.

Terminal
next lint --no-cache

Deshabilitando reglas

Si deseas modificar o deshabilitar cualquier regla proporcionada por los plugins soportados (react, react-hooks, next), puedes cambiarlas directamente usando la propiedad rules en tu .eslintrc:

eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname está disponible desde Node.js v20.11.0
  baseDirectory: import.meta.dirname,
})

const eslintConfig = [
  ...compat.config({
    extends: ['next'],
    rules: {
      'react/no-unescaped-entities': 'off',
      '@next/next/no-page-custom-font': 'off',
    },
  }),
]

export default eslintConfig

Con Core Web Vitals

El conjunto de reglas next/core-web-vitals se habilita cuando next lint se ejecuta por primera vez y se selecciona la opción strict.

eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname está disponible desde Node.js v20.11.0
  baseDirectory: import.meta.dirname,
})

const eslintConfig = [
  ...compat.config({
    extends: ['next/core-web-vitals'],
  }),
]

export default eslintConfig

next/core-web-vitals actualiza eslint-plugin-next para marcar como error varias reglas que son advertencias por defecto si afectan a Core Web Vitals.

El punto de entrada next/core-web-vitals se incluye automáticamente para nuevas aplicaciones creadas con Create Next App.

Con TypeScript

Además de las reglas de ESLint de Next.js, create-next-app --typescript también agregará reglas específicas de TypeScript con next/typescript a tu configuración:

eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname está disponible desde Node.js v20.11.0
  baseDirectory: import.meta.dirname,
})

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

export default eslintConfig

Esas reglas están basadas en plugin:@typescript-eslint/recommended. Consulta typescript-eslint > Configs para más detalles.

Con Prettier

ESLint también incluye reglas de formato de código, que pueden entrar en conflicto con tu configuración existente de Prettier. Recomendamos incluir eslint-config-prettier en tu configuración de ESLint para que ESLint y Prettier trabajen juntos.

Primero, instala la dependencia:

Terminal
npm install --save-dev eslint-config-prettier

yarn add --dev eslint-config-prettier

pnpm add --save-dev eslint-config-prettier

bun add --dev eslint-config-prettier

Luego, agrega prettier a tu configuración existente de ESLint:

eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname está disponible desde Node.js v20.11.0
  baseDirectory: import.meta.dirname,
})

const eslintConfig = [
  ...compat.config({
    extends: ['next', 'prettier'],
  }),
]

export default eslintConfig

Ejecutando lint en archivos staged

Si deseas usar next lint con lint-staged para ejecutar el linter en archivos git staged, deberás agregar lo siguiente al archivo .lintstagedrc.js en la raíz de tu proyecto para especificar el uso de la bandera --file.

.lintstagedrc.js
const path = require('path')

const buildEslintCommand = (filenames) =>
  `next lint --fix --file ${filenames
    .map((f) => path.relative(process.cwd(), f))
    .join(' --file ')}`

module.exports = {
  '*.{js,jsx,ts,tsx}': [buildEslintCommand],
}

Deshabilitando linting durante builds de producción

Si no deseas que ESLint se ejecute durante next build, puedes configurar la opción eslint.ignoreDuringBuilds en next.config.js a true:

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  eslint: {
    // Advertencia: Esto permite que los builds de producción se completen exitosamente incluso si
    // tu proyecto tiene errores de ESLint.
    ignoreDuringBuilds: true,
  },
}

export default nextConfig

Migrando configuraciones existentes

Si ya tienes ESLint configurado en tu aplicación, recomendamos extender directamente desde este plugin en lugar de incluir eslint-config-next a menos que se cumplan algunas condiciones.

Conjunto de reglas recomendado del plugin

Si las siguientes condiciones son verdaderas:

  • Tienes uno o más de los siguientes plugins ya instalados (ya sea por separado o a través de una configuración diferente como airbnb o react-app):
    • react
    • react-hooks
    • jsx-a11y
    • import
  • Has definido parserOptions específicos que son diferentes a cómo está configurado Babel dentro de Next.js (esto no se recomienda a menos que hayas personalizado tu configuración de Babel)
  • Tienes eslint-plugin-import instalado con resolvers de Node.js y/o TypeScript definidos para manejar imports

Entonces recomendamos eliminar estas configuraciones si prefieres cómo se han configurado estas propiedades dentro de eslint-config-next o extender directamente desde el plugin de ESLint de Next.js:

module.exports = {
  extends: [
    //...
    'plugin:@next/next/recommended',
  ],
}

El plugin se puede instalar normalmente en tu proyecto sin necesidad de ejecutar next lint:

Terminal
npm install --save-dev @next/eslint-plugin-next

yarn add --dev @next/eslint-plugin-next

pnpm add --save-dev @next/eslint-plugin-next

bun add --dev @next/eslint-plugin-next

Esto elimina el riesgo de colisiones o errores que pueden ocurrir al importar el mismo plugin o parser a través de múltiples configuraciones.

Configuraciones adicionales

Si ya utiliza una configuración separada de ESLint y desea incluir eslint-config-next, asegúrese de que se extienda al final, después de otras configuraciones. Por ejemplo:

eslint.config.mjs
import js from '@eslint/js'
import { FlatCompat } from '@eslint/eslintrc'

const compat = new FlatCompat({
  // import.meta.dirname está disponible a partir de Node.js v20.11.0
  baseDirectory: import.meta.dirname,
  recommendedConfig: js.configs.recommended,
})

const eslintConfig = [
  ...compat.config({
    extends: ['eslint:recommended', 'next'],
  }),
]

export default eslintConfig

La configuración next ya maneja los valores predeterminados para las propiedades parser, plugins y settings. No es necesario volver a declarar manualmente ninguna de estas propiedades a menos que necesite una configuración diferente para su caso de uso.

Si incluye otras configuraciones compartibles, deberá asegurarse de que estas propiedades no se sobrescriban ni modifiquen. De lo contrario, recomendamos eliminar cualquier configuración que comparta comportamiento con la configuración next o extender directamente desde el plugin ESLint de Next.js como se mencionó anteriormente.