Automatic Git Hooks Integration in a Node.js Project
Many Git users, I believe, are familiar with the situation where, after making a commit, something unnecessary is found
to have been included in the commit, or the committed code fails tests. Sometimes, this code even ends up being pushed
directly to origin
.
Who could forget the ‘Push changes immediately to origin/branch_name’ checkbox in SourceTree:
I think almost everyone has considered the logical solution of using Git hooks. But is it really that convenient?
To set up Git hooks locally, you need to go into the hidden .git/hooks
directory, find the necessary hook, and insert
the commands for code checking. It seems simple enough. But that’s only as long as the hooks are needed by you alone.
What if you want the hook to be set up automatically right after the project is deployed? And so that a new developer on
the project doesn’t stress out the CI system for no reason just because they missed a console.log
?
Fortunately, there’s a very convenient solution—a handy npm package called husky. You can install it like any other package using the command
npm install husky --save-dev
After installation, all that’s left is to configure our hooks. To do this, simply add a new husky section to your
package.json
and specify the necessary commands for the hooks:
{
"name": "demo",
"dependencies": {},
"devDependencies": {
"husky": "^1.1.2"
},
"husky": {
"hooks": {
"pre-commit": "gulp lint",
"pre-push": "gulp test:unit",
"...": "..."
}
}
}
After this, when you attempt to make a commit, the lint
command will run first. There’s no need to worry about the
path
to Node.js, running scripts from the ./node_modules/.bin/gulp test
folder, or anything else. Once all dependencies are
installed, the hook will be applied automatically.
If you want to change any command, simply make the corresponding changes in package.json
and commit those changes,
after
which the hook will be updated for all developers.
The library also allows configuration through a separate file like .huskyrc
, .huskyrc.json
, or .huskyrc.js
.
However, in
my opinion, for such a small amount of configuration, it’s unnecessary to place it in a separate file at the root of the
project.
How Does It Work?
All npm modules have the capability to run scripts after certain events. For example, after a package is installed (you
can read more about this in the documentation). Husky uses the postinstall
event, which is always executed after a
package is installed, to register its script. This script searches for the .git
directory in the parent directories
and
sets the package’s main module to run on all available hooks. When a hook is triggered later, the Husky module looks for
all possible hook command definitions in package.json
, .huskyrc
, or other files and executes them. That’s the whole
magic.