Git Prettier Commits with Husky

Ward Price
Level Up Coding
Published in
3 min readJan 18, 2021

--

This past week, I was setting up a Node.js backend for the first time and fell into a rabbit hole while researching the organizational development options. Enter Git Hooks—these allow the user to run custom scripts whenever a specified git event occurs. You can write the hooks in any language you’d like and you can even view example scripts that git installs when you git init your project directory. Navigate to .git/hooks to check them out.

I also came across the NPM package commitlint which follows the Conventional Commits spec. This is a spec of what should and should not be in our commit messages so that when others(or yourself, three weeks later) read the commit messages, it is clear what exactly was changed. It also creates a more descriptive changelog when viewing all past commits at once. Although it is very easy to read, the initial rules are a bit to take in.

I strongly suggest taking a look at their docs or this slideshow to fully understand how the spec is structured. Briefly, your comment should always begin with one of the following “types”.

build, ci, chore, docs, feat, fix, perf, refactor, revert, style, test

You may include the scope of the commit(filename, feature of the app, etc.), albeit this is not required, followed by a short description of the modification.

Examples commitlint give are…

chore: run tests on travis cifix(server): send cors headersfeat(blog): add comment section

In order to ensure my commit messages meet the Conventional Commits specs and that the code is formatted correctly, on each commit we will utilize Git Hooks. Furthermore, to make it super easy on ourselves, we will use the NPM package Husky. All we are going to have to mess with is some NPM commands and edit our package.json a little. No need to go into that git hooks directory. Let’s get started!

Setting up Husky and commitlint

First, let’s install Husky and commitlint. Because we’re using it for development purposes, remember to throw the --save-dev flag. This ensure it won’t be a part of the the production build, which would just waste unnecessary space. To save a few seconds, we will just install both packages at the same time with the following command.

$ npm i --save-dev husky @commitlint/{config-conventional, cli}

Next, we need to configure commitlint to use the conventual config. (Note: this is a one-line command.)

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

Now all that’s left to do, is edit our package.json file. Add the following for v4 of Husky, which is the current stable release as of this writing.

{
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
}

Great! All set. Now when you run git commit -m <yourMessage> commitlint will check to make sure it meets the Conventional Commits specs. If it meets the specs, commitlint will allow the commit to be made. If it doesn’t, it will return an error letting you know what is wrong with the message.

I also use this vscode extension which takes all the guess work out of making sure my commit messages meet the Conventional Commits specs. However, with this hook installed, I never have to worry about other contributors’ commit messages breaking from the specs.

Setting up a pre-commit Hook with pretty-quick

Because we already installed Husky, all we need to do is install prettier and pretty-quick. Don’t forget the --save-dev flag!

$ npm install --save-dev prettier pretty-quick

Then edit the package.json

{
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"pre-commit": "pretty-quick --staged"
}
}
}

Now whenever you make a commit, all the code will be formatted to Prettier’s specs just before commit!

One last thing to note, if you are like me and excited about Deno checkout Velociraptor. It’s a “script runner for Deno, inspired by npm’s package.json scripts.” One of their upcoming features is “Husky style git hooks!”

--

--