Aprender a programar en Javascript (cualquier lenguaje, en realidad) es una tarea que requiere ir perfeccionando continuamente. Una vez aprendemos las bases y fundamentos de Javascript, una estupenda recomendación sería la de usar un linter.
Los linters son herramientas que examinan tu código y te avisan cuando se detectan errores de sintaxis, código incorrecto o malas prácticas. Esto favorece el escribir código de calidad y acostumbra al usuario a solventar carencias o problemas en fases tempranas (y no tan tempranas) y ayudar a corregirlas.
Hay que tener claro que un linter nos ayuda a corregir malos hábitos que desembocan en problemas. Aunque un programa sea válido y funcione, puede estar escrito incorrectamente y ESLint te ayuda a detectar esos errores.
¿Qué es ESLint?
ESLint es un linter para código Javascript. Ayuda a detectar posibles problemas y errores (personalizables por el programador) para que el código Javascript escrito siga unos estándares de calidad, favoreciendo la escritura de código correcto, coherente y consistente. Aunque existen otros linters Javascript (JSHint, JSLint, etc...), ESLint se ha establecido como herramienta estándar de facto.
ESLint es totalmente configurable. Puedes indicarle que criterios (reglas) quieres que use y cuales quieres que ignore, adaptándose a las necesidades de cualquier empresa, programador o equipo de trabajo.
Instalación de ESLint
ESLint requiere como mínimo Node 18.18.0 o superior para funcionar. Siempre recomendamos tener la última versión estable de Node instalada, para lo cuál puedes seguir la Instalación con PNPM o la Instalación de NVM, un control de versiones que hará que la tarea sea muy cómoda y flexible.
El primer paso a realizar es instalar la herramienta ESLint es nuestro proyecto. Esto nos permitirá utilizarla para analizar nuestro código Javascript y detectar problemas. Para instalarla, escribiremos en una terminal el primer comando:
$ npm install -D eslint
$ npx eslint
Oops! Something went wrong! :(
ESLint: 9.13.0
ESLint couldn't find an eslint.config.(js|mjs|cjs) file.
Observa que tras instalar ESLint, intentamos ejecutar npx eslint
pero obtenemos un error. Este error ocurre porque aún no tenemos fichero de configuración de ESLint, que es obligatorio para funcionar. Veamos como crear uno.
Configuración inicial de ESLint
Desde ESLint 9 se usa un formato llamado flat config que es mucho más rápido, extensible y simple. En este tutorial veremos como usar este formato, por lo que debes tener versiones superiores a la 9.
La forma más rápida de configurar ESLint es crear un fichero de configuración eslint.config.mjs
en la carpeta raíz del proyecto. Este fichero contendrá, como mínimo, las siguientes líneas:
import globals from "globals";
import pluginJs from "@eslint/js";
export default [
{ languageOptions: { globals: globals.browser } },
pluginJs.configs.recommended,
];
Ten en cuenta que debes instalar las dependencias anteriores con un npm install -D globals @eslint/js
. Si todo esto se te hace muy complicado, puedes verificar la Configuración manual, donde el asistente de ESLint lo genera por ti.
El siguiente comando permite instalar y ejecutar el asistente @eslint/create-config
de ESLint, que te preguntará varias cuestiones y creará un archivo de configuración.
$ npx eslint --init
Al arrancarse el asistente para configurar ESLint en nuestro proyecto, nos preguntará algunas cuestiones sobre el proyecto a revisar. Hagamos un repaso rápido por las opciones que nos aparecen:
Modo de ESLint
Esta opción nos permite seleccionar el modo en el que funcionará el linter. Se recomienda utilizar la última opción, la más completa de todas:
? How would you like to use ESLint?
To check syntax only
> To check syntax and find problems
La primera opción, revisa sólo la sintaxis de nuestro código. La segunda opción (la recomendada), además ayuda a encontrar potenciales problemas en el código.
Módulos Javascript
Esta opción nos permite seleccionar la forma en la que importamos código Javascript desde otros archivos. Si estamos utilizando las palabras clave import
y/o export
en nuestro código, deberemos seleccionar la primera, ya que estamos utilizando módulos ESM. Si utilizamos una versión antigua de Node, o sigues utilizando require
o module.exports
, deberemos utilizar la segunda.
? What type of modules does your project use?
> JavaScript modules (import/export)
CommonJS (require/exports)
None of these
Si tienes más dudas, echa un vistazo al artículo Diferencias entre módulos ECMAScript (ESM) y CommonJS.
Framework Javascript
Esta opción nos da la posibilidad de indicar si estamos utilizando un framework Javascript específico como React o Vue.js y así poder adaptarse a la sintaxis correspondiente de estos frameworks. Si no fuera el caso, seleccionamos None of these:
? Which framework does your project use?
React
Vue.js
> None of these
Soporte de TypeScript
Si estamos transpilando nuestro código de Typescript a Javascript, podemos indicar en el linter que estamos utilizándolo. De lo contrario, simplemente indicamos que no lo utilizamos.
? Does your project use TypeScript?
> No
Yes
¿Javascript cliente o servidor?
Con esta opción indicamos al linter si el código va dirigido a navegadores (browser) o es código NodeJS. Ojo con esta opción, ya que también podemos marcar ambas (utilizando SPACE):
? Where does your code run?
> Browser
> Node
Instalación de dependencias
Una vez respondidas estas preguntas, nos indicará algo similar a esto:
The config that you've selected requires the following dependencies:
eslint, globals, @eslint/js
? Would you like to install them now? ‣ No / Yes
Seleccionamos la opción Yes
para instalar las dependencias. Al hacerlo, nos preguntará que gestor de paquetes quieres utilizar. La decisión más sencilla y habitual es npm
, aunque personalmente me gusta mucho pnpm
:
? Which package manager do you want to use? …
> npm
yarn
pnpm
bun
Una vez terminado el proceso, generará un fichero de configuración llamado eslint.config.mjs
.
Cómo usar ESLint
Una vez realizados los pasos anteriores, sólo tenemos que ejecutar eslint
, indicando el archivo que queremos analizar. Por ejemplo, vamos a crear el siguiente archivo index.js
con un código Javascript con ciertos problemas de sintaxis intencionados, a ver si es capaz de detectarlos:
let name;
const object = {
name: "Manz",
role: "streamer",
}
object = 34;
const showData = ()=>{
console.log("Data")
}
showData()
Ahora, escribiremos en una terminal el comando npx eslint
seguido del archivo que queremos revisar para que nos avise de los errores que contiene nuestro código:
$ npx eslint index.js
/home/manz/project-test/index.js
1:5 error 'name' is defined but never used no-unused-vars
8:1 error 'object' is constant no-const-assign
8:1 error 'object' is assigned a value but never used no-unused-vars
✖ 3 problems (3 errors, 0 warnings)
Nos ha encontrado tres problemas:
- 💔 La variable
name
se define, pero no se usa nunca. - 💔 La constante
object
se define como constante, pero se intenta cambiar su valor. - 💔 La variable
object
se define, pero no se usa nunca.
También se pueden usar globs como
*.js
o similares. Uno muy interesante es**
que sirve para analizar toda la carpeta y subcarpetas. Por ejemplo,src/**/*.js
buscará todos los ficheros.js
dentro de la carpetasrc
y subcarpetas.
Corregir automáticamente (Autofix)
Una de las características más interesantes de ESLint, es utilizar la característica autofix, es decir, que ESLint no sólo detecte los errores, sino que los corrija automáticamente. Para ello, sólo tenemos que añadir el parámetro --fix
:
$ npx eslint --fix index.js
Esto hará que ESLint revise el archivo y corrija todos los errores posibles de forma automática. Sin embargo, para nosotros lo ideal sería que nos lo corrija dentro de VSCode al guardar, en lugar de hacerlo desde una terminal.
Para conseguir esto, necesitamos «conectar» nuestro VSCode con ESLint:
- Paso 1: Configurar ESLint ✅
- Paso 2: Instalar el plugin ESLint en VSCode
- Paso 3: Configurar VSCode para corregir cuando guardemos
Para realizar este último paso, simplemente pulsamos F1 en VSCode y y escribimos y seleccionamos la opción Open User Settings (JSON). En ese fichero .json
escribimos lo siguiente:
/* ... */
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
/* ... */
Este fragmento de configuración es el equivalente a escribir el comando anterior npx eslint --fix index.js
al guardar el fichero. Recuerda que no todos los errores son autocorregibles, por lo que puede que ciertos errores no se arreglen de forma automática.
Personalizar reglas de ESLint
ESlint funciona con reglas. Las reglas son «criterios» para decidir si el código está haciendo algo correcto o incorrecto. Por defecto, ESLint viene con una serie de reglas definidas en su fichero de configuración. Por defecto usa recommended
, pero podemos cambiar ese recommended
por all
e incluir todas las reglas:
import globals from "globals";
import pluginJs from "@eslint/js";
export default [
{languageOptions: { globals: globals.browser }},
pluginJs.configs.all,
];
Ahora, si ejecutamos nuevamente ESLint encontrará 7 errores, ya que tiene más reglas activadas y está detectando problemas más específicos:
$ npx eslint index.js
/home/manz/project-test/index.js
1:5 error Variable 'name' should be initialized on declaration init-declarations
1:5 error 'name' is defined but never used no-unused-vars
8:1 error 'object' is constant no-const-assign
8:1 error 'object' is assigned a value but never used no-unused-vars
8:10 error No magic number: 34 no-magic-numbers
10:1 error Combine this with the previous 'const' statement one-var
11:5 error Unexpected console statement no-console
✖ 7 problems (7 errors, 0 warnings)
Es decisión del desarrollador definir que nivel o grado utilizar para revisar su código. Observa que a la derecha del error, aparece un texto con el nombre de la regla (init-declarations, no-unused-vars, etc...). Cada una de esas reglas define el comportamiento de una característica. Puedes consultar las reglas existentes en ESLint rules.
Puedes configurar en el fichero de configuración el comportamiento de las reglas para ajustarlo a tu gusto. Vamos a crear un objeto rules
con las reglas que queremos activar y desactivar:
import globals from "globals";
import pluginJs from "@eslint/js";
const rules = {
"no-unused-vars": "off",
"no-magic-numbers": "warn"
};
export default [
{languageOptions: { globals: globals.browser }},
pluginJs.configs.all,
{ rules }
];
Simplemente colocamos el nombre de la regla y en su valor off
para desactivarla, warn
para avisar pero no marcarlo como error y error
si queremos que lo detecte como error.
Finalmente, añadimos { rules }
al array del export default
. Asegúrate de ponerlo al final, para que sobreescriba a las anteriores, si existieran.
Podemos utilizar
npx eslint --inspect-config
para lanzar un asistente que te enviará al ESLint Config Inspector, una web local donde verás cómodamente las reglas activadas, tu configuración...
Usar un pack de reglas
Esto puede ser muy laborioso y lento para mucha gente, por lo que lo ideal suele ser instalar un paquete de reglas para ESLint. Hay muchos y muy variados, donde su creador ha añadido las reglas que ha considerado oportunas para su forma de trabajar.
Veamos algunos packs populares de reglas de ESLint:
Nombre del paquete (NPM) | Promotores | GitHub |
---|---|---|
eslint-config-airbnb | Airbnb | @airbnb/javascript |
neostandard | Neostandard | neostandard/neostandard |
eslint-config-xo | XO | @xojs/eslint-config-xo |
Veamos un ejemplo de instalación de neostandard, que es una evolución del clásico StandardJS. En primer lugar, instalamos el pack de reglas:
$ npm install -D neostandard
Una vez instalado, modificamos el fichero de configuración eslint.config.mjs
y añadimos el pack:
import globals from "globals";
import pluginJs from "@eslint/js";
import neostandard from "neostandard";
export default [
{languageOptions: { globals: globals.browser }},
pluginJs.configs.all,
...neostandard()
];
Observa que hemos importado el paquete neostandard
y lo añadimos al array de configuración mediante ...neostandard()
, ya que es una función que devuelve un array. Con esto ya lo tendríamos. Ahora, ejecutamos el linter:
$ npx eslint index.js
/home/manz/project-test/index.js
1:5 error Variable 'name' should be initialized init-declarations
1:5 error 'name' is defined but never used no-unused-vars
1:9 error Extra semicolon @stylistic/semi
4:9 error Strings must use singlequote @stylistic/quotes
5:9 error Strings must use singlequote @stylistic/quotes
8:1 error 'object' is constant no-const-assign
8:1 error 'object' is assigned a value but never used no-unused-vars
8:10 error No magic number: 34 no-magic-numbers
8:12 error Extra semicolon @stylistic/semi
10:19 error Missing space before => @stylistic/arrow-spacing
10:22 error Missing space after => @stylistic/arrow-spacing
11:1 error Expected indentation of 2 spaces but found 4 @stylistic/indent
11:5 error Unexpected console statement no-console
11:17 error Strings must use singlequote @stylistic/quotes
12:1 error Expected indentation of 0 spaces but found 2 @stylistic/indent
✖ 15 problems (15 errors, 0 warnings)
9 errors and 0 warnings potentially fixable with the `--fix` option.
Observa que muchos de los errores tienen una regla prefijada por @stylistic/
. Esto son problemas de sintaxis que tienen que ver con el formateo del código:
- ✨ Falta un punto y coma
- ✨ Indentaciones incorrectas
- ✨ Falta de espacios entre parámetros
- ✨ Comillas simples en vez de dobles
- ✨ etc...
Por lo tanto, ahora no sólo busca problemas de código sino también de formateo, que combinado con el autofix, puede funcionar de una forma similar a Prettier, pero siendo muy configurable.
Alternativas a ESLint
Ten en cuenta que en esta guía hemos visto como configurar ESLint con VSCode. Sin embargo, también es posible configurarlo en otros editores, a través de plugins como ESLint para SublimeText, ESLint para IntelliJ IDEA, ESLint para Rollup o ESLint para vim.
Por otro lado, aunque ESLint es probablemente la mejor y más completa herramienta para revisar código Javascript, existen algunas alternativas que podrían resultar interesantes en algunos escenarios:
Herramienta | Descripción | Web |
---|---|---|
Oxidation Compiler | Linter rápido basado en Rust, compatible con ESLint. | oxc-project/oxc |
Biome | Linter rápido basado en Rust, compatible con Prettier. | biomejs/biome |
Prettier | Formateado opinionado. Es cómodo, pero poco personalizable. | prettier/prettier |
Si estás buscando alternativas, quizás una de las anteriores te pueda servir.