Making commits the right way with hooks
Kaemon Lovendahl
Posted on August 27, 2020
Introduction
This tutorial will show you how to lint staged code and setup git commit hooks with husky so that you never have to spend time on the boring stuff!
Adding Packages
First things first let's start by adding the necessary packages.
yarn -D husky lint-staged commitizen
Feel free to view each of these repos in-depth.
Husky
Husky allows us to use call scripts using git-hooks
within our projects. There's a huge list of hooks that cover nearly every part of git. For now, we will just use pre-commit
and prepare-commit-msg
.
Add the following to your package.json
file.
"husky": {
"hooks": {
"pre-commit": "echo Hello World!"
}
}
You can add any git-hooks
within hooks
. The key must match a git-hook name, and the value can be any script or command. Committing the changes above should output the following to your console.
husky > pre-commit (node v12.16.1)
Hello World!
Lint-Staged
Lint-staged is specifically made to as the name implies, lint staged code before it gets committed.
If you don't use a linter you can skip this step. Although I highly recommend that you start as they are invaluable when used correctly.
Now, add the following to your package.json
file.
"lint-staged": {
"*.{js}": "eslint --ext .js --ignore-path .gitignore"
}
"*.{js}"
will run the specified command within each file that ends in .js
. You can add any number of file types. "*.{js,jsx,ts,tsx}"
will run on all React and TypeScript files.
eslint --ext .js --ignore-path .gitignore
lints any .js
packages. Similar with the key, you can list any number of --ext
files.
You can also run multiple commands by changing the value to an array. So if we want to use Prettier to format our code we could do something like this.
"*.{js}": [
"prettier --write",
"git add",
"eslint --ext .jsx --ext .js --ignore-path .gitignore"
]
After adding the above we need to let husky know to run the command.
// Change this
"pre-commit": "echo Hello World!"
// To this
"pre-commit": "lint-staged"
Now any staged files ending with .js
will be linted. The best part is that your code will fail to be committed if any commands fail. Now you can ensure that no one, including yourself, is pushing bad code.
Commitizen
commitizen/cli is an amazing tool that walks you through creating a git commit. Then formats it to conventional-commit standards.
Get started by running the following command to install the package.
yarn add -D cz-conventional-changelog --save-exact
Now add this to your package.json file.
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
}
You should now be able to run yarn cz
to start the cli tool! It'll walk you through a bunch of steps to create a conventional-commit.
Now we just need to apply it to husky. Thankfully commitizen shows us how to call the cli tool with git hooks using exec < /dev/tty && git cz --hook || true
as the hook command. The git-hook we'll apply it to is prepare-commit-msg
.
Your husky config should look something like this.
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"prepare-commit-msg": "exec < /dev/tty && git cz --hook || true"
}
}
That's it! Now all of your committed code will be linted, and force you to create a conventional-commit! Life becomes a little easier knowing that all committed code follows the same rules.
Ending Notes
There is a lot more you can do with Husky/Commitizen that isn't covered in this tutorial. I highly recommend you check their docs!
One additional feature that can be used with conventional-commits is generating changelogs for your projects!
Thanks for reading!
Posted on August 27, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.