ESLint para scripts de Node.js
Configura ESLint con flat config (eslint.config.js) para proyectos de scripts de Node.js con soporte de TypeScript, reglas específicas de Node.js y linting con conciencia de tipos.
Busca en todas las páginas de la documentación
Configura ESLint con flat config (eslint.config.js) para proyectos de scripts de Node.js con soporte de TypeScript, reglas específicas de Node.js y linting con conciencia de tipos.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
# Inicializa una nueva configuración de ESLint de forma interactiva
npm init @eslint/config@latest
# Instala el conjunto de herramientas central para un proyecto de script de Node.js con TypeScript
npm install --save-dev \
eslint \
typescript-eslint \
eslint-plugin-n \
globals
# Lint en tus scripts
npx eslint .
# Lint y auto-corregir
npx eslint . --fixCuándo usarlo: Cualquier proyecto de Node.js independiente - CLIs, scripts de construcción, automatización, o paquetes de herramientas de monorepo - que vive fuera de una aplicación Next.js/React.
// eslint.config.js
import js from "@eslint/js";
import tseslint from "typescript-eslint";
import nodePlugin from "eslint-plugin-n";
import globals from "globals";
export default tseslint.config(
// Los ignores globales - deben ser la única clave en su propio objeto
{
ignores: ["dist/", "build/", "coverage/", "node_modules/"],
},
// Reglas de JS base
js.configs.recommended,
// Reglas recomendadas del plugin de Node.js (preset de flat config)
nodePlugin.configs["flat/recommended-script"],
// Reglas de TypeScript con verificación de tipos
...tseslint.configs.strictTypeChecked,
...tseslint.configs.stylisticTypeChecked,
{
files: ["**/*.ts", "**/*.mts"],
languageOptions: {
globals: globals.nodeBuiltin,
parserOptions: {
project: "./tsconfig.json",
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
// Aplica async/await sobre cadenas de promesas sin procesar
"promise/prefer-await-to-then": "off",
"@typescript-eslint/no-floating-promises": "error",
"@typescript-eslint/no-misused-promises": "error",
"@typescript-eslint/return-await": ["error", "always"],
// Reglas del plugin de Node.js
"n/no-missing-import": "off", // typescript-eslint resuelve importaciones
"n/no-unpublished-import": "off",
"n/no-process-exit": "warn",
},
},
);Lo que esto demuestra:
tseslint.config() para la autoría de configuración con seguridad de tiposstrictTypeChecked + stylisticTypeChecked para las reglas de TS más rigurosaseslint-plugin-n (el fork mantenido de eslint-plugin-node) que proporciona reglas específicas de Node.jsparserOptions.projecteslint.config.js (flat config) desde la raíz del proyecto de forma predeterminada - no más archivos .eslintrc en cascada.typescript-eslint se envía como un paquete único que re-exporta @typescript-eslint/parser, @typescript-eslint/eslint-plugin, y un helper config() que concatena y tipifica objetos de configuración.eslint-plugin-n reemplaza el abandonado eslint-plugin-node. Agrega reglas específicas de Node.js como n/no-missing-import, n/no-unpublished-bin, y n/no-deprecated-api.TypeChecked) requieren que el parser cargue tsconfig.json vía parserOptions.project. Sin él, esas reglas no hacen nada silenciosamente.tsconfigRootDir: import.meta.dirname asegura que la ruta project se resuelva relativa al archivo de configuración, no al directorio de trabajo actual.Configuración solo JavaScript (sin TypeScript):
// eslint.config.js
import js from "@eslint/js";
import nodePlugin from "eslint-plugin-n";
import globals from "globals";
export default [
js.configs.recommended,
nodePlugin.configs["flat/recommended-script"],
{
languageOptions: {
ecmaVersion: "latest",
sourceType: "module",
globals: globals.nodeBuiltin,
},
},
];Linting con conciencia de tipos con un tsconfig dedicado:
{
files: ["**/*.ts"],
languageOptions: {
parserOptions: {
project: "./tsconfig.eslint.json",
tsconfigRootDir: import.meta.dirname,
},
},
}Integración con Prettier (desactiva reglas de estilo que entran en conflicto):
npm install --save-dev eslint-config-prettierimport prettier from "eslint-config-prettier";
export default tseslint.config(
js.configs.recommended,
...tseslint.configs.recommended,
prettier, // debe ser ÚLTIMO - desactiva reglas de estilo conflictivas
);Ignores con alcance para archivos generados:
{
ignores: ["**/*.generated.ts", "src/proto/**"],
}@typescript-eslint/parser se instala transitivamente a través del meta-paquete typescript-eslint - raramente necesitas importarlo directamente.no-floating-promises y no-misused-promises son esenciales para scripts de Node.js donde los rechazos silenciosos sin manejar pueden corromper el estado....tseslint.configs.strictTypeChecked - atrapa errores reales como no-unnecessary-condition y no-unsafe-argument.tseslint.config() proporciona autocompletado y errores de tipo si escribes mal un nombre de regla u opción.Cosas que te morderán. Cada gotcha incluye qué sale mal, por qué sucede, y la solución.
Confusión entre flat config y .eslintrc heredado - ESLint 9+ usa flat config de forma predeterminada. Si aún tienes un .eslintrc.json en el proyecto, ESLint lo ignora silenciosamente una vez que eslint.config.js existe. Solución: Elimina todos los archivos heredados cuando migres y verifica con npx eslint --print-config path/to/file.ts.
Falta parserOptions.project desactiva reglas con conciencia de tipos - Las reglas de strictTypeChecked o stylisticTypeChecked requieren que se cargue el programa de TypeScript. Sin project, lanzan en tiempo de ejecución o pasan silenciosamente. Solución: Siempre establece parserOptions.project y tsconfigRootDir en el bloque de archivos de TS.
eslint-plugin-n reporta falsos positivos para alias de ruta de TS - Las reglas como n/no-missing-import no pueden resolver alias de ruta @/utils definidos en tsconfig.json. Solución: Desactiva n/no-missing-import (y n/no-unpublished-import) cuando uses TypeScript - typescript-eslint ya valida importaciones.
Archivo de configuración ESM en un proyecto CommonJS - Si package.json tiene "type": "commonjs" (o ningún campo type), eslint.config.js con sintaxis import falla al cargar. Solución: Cambia el nombre a eslint.config.mjs O agrega "type": "module" a package.json.
Conflictos entre reglas de Prettier/ESLint - Habilitar reglas de ESLint de estilo junto con Prettier produce auto-correcciones en conflicto. Solución: Agrega eslint-config-prettier como el último elemento en el array de configuración para desactivar reglas conflictivas.
ignores mezclado con otras claves silenciosamente se convierte en un filtro de archivo - En flat config, un objeto con tanto ignores como rules se trata como un filtro, no como un ignore global. Solución: Coloca los ignores globales en su propio objeto { ignores: [...] } sin otras claves.
Otras formas de resolver el mismo problema - y cuándo cada una es la mejor opción.
| Alternativa | Úsalo Cuando | No lo Uses Cuando |
|---|---|---|
| Biome | Quieres una herramienta única basada en Rust rápida para lint + format | Necesitas el ecosistema completo de plugins de ESLint o reglas personalizadas |
| oxlint | Quieres velocidad extrema y estás bien con un subconjunto de reglas | Dependes de reglas con conciencia de tipos (aún no soportadas) |
| Deno lint | Estás ejecutando scripts en Deno, no en Node | Apuntas a Node.js |
standard | Quieres cero configuración, valores predeterminados opinados | Necesitas personalizar cualquier regla |
eslint-plugin-node no se mantiene.eslint-plugin-n es el fork mantenido por la comunidad con soporte de flat config.n/ (p. ej. n/no-missing-import).typescript-eslint agrupa el parser y el plugin.typescript-eslint y usa tseslint.config() - cablean ambos juntos.parserOptions.project en la ruta de tu tsconfig.json.parserOptions.tsconfigRootDir en import.meta.dirname....tseslint.configs.strictTypeChecked (o recommendedTypeChecked).project, las reglas con conciencia de tipos lanzan un error o pasan silenciosamente.no-floating-promises atrapa llamadas await olvidadas.no-misused-promises evita pasar funciones asincrónicas donde se esperan callbacks sincronos.no-unsafe-argument atrapa any filtrándose desde dependencias sin tipo.package.json para "type". Si es commonjs o falta, cambia el nombre de la configuración a eslint.config.mjs u agrega "type": "module"..eslintrc heredados se ignoran cuando existe una flat config.npx eslint --print-config somefile.ts para ver qué configuración se carga realmente.n/no-missing-import no puede resolver alias de ruta de TypeScript como @/lib/foo.n/no-missing-import y n/no-unpublished-import en proyectos de TypeScript.typescript-eslint ya verifica importaciones a través del compilador de TypeScript.tseslint.config() - proporciona autocompletado completo y errores de tipo.// @ts-check con JSDoc @type \{import("eslint").Linter.Config[]\}.eslint.config.ts de forma nativa.recommendedTypeChecked es la línea base segura - atrapa errores sin ser demasiado estricto.strictTypeChecked agrega reglas más estrictas como no-unnecessary-condition y prefer-reduce-type-parameter.files: ["scripts/**/*.ts"] y anula reglas dentro de él.eslint-config-prettier solo desactiva reglas de estilo que entran en conflicto con Prettier.files: ["**/*.js"] y otro con files: ["**/*.ts"]..ts para evitar errores en archivos de JS sin tipo.@typescript-eslint/no-floating-promises para atrapar promesas sin manejar.@typescript-eslint/no-misused-promises para desajustes de callback.@typescript-eslint/return-await establecido en "always" para trazas de stack más limpias.Revisado por Chris St. John·Última actualización: 10 jul 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥