🐶 Automate linting with Husky
- Published on
ESLint and Prettier are used to enforce a consistent style and follow code standards across JavaScript projects. It can be automated with the help of VSCode extensions (and WebStorm config), when saving a file.
The problem I observed was not everyone on my team had ESLint and Prettier extensions installed. Some of them were working with a barebones installation of VSCode. This caused some friction when things were commited and pushed upstream because the PR review comments had "Fix lint here", which in 2021 should not be something we should be spending our time on.
Another problem was with enforcing the conventional commit format.
Enter Husky. You can use it to lint your commit messages, run tests, lint code, etc... when you commit or push. Husky supports all Git hooks.
Perfect! Let's get started
Installing
First step is to install husky
to the project:
npm install husky --save-dev
Next to enable Git Hooks,
npx husky install
This creates a .husky/_/husky.sh
file in the project. .husky/_/husky.sh
file is always git ignored
If someone is cloning the repo for the first time, we can use the prepare
script to install husky
automatically
npm set-script prepare "husky install"
This would update the package.json
file to:
// package.json
{
"scripts": {
"prepare": "husky install"
}
}
Now anytime someone does a npm install
, prepare
script will take care of calling install
from Husky, creating the husky.sh
file on local machine.
Configure Hook
Now we can configure pre-commit
and commit-msg
hooks
npx husky add .husky/pre-commit "npm command"
git add .husky/pre-commit
This will run npm command
when we make a commit and will either pass or fail depending on your use-case.
Linting Staged Files
For my use-case, I want the pre-commit
hook to lint staged files. lint-staged
is the package I chose to do that work for me.
First I updated package.json
and included lint-staged
config.
// package.json
"lint-staged": {
"*.{js,jsx}": [
"eslint --cache --fix"
],
"*.{json,scss}": [
"prettier --write ."
]
}
Then in .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
And that's it. Now whenever we make a commit, lint-staged
will run both eslint
and prettier
and fix all fixable problems. No more lint comments in PR reviews.
Follow the conventional commit format.
- Automatically generating CHANGELOG.
- Automatically determining a semantic version bump (based on the types of commits landed).
- Communicating the nature of changes to teammates, the public, and other stakeholders.
- Triggering build and publish processes.
- Making it easier for people to contribute to your projects, by allowing them to explore a more structured commit history.
commitlint
checks if commit messages meet the conventional commit format.
First install the required packages:
# Install commitlint cli and conventional config
npm install --save-dev @commitlint/{config-conventional,cli}
Next configure commitlint.config.js
file to extend from conventional config.
module.exports = { extends: ['@commitlint/config-conventional'] }
Then in .husky/commit-msg
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit "$1"
You can test the hook by simply committing. You should see something like this if everything works.
git commit -m "foo: this will fail"
husky > commit-msg (node v10.1.0)
No staged files match any of provided globs.
⧗ input: foo: this will fail
✖ type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]
✖ found 1 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
husky > commit-msg hook failed (add --no-verify to bypass)
Fin
And that's it. Whenever there is a commit, the hooks run and makes sure everything is upto the project guidelines.
Pro-tip: Add a Contributing Guidelines section in your project README.md so that people who plan on contributing aren't thrown off as to why their commits aren't working.
Husky is a great tool to run scripts leveraging Git hooks. And it's not just limited to lint-staged
and commitlint
, since it is just a bash script, you can run anything from generating automated changelogs to running tests on each commit.
If you want to configure ESLint and Prettier, check out this post where I outline the installation steps, extensions required and the plugins I use on my projects.