Los méritos de Git como sistema de control de versiones son difíciles de rebatir, pero si bien Git hará un excelente trabajo al realizar un seguimiento de las confirmaciones que usted y sus compañeros de equipo hayan realizado en un repositorio, no garantizará, en sí mismo, la calidad de esos se compromete Git no impedirá que confirmes código con errores de linting, ni que escribas mensajes de confirmación que no transmitan ningún tipo de información sobre la naturaleza de las confirmaciones en sí mismas y, sin duda, no impedirá que confirmes con un formato deficiente. código.
Afortunadamente, con la ayuda de los ganchos de Git, podemos corregir este estado de cosas con solo unas pocas líneas de código. En este tutorial, lo guiaré a través de cómo implementar ganchos de Git que solo le permitirán realizar una confirmación siempre que cumpla con todas las condiciones que se han establecido para lo que constituye una confirmación aceptable. Si no cumple con una o más de esas condiciones, se mostrará un mensaje de error que contiene información sobre lo que se debe hacer para que la confirmación pase las comprobaciones. De esta manera, podemos mantener las historias de confirmación de nuestras bases de código limpias y ordenadas y, al hacerlo, hacer que la vida de nuestros compañeros de equipo, y sin mencionar la de nosotros mismos en el futuro, sea mucho más fácil y placentera.
Como beneficio adicional, también nos aseguraremos de que el código que pasa todas las pruebas se formatee antes de que se confirme. ¿Qué es lo que no me gusta de esta propuesta? Muy bien, empecemos a romper.
requisitos previos
Para poder seguir este tutorial, debe tener un conocimiento básico de Node.js, npm y Git. Si nunca ha oído hablar de algo llamado package.json y git commit -m [message]
Suena como un código para algo súper secreto, entonces te recomiendo que visites este y este sitio web antes de continuar leyendo.
Nuestro plan de acción
En primer lugar, vamos a instalar las dependencias que hacen que la implementación de ganchos de confirmación previa sea un paseo por el parque. Una vez que tengamos nuestra caja de herramientas, configuraremos tres controles que nuestro compromiso deberá pasar antes de que se realice:
- El código debe estar libre de errores de pelusa.
- Todas las pruebas unitarias relacionadas deben pasar.
- El mensaje de confirmación debe adherirse a un formato predeterminado.
Luego, si la confirmación pasa todas las comprobaciones anteriores, se debe formatear el código antes de confirmarlo. Una cosa importante a tener en cuenta es que estas comprobaciones solo se ejecutarán en archivos que se hayan preparado para la confirmación. Esto es algo bueno, porque si este no fuera el caso, limpiar toda la base del código y ejecutar todas las pruebas unitarias agregaría una gran sobrecarga en términos de tiempo.
En este tutorial, implementaremos las comprobaciones discutidas anteriormente para algunos repetitivos front-end que usan TypeScript y luego Jest para las pruebas unitarias y Prettier para el formato del código. El procedimiento para implementar ganchos de confirmación previa es el mismo independientemente de la pila que esté utilizando, por lo que no se sienta obligado a subirse al tren de TypeScript solo porque lo estoy montando; y si prefiere Mocha a Jest, entonces haga sus pruebas unitarias con Mocha.
Instalando las dependencias
En primer lugar, vamos a instalar Husky, que es el paquete que nos permite hacer las comprobaciones que consideremos necesarias antes de realizar la confirmación. En la raíz de su proyecto, ejecute:
npm i husky --save-dev
Sin embargo, como se discutió anteriormente, solo queremos ejecutar las comprobaciones en los archivos que se han preparado para la confirmación, y para que esto sea posible, necesitamos instalar otro paquete, a saber, lint-staged:
npm i lint-staged --save-dev
Por último, pero no menos importante, instalaremos commitlint, que nos permitirá aplicar un formato particular para nuestros mensajes de confirmación. He optado por uno de sus formatos preempaquetados, es decir, el convencional, ya que creo que fomenta mensajes de compromiso que son simples pero al punto. Puedes leer más sobre esto aquí.
npm install @commitlint/{config-conventional,cli} --save-dev
## If you are on a device that is running windows
npm install @commitlint/config-conventional @commitlint/cli --save-dev
Después de que se hayan instalado los paquetes de commitlint, debe crear una configuración que le indique a commitlint que use el formato convencional. Puedes hacer esto desde tu terminal usando el siguiente comando:
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
¡Estupendo! Ahora podemos pasar a la parte divertida, ¡es decir, implementar nuestras comprobaciones!
Implementando nuestros ganchos de compromiso previo
A continuación se muestra una descripción general de los scripts que tengo en el paquete.json de mi proyecto repetitivo. Vamos a ejecutar dos de estos scripts listos para usar antes de realizar una confirmación, a saber, el lint
y prettier
guiones. Probablemente se esté preguntando por qué no ejecutamos el test
script también, ya que vamos a implementar una verificación que asegure que pasen todas las pruebas unitarias relacionadas. La respuesta es que debe ser un poco más específico con Jest si no desea que se ejecuten todas las pruebas unitarias cuando se realiza una confirmación.
"scripts": {
"start": "webpack-dev-server --config ./webpack.dev.js --mode development",
"build": "webpack --config ./webpack.prod.js --mode production",
"test": "jest",
"lint": "tsc --noEmit",
"prettier": "prettier --single-quote --print-width 80 "./**/*.{js,ts}" --write"
}
Como puede ver en el código que agregamos al archivo package.json a continuación, crear los ganchos previos a la confirmación para los scripts de lint y más bonitos no es más complicado que decirle a Husky que antes de realizar una confirmación, es necesario realizar la preparación de lint. correr. Luego le dices a lint-staged que ejecute los scripts lint y más bonitos en todos los archivos JavaScript y TypeScript preparados, ¡y eso es todo!
"scripts": {
"start": "webpack-dev-server --config ./webpack.dev.js --mode development",
"build": "webpack --config ./webpack.prod.js --mode production",
"test": "jest",
"lint": "tsc --noEmit",
"prettier": "prettier --single-quote --print-width 80 "./**/*.{js,ts}" --write"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"./**/*.{ts}": [
"npm run lint",
"npm run prettier"
]
}
En este punto, si desea enojar al compilador de TypeScript al pasar una cadena a una función que espera un número y luego intenta confirmar este código, nuestra verificación de pelusa detendrá su confirmación y le informará sobre el error y dónde. para encontrarlo. De esta manera, puede corregir el error de sus caminos, y aunque creo que, en sí mismo, es bastante poderoso, ¡aún no hemos terminado!
Añadiendo "jest --bail --coverage --findRelatedTests"
a nuestra configuración para lint-staged, también nos aseguramos de que la confirmación no se realice si no pasa alguna prueba unitaria relacionada. Junto con el control de pelusa, este es el código equivalente a usar dos arneses de seguridad mientras repara las tejas rotas en su techo.
¿Qué hay de asegurarse de que todos los mensajes de confirmación se adhieran al formato convencional de confirmación? Los mensajes de confirmación no son archivos, por lo que no podemos manejarlos con lint-staged, ya que lint-staged solo funciona con archivos preparados para la confirmación. En su lugar, tenemos que volver a nuestra configuración para Husky y agregar otro enlace, en cuyo caso nuestro paquete.json se verá así:
"scripts": {
"start": "webpack-dev-server --config ./webpack.dev.js --mode development",
"build": "webpack --config ./webpack.prod.js --mode production",
"test": "jest",
"lint": "tsc --noEmit",
"prettier": "prettier --single-quote --print-width 80 "./**/*.{js,ts}" --write"
},
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS", //Our new hook!
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"./**/*.{ts}": [
"npm run lint",
"jest --bail --coverage --findRelatedTests",
"npm run prettier"
]
}
Si su mensaje de confirmación no sigue el formato convencional de confirmación, no podrá realizar su confirmación: ¡mensajes de confirmación tan largos, mal formateados y oscuros!
Si pone su casa en orden y escribe un código que pasa las verificaciones de prueba de unidad y pelusa, y su mensaje de confirmación tiene el formato correcto, lint-staged ejecutará el script Prettier en los archivos preparados para la confirmación antes de que se realice la confirmación, lo que se siente como la guinda del pastel. En este punto, creo que podemos sentirnos bastante bien con nosotros mismos; un poco presumido incluso.
Implementar ganchos de confirmación previa no es más difícil que eso, pero las ganancias de hacerlo son enormes. Si bien siempre soy escéptico de agregar un paso más a mi flujo de trabajo, el uso de ganchos de confirmación previa me ha ahorrado un mundo de molestias, y nunca volvería a hacer mis confirmaciones en la oscuridad, si se me permite terminar este tutorial en una nota algo pseudo-poética.