Integración de ESLint + Prettier
Haz que ESLint y Prettier funcionen juntos sin conflictos separando conceptos: ESLint para calidad de código, Prettier para formateo.
Receta
Tarjeta de receta de referencia rápida — lista para copiar y pegar.
# Instala el paquete de compatibilidad
npm install --save-dev eslint-config-prettier
# Eso es todo — no se necesita eslint-plugin-prettier// package.json scripts (ejecútalos por separado)
{
"scripts": {
"lint": "next lint",
"lint:fix": "next lint --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"check-all": "npm run format:check && npm run lint"
}
}Cuándo usarlo: En cualquier proyecto que use ESLint y Prettier (que es la mayoría de proyectos React/Next.js).
Ejemplo Funcional
// eslint.config.mjs
import { FlatCompat } from "@eslint/eslintrc";
import { dirname } from "path";
import { fileURLToPath } from "url";
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",
"prettier", // Debe ser LAST — desactiva las reglas de formateo de ESLint
),
{
rules: {
// Reglas de calidad de código (no formateo) — estos no entrarán en conflicto
"@typescript-eslint/no-unused-vars": [
"error",
{ argsIgnorePattern: "^_" },
],
"react-hooks/exhaustive-deps": "warn",
"import/order": [
"warn",
{
groups: ["builtin", "external", "internal"],
"newlines-between": "always",
},
],
},
},
];
export default eslintConfig;// .prettierrc
{
"semi": true,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 80,
"plugins": ["prettier-plugin-tailwindcss"]
}Lo que esto demuestra:
eslint-config-prettier(la extensión"prettier") desactiva todas las reglas de ESLint que entran en conflicto con Prettier- ESLint maneja solo la calidad de código (variables no utilizadas, dependencias de hooks, orden de imports)
- Prettier maneja solo el formateo (puntos y comas, comillas, indentación)
- Scripts npm separados para cada herramienta
Análisis Profundo
Cómo Funciona
- ESLint tiene reglas de formateo (por ejemplo,
indent,semi,quotes) y reglas de calidad de código (por ejemplo,no-unused-vars,react-hooks/exhaustive-deps) - Prettier también controla el formateo, así que las dos herramientas luchan por los mismos archivos
eslint-config-prettierdesactiva cada regla de ESLint que Prettier maneja, eliminando conflictos- Debe ser el último elemento en
extendspara anular todas las configuraciones anteriores
Variaciones
Por qué NO usar eslint-plugin-prettier:
// ❌ Este enfoque ejecuta Prettier dentro de ESLint
// eslint-plugin-prettier — NO recomendado
{
plugins: ["prettier"],
rules: {
"prettier/prettier": "error",
},
}Problemas con este enfoque:
- Cada problema de formateo aparece como un error de ESLint, produciendo salida ruidosa
- El linting se vuelve significativamente más lento porque Prettier se ejecuta dentro de ESLint
- Las líneas rojas onduladas en cada problema de formateo saturan el editor
- Dos herramientas haciendo el mismo trabajo en el mismo proceso
Enfoque recomendado: ejecútalas por separado:
{
"scripts": {
"lint": "next lint",
"lint:fix": "next lint --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"fix-all": "npm run lint:fix && npm run format"
}
}Enfoque con hooks de pre-commit (lo mejor de ambos mundos):
// package.json
{
"lint-staged": {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{css,json,md}": ["prettier --write"]
}
}Notas de TypeScript
// Ambas herramientas funcionan sin problemas en archivos .ts y .tsx.
// ESLint detecta problemas conscientes del tipo:
const unused = "hello"; // @typescript-eslint/no-unused-vars ❌
// Prettier maneja el formateo:
const obj = { a: 1, b: 2, c: 3 }; // Prettier controla espaciado, comas finales, etc.
// Sin superposición — cada herramienta hace su trabajo.Trampas
Cosas que te causarán problemas. Cada trampa incluye qué sale mal, por qué sucede y la solución.
-
El orden de la configuración importa — Si
"prettier"no es el último elemento enextends, las reglas de formateo de ESLint de configuraciones posteriores se volverán a habilitar y entrarán en conflicto. Solución: Siempre pon"prettier"al final en tu array de extends. -
Verificar conflictos — No estás seguro si una regla entra en conflicto. Solución: Ejecuta
npx eslint-config-prettier 'src/**/*.tsx'para listar las reglas que entran en conflicto con Prettier. La herramienta CLI reporta exactamente qué reglas desactivar. -
Formateo diferente en CI vs local — Si los desarrolladores no tienen habilitado el formateo al guardar, CI detecta errores de formateo que nunca vieron. Solución: Usa Husky + lint-staged para formatear automáticamente antes de cada commit.
-
El orden de imports no es formateo —
import/orderes una regla de calidad de código que Prettier no maneja (Prettier no reordena imports). Solución: Manténimport/orderen ESLint; no entra en conflicto con Prettier. Alternativamente, usaprettier-plugin-organize-imports.
Alternativas
Otras formas de resolver el mismo problema — y cuándo cada una es la mejor opción.
| Alternativa | Usalo Cuando | No lo Uses Cuando |
|---|---|---|
| Biome | Quieres linting + formateo en una herramienta sin conflictos | Necesitas el ecosistema de plugins de ESLint |
| Solo Prettier (sin ESLint) | Proyecto muy pequeño sin preocupaciones de calidad de código | Quieres detectar bugs, variables no utilizadas o violaciones de hooks |
| Solo ESLint (con reglas de formateo) | Te niegas a agregar otra herramienta | Quieres formateo consistente y opinionado |
FAQs
¿Qué hace realmente eslint-config-prettier?
- Desactiva cada regla de ESLint que entra en conflicto con Prettier.
- No añade ninguna regla nueva.
- Debe ser el último elemento en
extendspara anular todas las configuraciones anteriores.
¿Por qué eslint-plugin-prettier no es recomendado?
- Ejecuta Prettier dentro de ESLint, haciendo el linting significativamente más lento.
- Cada problema de formateo aparece como un error de ESLint, produciendo salida ruidosa.
- Las líneas rojas onduladas en cada diferencia de formateo saturan el editor.
- Ejecutar las herramientas por separado es más limpio y rápido.
Trampa: ¿Qué sucede si "prettier" no es el último elemento en extends?
- Las reglas de formateo de ESLint de configuraciones listadas después de
"prettier"se volverán a habilitar. - Esto causa conflictos donde ESLint y Prettier luchan por el mismo formateo.
- Siempre pon
"prettier"al final en tu array de extends.
¿Cómo verifico qué reglas de ESLint entran en conflicto con Prettier?
npx eslint-config-prettier 'src/**/*.tsx'Esta herramienta CLI reporta exactamente qué reglas activas entran en conflicto con Prettier.
¿Entra import/order en conflicto con Prettier?
- No. Prettier no reordena imports.
import/orderes una regla de calidad de código, no una regla de formateo.- Mantenla en ESLint; funciona junto a Prettier sin conflictos.
¿Cuál es la forma recomendada de ejecutar ambas herramientas?
{
"scripts": {
"lint": "next lint",
"lint:fix": "next lint --fix",
"format": "prettier --write .",
"format:check": "prettier --check .",
"fix-all": "npm run lint:fix && npm run format"
}
}Ejecútalas como comandos separados, no como una herramienta combinada.
¿Cómo configuro hooks de pre-commit para ejecutar ESLint y Prettier?
{
"lint-staged": {
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{css,json,md}": ["prettier --write"]
}
}ESLint corrige problemas de calidad de código primero, luego Prettier formatea.
Trampa: ¿Por qué veo formateo diferente en CI versus localmente?
- Los desarrolladores sin formateo al guardar habilitado ven errores de formateo solo en CI.
- Usa Husky + lint-staged para formatear automáticamente antes de cada commit.
- Esto asegura que el código comprometido siempre esté formateado, independientemente de la configuración del editor.
¿Afecta eslint-config-prettier a las reglas específicas de TypeScript?
- Solo desactiva las reglas relacionadas con formateo (indentación, espaciado, comillas).
- Las reglas de calidad de código de TypeScript como
@typescript-eslint/no-unused-varsno se ven afectadas. - Las reglas conscientes del tipo permanecen totalmente activas.
¿Puedo usar Prettier para formateo y ESLint para linting consciente del tipo de TypeScript?
- Sí. Esta es la configuración recomendada.
- ESLint maneja la calidad de código (variables no utilizadas, dependencias de hooks, verificaciones conscientes del tipo).
- Prettier maneja el formateo (puntos y comas, comillas, indentación).
eslint-config-prettierasegura que no haya superposición entre los dos.
¿Qué hace el script check-all?
npm run format:check && npm run lintformat:checkverifica que los archivos estén formateados sin modificarlos.lintejecuta ESLint para la calidad de código.- Úsalo en CI para validar sin auto-reparar.
Relacionado
- Configuración de ESLint para Next.js — configuración base de ESLint
- Configuración de Prettier — configuración de Prettier y opciones
- Husky & lint-staged — auto-formatear en commit
- Linting en CI/CD — aplicar ambos en CI