ESLint: los hechos esenciales sobre las herramientas de interfaz esenciales

Recientemente, me he involucrado más en el desarrollo front-end. Cuanto más hago, más se pierden mi mente y mi alma en su mundo caótico. Incluso una aplicación simple de To-Do-List puede requerir fácilmente un montón de herramientas (ESLint, Babel, Webpack, por nombrar algunas) y paquetes solo para comenzar.

Afortunadamente, existen muchos kits de inicio, por lo que no tenemos que hacer todo desde cero. Con ellos, todo ya está configurado para que podamos comenzar a escribir la primera línea de código de inmediato. Ahorra tiempo en tareas repetitivas y aburridas, lo que puede ser excelente para desarrolladores experimentados.

Sin embargo, este beneficio tiene un precio para los principiantes. Dado que todo funciona desde el primer momento, parece mágico, y es posible que no sepan lo que realmente está sucediendo bajo el capó, lo cual es importante entender en algún nivel. Aunque la curva de aprendizaje no es tan empinada como otras —trata de comparar con algunas herramientas que has estado aprendiendo y usando, entenderás lo que quiero decir— en este mundo caótico, necesitamos una guía de supervivencia para el viaje.

Esta serie cubrirá las herramientas fundamentales del desarrollo front-end y los elementos esenciales que necesitamos saber sobre ellas. Esto nos permitirá gobernar las herramientas en lugar de ser controlados por ellas.

En él, nos centraremos en la experiencia del desarrollador de cada una de estas herramientas. Entonces, el objetivo de esta serie es actuar como una guía de supervivencia y brindar una descripción general de alto nivel de cada herramienta, no para servir como documentación.

Que se incluirá:

  • ESLint <- Estamos aquí
  • Babel
  • Webpack
  • Fluir
  • TypeScript
  • Broma.

Basta de prefacio, comencemos con la primera herramienta: ESLint.

¿Qué es ESLint y por qué deberíamos usarlo?

ESLint es, como su nombre lo indica, un linter para ECMAScript. Y la definición de linter es:

una máquina para eliminar las fibras cortas de las semillas de algodón después del desmotado.

Aunque el código y las semillas de algodón no tienen ninguna relación, independientemente del código o las semillas de algodón, un linter ayudará a que las cosas sean más limpias y consistentes. No queremos ver el código como este:

const count = 1; const message = "Hello, ESLint" count += 1 

Se ve feo y tiene un error. Aquí es cuando ESLint interviene para ayudar con eso. En lugar de dejar que el error se descargue en la consola del navegador cuando ejecutamos el código, ESLint lo detectará mientras escribimos (bueno, en realidad no: necesitaremos un editor o extensiones IDE para esto, que se tratarán más adelante).

Por supuesto, este error no es difícil de entender, pero ¿no sería mejor tener un asistente que nos recuerde cada vez que estamos a punto de cometer un error y quizás lo corrija automáticamente por nosotros? Aunque ESLint no puede detectar todo tipo de errores, al menos nos ahorra algo de esfuerzo para que podamos dedicar tiempo a otras cosas que importan y necesitan atención humana.

¿Cómo funciona ESLint?

Ahora que sabemos qué es ESLint y por qué lo necesitamos, profundicemos un poco más y veamos cómo funciona. En esencia, podemos dividirlo en tres grandes pasos.

Analizador

El código que escribimos no es más que una secuencia de caracteres. Sin embargo, esta secuencia no es solo caracteres aleatorios: necesitan seguir un conjunto de reglas o convenciones que es la gramática que forma un idioma.

Para un ser humano, pasar de leer texto o código a comprenderlo conceptualmente requiere poco esfuerzo. Para una computadora, esto es mucho más difícil de lograr. Por ejemplo:

const tool = 'ESLint' // 1 const tool = "ESLint" // 2 

Cuando leemos las dos líneas de arriba, inmediatamente sabemos que son idénticas y se pueden leer como "hay una constante nombrada toolcon el valor de ESLint". Para una computadora, que no entiende el significado, estas dos líneas se ven bastante diferentes. Como resultado, si alimentamos con código sin formato a ESLint, es casi imposible hacer nada.

Cuando las cosas se complican y resultan difíciles de comunicar, piense en cómo podemos tener una computadora para comprender lo que hacemos, la abstracción puede ser un escape. Al abstraer algo, ocultamos todos los detalles innecesarios, reducimos el ruido y mantenemos a todos en la misma página, lo que facilita la comunicación. En el ejemplo anterior, un espacio o dos espacios no importan, ni las comillas simples ni las dobles.

En otras palabras, eso es lo que hace un analizador. Convierte código en bruto en un árbol de sintaxis abstracta (AST), y este AST se utiliza como medio para basar las reglas de lint. Todavía hay muchos pasos que un analizador debe seguir para crear un AST; si está interesado en aprender más sobre cómo se genera un AST, este tutorial tiene una buena descripción general.

Reglas

El siguiente paso en el proceso es ejecutar el AST a través de una lista de reglas. Una regla es una lógica de cómo resolver posibles problemas existentes en el código del AST. Los problemas aquí no son necesariamente errores sintácticos o semánticos, pero también pueden ser estilísticos. El resultado de una regla incluirá información útil para su uso posterior, como líneas de código, posiciones y mensajes informativos sobre el problema.

Además de detectar problemas, una regla puede incluso corregir automáticamente el código si es posible. Por ejemplo, cuando se aplica ningún espacio múltiple al código anterior, recortará todos los espacios redundantes, lo que hace que el código se vea limpio y coherente.

 const tool = "ESLint" // 2 // becomes const tool = "ESLint" // 2 

En diferentes escenarios, una regla se puede usar en diferentes niveles (exclusión voluntaria, solo advertencia o error estricto) y tiene varias opciones, lo que nos da control sobre cómo usar la regla.

Resultado

Aquí llega el final del proceso. Con el resultado de una regla, es solo cuestión de cómo la mostramos de una manera amigable para los humanos, gracias a toda la información útil que mencionamos anteriormente. Luego, a partir del resultado, podemos señalar rápidamente el problema, dónde está y corregirlo, o tal vez no.

Integración

ESLint se puede usar como una herramienta independiente con su robusta CLI, pero esa es una forma básica de usar ESLint. No queremos escribir un comando cada vez que queremos lint código, especialmente en un entorno de desarrollo. La solución para esto es integrar ESLint en nuestro entorno de desarrollo para que podamos escribir código y ver los problemas detectados por ESLint en un solo lugar.

Este tipo de integración proviene de extensiones específicas para IDE o editores. Estas extensiones requieren que ESLint funcione, ya que ejecutan ESLint detrás de escena; no es de extrañar que todavía necesitemos instalar ESLint junto con ellas, no son nada sin ESLint. Este principio se aplica a otros IDE o extensiones de editor que utilizamos a diario.

¿Recuerda el resultado de una regla que hablamos anteriormente? Una extensión lo usará para mostrarse en el IDE o editor. La forma en que se muestra exactamente la salida depende de cómo se implemente la extensión y cómo el IDE o editor esté abierto a sus extensiones. Algunas extensiones también aprovechan las capacidades de corrección de problemas de las reglas para cambiar el código al guardar si lo habilitamos.

Configuración

La configuración es el principal poder que da versatilidad a una herramienta. ESLint no es diferente de eso, excepto que tiene la configuración más completa entre otras herramientas. En general, necesitamos un archivo o un lugar para poner la configuración, y tenemos un par de opciones.

Todos ellos se reducen a dos formas principales: o tenemos un archivo de configuración separado para cada herramienta, o los agrupamos todos package.json.  .eslintrc.jses uno de los archivos que ESLint buscará para su configuración, y también el de mayor prioridad.

Lo siguiente que necesitamos saber sobre la configuración es su jerarquía y comportamiento en cascada. Gracias a estas características, no necesitamos tener un archivo de configuración en cada carpeta del proyecto.

Si un archivo de configuración no existe en una carpeta, ESLint simplemente busca uno en el padre de la carpeta hasta que no puede encontrar uno. Luego volverá a la configuración predeterminada de todo el usuario en ~/.eslintrc. De lo contrario, el archivo de configuración sumará o anulará los de los niveles superiores.

Sin embargo, hay un cambio especial en esto. Si especificamos root: trueen un archivo de configuración, la búsqueda se detendrá en ese archivo en lugar de subir como antes. Además, ESLint usará ese archivo de configuración como la configuración raíz, y todas las configuraciones secundarias se basarán en este.

Esto no se limita solo a ESLint, estas cosas son comunes para otras herramientas. Hablemos de la configuración específica de ESLint.

Analizador

El papel del analizador en ESLint se ha discutido anteriormente. De forma predeterminada, ESLint usa Espree como analizador. Podemos cambiar este analizador a otro compatible como babel-eslint o @ typescript-eslint / parser si usamos Babel o Typescript, respectivamente.

Para configurar el analizador, usamos parserOptions. Entre las opciones compatibles con Espree, aquí hay algunas que usamos con frecuencia y a las que debemos prestar atención:

  • ecmaVersion

Necesitamos especificar la versión de ECMA apropiada para las funciones que queremos usar. Por ejemplo, si emcaVersion: 5, el siguiente código dará algunos errores.

```javascript let a = [1, 2, 3, 4] // error due to `let` keyword var b = [...a, 5] // error due to spread syntax ``` 

El analizador no puede analizar el código porque tanto la letpalabra clave como la sintaxis de propagación se acaban de introducir en ES6. Cambiar emcaVersiona 6 o superior simplemente resolverá los errores.

  • sourceType

Hoy en día, principalmente escribimos todo en módulos y luego los agrupamos. Entonces, esta opción, la mayoría de las veces, debería ser module.

Otro valor que podemos usar, además del predeterminado, es script. La diferencia es si podemos usar módulos JS o no, es decir, use importy exportpalabra clave. La próxima vez que recibamos este mensaje de error Parsing error: 'import' and 'export' may appear only with 'sourceType: module', sabremos dónde buscar.

  • ecmaFeatures.jsx

Puede haber características ES adicionales que queramos utilizar, por ejemplo, sintaxis JSX. Usamos ecmaFeatures.jsx: truepara habilitar esta función. Tenga en cuenta que el soporte JSX de Espree no es lo mismo que JSX en React. Si queremos un JSX específico de React, deberíamos usar eslint-plugin-react para obtener mejores resultados.

Si usamos otro analizador, estas opciones son más o menos iguales. Algunos pueden tener menos opciones y otros pueden tener más, pero todos se definen a continuación parserOptions.

Medio ambiente

Depende de dónde se esté ejecutando el código: existen diferentes variables globales predefinidas. Tenemos window, documenten el navegador, por ejemplo. Sería irritante si la regla no-undef está habilitada y ESLint nos sigue diciendo windowo documentno está definida.

La envopción está aquí para ayudar. Al especificar una lista de entornos, ESLint conocerá las variables globales en estos entornos y nos permitirá usarlas sin una palabra.

Hay un entorno especial que debemos tener en cuenta es6. Se establecerá implícitamente parserOptions.ecmaVersionen 6 y habilitará todas las funciones de ES6 excepto los módulos que aún necesitamos usar por parserOptions.sourceType: "module"separado.

Complementos y configuraciones compartibles

Tener la misma configuración de reglas una y otra vez en diferentes proyectos puede resultar agotador. Afortunadamente, podemos reutilizar una configuración y solo anular las reglas según sea necesario con extends. A este tipo de configuración lo llamamos configuraciones compartibles, y ESLint ya tiene dos para nosotros: eslint:recommendedy eslint:all.

Convencionalmente, las configuraciones compartibles de ESLint tienen eslint-configprefijo para que podamos encontrarlas fácilmente a través de NPM con eslint-configpalabras clave. Entre cientos de resultados, hay algunos populares, como eslint-config-airbnb o eslint-config-google, lo que sea.

Fuera de la caja, ESLint tiene un montón de reglas para diferentes propósitos, desde posibles errores, mejores prácticas, ES6 hasta problemas de estilo. Además, para potenciar su capacidad, ESLint tiene una gran cantidad de reglas de terceros proporcionadas por casi mil complementos. Similar a las configuraciones compartibles, los complementos de ESLint tienen el prefijo eslint-pluginy están disponibles en NPM con la eslint-pluginpalabra clave.

Un complemento define un conjunto de nuevas reglas y, en la mayoría de los casos, expone sus propias configuraciones útiles. Por ejemplo, eslint-plugin-react nos da dos configuraciones para compartir, eslint-plugin-react:recommendedy eslint-plugin-react:allal igual que eslint:recommendedy eslint:all. Para usar uno de ellos, debemos, en primer lugar, definir el nombre del complemento y, en segundo lugar, extender la configuración.

{ plugins: ["react"], extends: "plugin:react/recommended" } // Note that we need to prefix the config by `plugin:react` 

Una pregunta común es qué complementos o configuraciones usar. Si bien depende en gran medida de nuestras necesidades, podemos usar Awesome ESLint como referencia para encontrar complementos y configuraciones útiles.

Más bonita

Casi hemos llegado, casi hemos llegado al final. Por último, pero no menos importante, hablaremos de un par popular de ESLint, Prettier. En resumen, Prettier es un formateador de código obstinado. Aunque Prettier se puede usar solo, integrarlo a ESLint mejora mucho la experiencia, y eslint-plugin-prettier hace este trabajo.

La diferencia entre usar Prettier solo y usar Prettier con ESLint se puede resumir en el formato de código como un problema. En lugar de dar problemas de formato por separado, ejecutar Prettier con ESLint tratará los problemas de formato como otros problemas. Sin embargo, estos problemas siempre se pueden solucionar, lo que equivale a formatear el código.

Así es como eslint-plugin-prettierfunciona. Ejecuta Prettier, por regla general, detrás de escena y compara el código antes y después de ejecutar Prettier. Finalmente, informa las diferencias como problemas individuales de ESLint. Para solucionar estos problemas, el complemento simplemente usa el código formateado de Prettier.

Para tener esta integración, necesitamos instalar tanto prettiery eslint-plugin-prettier. eslint-plugin-prettiertambién viene con eslint-plugin-prettier:recommendedconfig, que extiende eslint-config-prettier. Por lo tanto, también necesitamos instalarlo eslint-config-prettierpara usarlo.

{ "plugins": ["prettier"], "extends": "plugin:prettier/recommended" } 

Conclusión

Los linters o formateadores de código se han convertido en el estándar de facto en el desarrollo de software en general, y ESLint, específicamente, en el desarrollo front-end.

Sus beneficios van mucho más allá de lo que hace técnicamente, ya que ayuda a los desarrolladores a centrarse en asuntos más importantes. Gracias a la delegación de estilos de código a una máquina, podemos evitar estilos de opinión en la revisión de código y utilizar ese tiempo en su lugar para una revisión de código más significativa. La calidad del código también se beneficia y obtenemos un código más coherente y menos propenso a errores.

Este artículo se publicó originalmente en mi blog .