ESLint + Prettier + Husky + Gitflow en Angular

Anartz Mugika Ledo🤗
12 min readOct 12, 2022

El objetivo principal de este artículo es proporcionar los pasos a seguir con las instrucciones detalladas y necesarias para poder configurar un proyecto de Angular con las herramientas que nos va a ayudar a trabajar con buenas prácticas.

Estas buenas prácticas que queremos aplicar se realizarán tanto en la escritura del código, siguiendo una línea estable de escritura con unas normas preestablecidas y también en lo que respecta a la adición de mensajes de commit donde realizaremos las configuraciones necesarias con el objetivo de respetar la convención para escribir los mensajes de commit siguiendo una estructura común que se usará en infinidad de proyectos, con lo que esto proporcionará una forma de trabajar estable y correcta mediante git flow escribiendo mensajes de commit.

Preparativos para empezar a trabajar

El tutorial se desarrollará con una aplicación Angular en la versión 13 (es igual de aplicable para la versión 14) y lo podéis descargar desde aquí, para no tener que estar creando el proyecto de 0 y así poder empezar en el mismo punto del que me encuentro yo actualmente.

¿Qué pasos vamos a dar en esta guía?

Los pasos que vamos a dar para configurar nuestro proyecto de Angular aplicando una estructura y funcionalidad que nos permitirá aplicar buenas prácticas son los siguientes:

  1. ESLint: Linter de Javascript que nos va a permitir hacer que compruebe mediante unas normas preestablecidas, que se cumplen a la hora de codificar en el proyecto.
  2. Husky: Herramienta que es un paquete que sirve para controlar el uso de los Hooks de Git de una manera super fácil sin mucho esfuerzo. Instalación y primeras configuraciones con el hook pre-commit.
  3. CommitLint: es un paquete que nos puede ayudar a mantener los mensajes de la historia de git con un estándar respetando una estructura que ya se mencionará posteriormente. Aquí configuraremos el hook commit-msg para comprobar que seguimos las buenas prácticas mediante la ejecución de commitlint
  4. Prettier: es una herramienta para formatear el código, tiene soporte para HMTL, CSS, JavaScript, JSX, TypeScript, GraphQL… Lo usaremos para formatear principalmente el código HTML, CSS y Typescript que encontraremos en nuestro proyecto de Angular añadiendo unas propiedades como espacio para tabulaciones, si usamos “;”, comillas simples y demás.

Ahora que ya sabemos que pasos vamos a seguir en este artículo para configurar todo el pack de herramientas para trabajar con buenas prácticas en nuestro proyecto, procedemos a completar los pasos uno por uno hasta llegar a la meta donde podremos formatear el código automáticamente con prettier usando el linter de eslint mientras comprobamos si los mensajes de los commit aplican las recomendaciones para los mensajes de commit usando la herramienta commitlint.

1.- Configurar ESLint

Para configurar ESLint en Angular vamos a seguir las instrucciones que podremos encontrar en este enlace que os proporciono. Esto será compatibles con las versiones de Angular 12+. Accedemos a el para tener toda la información y ver otros aspectos que nos pueda resultar interesante. Ahora que estamos dentro del README, seguimos los pasos principales para configurar correctamente ESLint en el proyecto de Angular.

  • Paso 1 y 2 del proceso a seguir completados, ya que el proyecto ya lo tenemos creado y operativo. Si no lo habéis realizado, os recomiendo que lo descarguéis desde aquí.
  • Debemos de ejecutar el siguiente comando de schematics: ng add @angular-eslint/schematics. Esto servirá para que automáticamente instale las dependencias necesarias y a su vez realice las configuraciones necesarias como añadir en angular.json el registro de los diferentes Schematics usados en la propiedad "schematicCollections" entre otros ajustes.

Al ejecutar el comando nos preguntarán si queremos seguir hacia adelante y decimos que si (Y)

Cuando pase un instante y haga los cambios en los diferentes ficheros, al terminar nos muestra este feedback:

Proceso de instalación y configuración de ESLint en Angular

Ahora vamos mirando que ficheros y modificaciones se han realizado que se pueden ver a continuación:

Vamos fichero por fichero analizando los cambios:

(1) .eslintrc.json

(2) angular.json

Observamos los cambios dentro de la línea 8, 17 y 31.

(3) package.json

Llegados a este punto ya tenemos el primer paso completado y con esto podemos probar ejecutando el linter con yarn lint (o npm run lint si no usáis yarn) aunque en estos momentos no tiene mucha relevancia. Podemos ver todos los cambios en este commit. Seguimos al segundo paso.

2.- Instalación y configuración de Husky

Para instalar Husky en nuestro proyecto lo primero vamos a acceder a este enlace para ver las diferentes opciones de instalación que son las siguientes:

npx husky-init && npm install # Si trabajamos con NPM
npx husky-init && yarn # Si trabajamos con Yarn 1 (este es mi caso) yarn dlx husky-init --yarn2 && yarn # Si trabajamos con Yarn 2+
pnpm dlx husky-init && pnpm install # Si trabajamos con pnpm

Dependiendo de como gestionemos nuestras dependencias debemos de ejecutar la instalación de una manera u otra. Lo más normal es que estéis trabajando con NPM o Yarn 1 pero sea cual sea vuestra manera de gestionar las dependencias deberéis de realizarlo tal y como se indica.

En el caso de mi equipo estoy usando Yarn 1 para gestionar las dependencias y por eso ejecutaré el siguiente comando (si trabajaís con otras versiones o alternativas como NPM o PNPM consultad las instrucciones):

npx husky-init && yarn

Al ejecutar nos debe de mostrar algo de este estilo:

Proceso de instalar y configurar automáticamente Husky

Con esto se añadirá un directorio en la raíz llamado .husky que contiene un fichero para ejecutar los hooks de Git llamado pre-commit con el comando para ejecutar el test de Angular con npm test

.husky/pre-commit

Lo que hace básicamente es accede dentro del fichero Shell de husky en nuestra máquina y ejecuta cuando detecta la acción previa al commit, ejecuta npm test que se asigna automáticamente cuando hemos instalado y realizado las primeras configuraciones de Husky.

En este punto podemos añadir más comandos como la ejecución de los test unitarios, los test de integración o incluso el plugin de prettier para dar formato al código siguiendo una normas establecidas. Esto último, como bien se sabe, lo haremos. Vamos paso por paso primero trabajando con el Linter de ESLint.

Se modifica el package.json añadiendo el apartado de Husky automáticamente cuando hemos ejecutado el comando para instalar y configurar Husky automáticamente.

Se añade el script automáticamente

Ahora accedemos al fichero pre-commit dentro del directorio .husky y modificamos el contenido reemplazando con yarn lint ( npm run lint si estamos con NPM). Es decir, eliminamos npm test y lo sustituimos.

Contenido del hook pre-commit

Para asegurarnos que funciona todo correctamente añadimos todos los permisos para ejecutar correctamente chmod a+x .husky/pre-commit para evitar problemas cuando estamos ejecutando los Hooks de Git.

Ya tenemos definida la acción para ejecutar automáticamente yarn lint mediante hooks, con el hook pre-commit. Esto se ejecutará siempre y cuando estemos realizando un commit habilitando que este hook se ejecute antes de realizar la anotación en el registro (que podemos comprobar con git log).

Ahora pueden ocurrir dos situaciones:

La que da error. No deja seguir hacia adelante.

Haciendo el cambio en el selector de app-root a anartz-root forzaremos el error al ejecutar yarn lint

Este será el error que se mostrará con ese desajuste:

Este sería el mensaje que se mostraría en el linter si todo está OK (volvemos a dejar el selector con el contenido inicial) que haría posible que se añada el commit.

Después de haber trabajado con el hook pre-commit, seguimos con el hook commit-msg que se ejecutará cuando ya se va a añadir el comentario del commit y hemos pasado la ejecución del pre-commit y todo está OK.

Para respetar el formato de los mensajes de los commit siguiendo lo descrito por la convención de git flow, vamos a instalar commitlint que es un linter que comprueba la estructura de los mensajes y sigue unas normas principales que mostraré en un instante, después de instalar lo necesario para trabajar con los paquetes de las funcionalidades de commitlint.

Comenzamos con las configuraciones siguiendo la siguiente referencia: https://commitlint.js.org/#/guides-local-setup

Ejecutamos el siguiente comando, donde instalamos @commitlint/cli y @commitlint/config-conventional

yarn add -D @commitlint/{cli,config-conventional}

Este sería el resultado que se muestra al ejecutar la instalación:

Configuramos commitlint usando la configuración convencional mediante la creación del fichero commitlint.config.js ejecutando el siguiente comando:

echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js

Al ejecutar el comando, en la raíz del proyecto veremos un nuevo fichero commitlint.config.js con el contenido que hemos introducido dentro del paréntesis que ejecuta con “echo”.

Estado del fichero para el linter de commits

.husky/commit-msg

Para crear el fichero con el comando que se ejecutará para lintear el commit lo realizamos ejecutando el siguiente comando:

npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'

Y con ello conseguimos que se cree el fichero con este contenido:

Añadimos chmod a+x .husky/commit-msg para gestionar y otorgar todos los permisos en este fichero para evitar problemas cuando ejecutemos mediante Git Hooks el hook configurado commit-msg.

Ahora sin ejecutar el Hook podemos hacer pruebas “a mano” ejecutando el comando para utilizar el Linter de los commits y lo podemos hacer de la siguiente manera ( basándonos en lo siguiente):

¿Cuál es el motivo de que nos de un error? Como bien nos indica el feedback del error, el tipo debe de ser uno de los especificados en el mensaje “type must be one of [build, chore,…” y como se puede observar, el type está especificado con “foo”.

Para saber como debemos de formar los mensajes respetando una estructura y normas sencillas tenemos que tener en cuenta lo siguiente:

Propósito de cada tipo:

  • feat: (una nueva feature (funcionalidad) del usuario, no será cuando hacemos un build)
  • fix: (solución a un bug surgido en el código, no será cuando hacemos build)
  • docs: (cambios en la documentación)
  • style: (formateo, añadir semicolons, etc; sin cambios en el código de producción)
  • refactor: (refactorizar código de producción, ej. renombar una variable)
  • test: (añadir test que faltan, refactorizar tests; sin cambios en el código de producción)
  • chore: (actualizar tareas grunt, etc; sin cambios en el código de producción)

Recordad que usaremos esta referencia para añadir correctamente los mensaje de commit siguiendo la guía de estilo convencional de escritura de commit de Git: https://www.conventionalcommits.org/en/v1.0.0/

Con esto ya tenemos todo lo necesario configurado para trabajar con los hooks pre-commit y commit-msg, vamos a probarlos ejecutando un commit para los cambios realizados.

Ejecutamos el siguiente comando:

git commit -m "chore: add config pre-commit and commit-msg hooks"

Al ejecutar el comando pasará por dos estados:

  • pre-commit: Comprueba el linter, si es correcto, que en teoría ya lo es porque no hemos cambiado nada de código.
  • commit-msg: Comprueba el mensaje del commit que en este caso usa el formato correcto (por si acaso, siempre podemos ejecutar echo 'chore: add config pre-commit and commit-msg hooks' | npx commitlint para hacer una prueba.

Creamos el commit y este será el resultado:

Como en el commit, al ejecutar pre-commit todo ok y el commit-msg cuyo mensaje respeta las normas ya tenemos todo OK. Con esto ya hemos terminado este paso y pasamos al último donde vamos a aprender a configurar Prettier para darle formato automáticamente al código cuando hacemos un commit con las mismas reglas, sea quien sea el que escribe el código.

Los cambios realizados en este apartado con la configuración e instalación de Husky con los Hooks de Git los podemos encontrar en este enlace.

Para dar más cobertura de información sobre estos temas, os invito a consultar estas referencias:

Más información sobre los Git Hooks: https://git-scm.com/docs/githooks

Añadir configuración de Prettier con ESLint para formatear el código

Ahora que ya tenemos la verificación del linter con los ajustes básicos para comprobar que el código sigue unas normas, vamos a añadir el plugin Prettier combinándolo con ESLint para que corrija lo que no está correcta en las reglas de ESLint junto con las que vamos a añadir en la configurar del Prettier.

¿Cuál es el objetivo de ir añadiendo estas herramientas? El objetivo principal es que se siga una línea de desarrollo a la hora de escribir, sobre todo cuando estamos en equipos de varias personas, para que lo escrito se amolde a lo que se ha definido y así seguir una línea en común.

Para realizar el proceso de configuración seguiremos los siguientes pasos:

1.- Instalación de las dependencias principales de prettier

Ejecutamos el siguiente comando donde añadimos prettier junto con prettier-quick que se encargará de escribir el contenido de los ficheros del proyecto de Angular donde tenemos los componentes, directivas, pipes,…

yarn add -D prettier pretty-quick

Una vez instaladas las dependencias mencionadas, seguimos hacia adelante.

2.- Añadir los ficheros .prettierrc.json y .prettierignore en la raíz del proyecto.

Creamos el fichero .prettier.json en la raíz del proyecto y añadimos el siguiente contenido donde vamos a especificar las normas que queremos añadir en el apartado de configuración para este proyecto con Prettier:

{
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"semi": true,
"bracketSpacing": true,
"arrowParens": "avoid",
"trailingComma": "es5",
"bracketSameLine": true,
"printWidth": 80
}

Añadimos el fichero .prettierignore (en la raíz también) en el que vamos a añadir lo mismo que en el fichero .gitignore

3.- Instalación de dependencias para trabajar con Prettier / ESLint

Añadimos el siguiente comando para instalar las dependencias necesarias y lo hacemos en desarrollo:

yarn add prettier-eslint eslint-config-prettier eslint-plugin-prettier -D

4.- Editar .eslintrc.json

Pasamos del contenido que tenemos actualmente en .eslintrc.json.

{
"root": true,
"ignorePatterns": [
"projects/**/*"
],
"overrides": [
...
{
"files": [
"*.html"
],
"extends": [
"plugin:@angular-eslint/template/recommended"
],
"rules": {

}
}
// AÑADIMOS NUEVAS NORMAS AQUÍ <===============
]
}

Quedando los cambios establecidos en los puntos mencionados:

{
"root": true,
"ignorePatterns": ["projects/**/*"],
"overrides": [
{
"files": ["*.ts"],
"parserOptions": {
"project": ["tsconfig.json"],
"createDefaultProgram": true
},
"extends": [
"plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/template/process-inline-templates",
"plugin:prettier/recommended" <===================
],
"rules": {
...
}
},
{
"files": ["*.html"],
"extends": ["plugin:@angular-eslint/template/recommended"],
"rules": {}
},
// NOTE: Se servirá para aplicar con Prettier
{
"files": ["*.html"],
"excludedFiles": ["*inline-template-*.component.html"],
"extends": ["plugin:prettier/recommended"],
"rules": {
// NOTE: WE ARE OVERRIDING THE DEFAULT CONFIG TO ALWAYS SET THE PARSER TO ANGULAR (SEE BELOW)
"prettier/prettier": ["error", { "parser": "angular" }]
}
}
]
}

Si queréis ver los cambios con más detalle y ante cualquier duda, podéis acceder a este enlace: https://github.com/mugan86/angular-husky-eslint-gitflow-commit-prettier/commit/b3ecdba47aa477b3923c31ce7d274eb73f793524

5.- Fichero settings.json en .vscode

Añadir en la configuración de .vscode un nuevo fichero llamado settings.json con el siguiente contenido para establecer el plugin prettier a usar tanto en HTML y Typescript, necesario en este proyecto:

{
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": { "source.fixAll.eslint": true },
"editor.formatOnSave": false
},
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.codeActionsOnSave": { "source.fixAll.eslint": true },
"editor.formatOnSave": false
}
}

6.- Añadir nuevo script

Añadimos el script para limpiar los apartados que detecta eslint con prettier

"lint:fix": "ng lint --fix",

En el package.json se reflejará de la siguiente manera:

7.- Modificar el hook pre-commit

Añadimos los siguiente npx pretty-quick --staged && yarn lint:fix en los scripts del package.json, quedando de la siguiente manera:

Ahora, en el fichero que hemos creado anteriormente con este contenido: .husky/pre-commit

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

yarn lint

Y lo modificamos, dejándolo de la siguiente manera: .husky/pre-commit

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

yarn prettier

8.- Ejecutar commit haciendo un check de todos los ficheros

Todo lo desarrollado paso a paso lo podemos encontrar en este resultado final: https://github.com/mugan86/angular-husky-eslint-gitflow-commit-prettier

Podemos usar este repositorio como un template para iniciar nuestros proyectos con toda esta configuración, algo que nos va a reducir un montón de trabajo.

9- Presencia en redes sociales.

Podéis encontrarme en las siguientes redes.

¡Espero que os sea de gusto el artículo y lo compartáis!

--

--

Anartz Mugika Ledo🤗

[{#frontend:[#mobile:{#android, #kotlin, #ionic}}, {#web:{#angular, #qwik, #bootstrap}}],{#backend: [{#graphql, #nestjs,#express, #mongodb, #mysql}]}]