DEV Community

Kaemon Lovendahl
Kaemon Lovendahl

Posted on

Making commits the right way with hooks

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
Enter fullscreen mode Exit fullscreen mode

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!"
  }
}
Enter fullscreen mode Exit fullscreen mode

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!
Enter fullscreen mode Exit fullscreen mode

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"
}
Enter fullscreen mode Exit fullscreen mode

"*.{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"
]
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Now add this to your package.json file.

"config": {
  "commitizen": {
    "path": "cz-conventional-changelog"
  }
}
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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!

Oldest comments (1)

Collapse
 
asjadanis profile image
Asjad Anis

Which version of husky are you using.
I am on version 7.0.1 and the githooks never trigger unless I manually add the hooks in .husky folder