Lint Staged With Husky for Pre-commit Validations
Really often we want to run some check for our code like linting before our commit. And we can easily do it by using lint-staged
and husky
. This is why in this post you will learn how to use them together in order to implement such functionality.
Do we have a problem?
What do we want to solve? Just imagine that you have a huge project. And you need to run some linting, tests or code formatting in your changed files. You worked on some feature, you finished it and now you want to run this checks.
Here we have 2 problems. If you just run commands from the console, you will run them for all files inside your project. It doesn't make any sense because it will ages. And if your project is super big it can take several minutes.
What we want to do instead is to run all commands just for our changed files.
Lint-staged
Typically you are using Git and it knows exactly what files you changed.
The second important point is that every developer can forget to run these commands by hands before they make the commit or push their changes to remote repository.
Which actually means that we must somehow configure this logic so all these commands will be called automatically and they will be called only for changed files.
For this in Javascript world we use 2 packages: lint-staged and husky.
We use lint-stage to run commands only for our changed files. What are changed files? These are just staged files inside Git.
As you can see after git add .
we have green staged file. This is exactly what lint-staged
will run commands on.
Lint-staged runs linters (on any other commands) on staged Git files.
Husky
The second package that we will use is called husky
. This package can add prehooks for commit or push inside Git. Let's say that we want to run Eslint and Prettier before commit. But we want to do it automatically. This is exactly why do we need husky.
What I want to do now is configure lint-staged and husky for our project. I have create-react-app but it doesn't matter. It will work with any project.
Installation
The first step here will be to install both packages.
npm install husky
npm install lint-staged
Our next step here is to install libraries or tools that we will use for linting or prettifying. This is why here I want to configure Prettier and then Eslint because these are 2 most popular linters.
npm install prettier
npm init @eslint/config
We used npm init
which will not only install Eslint for us but also create a default config file. Here we get some questions to create correct configuration. I just hit enter on every question.
Lint-staged configuration
All our packages are installed. Now we can jump back in our package.json
and configure here our lint-staged
.
"lint-staged": {
"src/**/*.{js,html.css}": "prettier --write",
"src/**/*.js": "eslint"
}
Here we defined that for all Javascript, Html and CSS files in src directory we want to run prettier
and apply formatting to the files. For Javascript files we want also to run eslint
command.
Now inside console we can directly run lint-staged
command which will use correct config.
npm lint-staged
As you can see lint-staged
didn't do anything because we don't have any changes. But the command is working fine.
Husky configuration
Now we must configure husky
package. And actually for husky
we have a special command which will install our husky
script and configure pre-commit for Git.
npx husky-init && npm install
npx husky add .husky/pre-commit "npm test"
First command will install husky and create Git hooks. Second command will add new pre-commit script with npm test
string.
Now inside our project we have new .husky
folder. Inside we have a pre-commit
file which we just created. Also we have .husky/_/husky.sh
. This is a shell script that we should not touch. But what we want to do now is update pre-commit file
.
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
Instead of npm test
we must call lint-staged
just like we did in console. This means that before every commit we will call our lint-staged
commands for all changed files like we defined.
Now let's make some change and do a commit.
As you can see at the moment of our commit lint-stage
command was called and Eslint failed with an error. Which actually means that we successfully configured lint-staged
together with husky
to make pre-commit checks for our changed files.
Want to conquer your next JavaScript interview? Download my FREE PDF - Pass Your JS Interview with Confidence and start preparing for success today!
📚 Source code of what we've done