Husky¶
What?¶
Husky is a tool that lets you automate the execution of user-defined commands triggered by specific Git hooks.
See npm package here.
Why?¶
The main goal is to customize Git by firing custom scripts to improve the development process, like displaying a warning message if the commit is too large or even preventing to slip into the repository! This can be done by integrating Husky with other JS tools like ESlint, so that it runs automatically when you try to commit changes and prevent the commit if ESlint returned errors. This can be achieved with the
pre-commit
hook.
Another great option is to use commitlint in the commit-msg
hook so that it verifies that the commit messages are aligned with the Conventional Commits specification.
We can even make Husky run the automated tests for every commit and prevent you from committing changes if the test coverage decreases! But that would be a little bit too extreme if we just want to commit the changes of an unfinished task to continue later.
How?¶
Just install it as a dev dependency like this:
npm install husky --save-dev
And then add the following to your package.json
// package.json
{
"husky": {
"hooks": {
"pre-commit": "<my-command>",
"commit-msg": "<another-command>",
"pre-push": "<yet-another-command>",
"...": "..."
}
}
}
The best way to customize the linting command is with lint-staged, which lets you create different rules for each type file. So, a possible integration with Husky, lint-staged and commitlint would be like this:
// package.json
{
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"lint-staged": {
"**/*.{js,jsx}": [
"./node_modules/.bin/eslint --fix"
],
"**/*.md{,x}": [
"prettier --check"
]
}
}
In this case we're using ESlint's fix option which will automatically fix all possible errors and add those changes to the commit. NOTE: If the errors can't be resolved automatically by ESlint, the commit will fail.
This way, next time we commit changes it will run lint-staged
command first and then commitlint
and only commit if all of them pass:
IMPORTANT NOTE: If you have more than one package in your project (i.e., there is more than one package.json
) and you are storing them all in the same repository, it is highly recommended to use lerna and add Husky ONLY in the root package.json
:
.
└── root
├── .git
├── package.json 🐶 # Add husky here
└── packages
├── A
│ └── package.json
├── B
│ └── package.json
└── C
└── package.json
Can I see an example project?¶
Yeah! Take a look at this one.