Elevating Code and Commit Quality with Husky, Prettier, ESLint, Lint-Staged, and Commitlint

Pankaj Sharma
Naukri Engineering
Published in
5 min readNov 6, 2023
  • Commit quality code with Husky, Prettier, EsLint, and Lint-Staged
  • Meet the conventional commit format using commitlint and husky

Why do you need code quality?

A consistent and clean code is the cornerstone of code quality and it contributes to the success of a project. So, writing code is easy, but writing clean and consistent code is a tough task. Furthermore, each developer has their own unique coding style, making it challenging to maintain consistency within a project.

So, how can you achieve code quality?

It requires some rules/ guidelines to be documented and followed by every developer. But the true challenge arises, as a project scales to a large state or team grows, it becomes very critical to follow all the guidelines correctly.

Do you have any solution to enforce coding rules?

Yes! ESLint, Prettier, husky, and lint-staged tools provide capability to configure the rules and its enforcement to be followed. The combination of these tools offers real-time errors and warnings within your IDE while you’re coding.

How to Implement — Enforcing coding rules?

JavaScript projects should use linting tools and test scripts to have quality code. These tools significantly reduces debugging time and facilitates smoother peer code reviews.

  1. ESLint: This tool will help you catch and fix problems in your JavaScript/ TypeScript code. It checks for common syntax and style errors, making your code more consistent and easy to understand.
  2. Prettier: This is an opinionated code formatter. It enforces a consistent style by parsing your code and reprinting it with its own rules. This eliminates all original styling and guarantees consistency.

To enforce coding standards by running linting and test scripts for each git-commit action, it requires 2 tools:

  1. Husky: This tool improves your commits and more. It allows you to run scripts (like linting or tests) before committing your code, ensuring only quality code gets committed.
  2. Lint-Staged: When combined with Husky, it allows you to run linters on staged changes only, making the process faster and more efficient.

To enforce a commit message following the commit format for each git-commit action and test scripts for each git-commit action, it requires a Husky and commitlint tool.

  1. commitlint: This tool helps us to check if your commit messages meet the conventional commit format.

Work-flow on git commit action:

Work-flow on Git commit action
  • Every time you do a git-commit action, the Husky pre-commit gets triggered
  • Inside .husky/pre-commit you have defined that lint-staged gets run for every pre-commit action
  • Lint-staged will look for a lint-staged config to know what scripts (Linting tools like ESLint, prettier and commitlint) which will run specified scripts on matching staged files to run for each specified file type
  • The output of these scripts will be provided in the terminal by Lint-staged

Pre-requisites

  1. Familiarity with npm and package.json scripts.
  2. Knowledge of git commands.

Installation:

To set up ESLint, you need to run the below command that will ask questions about coding rules and install all dependencies.

npm init @eslint/config

Now, you have to install other npm packages using the below command. if few are already installed in your project. You can remove from below command

npm install --save-dev eslint prettier eslint-plugin-react eslint-plugin-react-hooks eslint-config-prettier eslint-plugin-prettier

If TypeScript configured in your project, you need to install below npm packages.

npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin

These packages include:

  • eslint: The core ESLint package.
  • prettier: The code formatter.
  • eslint-plugin-react: ESLint rules for React.
  • eslint-plugin-react-hooks: ESLint rules for React Hooks.
  • eslint-config-prettier: Disables ESLint rules that conflict with Prettier.
  • eslint-plugin-prettier: Integrates Prettier with ESLint.
  • husky: Enables Git hooks.
  • @typescript-eslint/parser: TypeScript parser for ESLint.
  • @typescript-eslint/eslint-plugin: TypeScript-specific ESLint rules.

Create three new files with the name .prettierrc, .eslintignore and .prettierignore in the root directory.

Copy the below lines to your .eslintignore and .prettierignore files to ignore below directories

node_modules
public
build
dist

Copy below code to .prettierrc file to follow prettier configurations

{
"bracketSpacing": true,
"semi": true,
"singleQuote": false,
"trailingComma": "es5",
"tabWidth": 2,
"printWidth": 80,
"endOfLine": "lf",
"arrowParens": "always"
}

Configuration: Below configuration steps are needed to initialize husky

  1. Install husky to project
npm install husky --save-dev

2. 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, you 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"
}
}

* if you have npm version > 7.24.1, else do the above entry in package.json file manually.

3. Configure hooks: Use below commands to configure pre-commit and commit-msg hooks

npx husky add .husky/pre-commit "npm command"
npx husky add .husky/commit-msg "npm command"
git add .husky/pre-commit

This will run npm command when you make a commit and will either pass or fail depending on your use-case (npm command could be npm test )

4. Install lint-staged as dev dependency

npm install --save-dev lint-staged

5. Use pre-commit hook to lint staged file and update below code to .husky/pre-commit file

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged

6. Add below lint-staged config to package.json file

// package.json
"lint-staged": {
"src/**/*.{js,jsx,ts,tsx,json}": [
"eslint --fix --max-warnings=0"
],
"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
"prettier --write"
]
},

7. Install commit-lint and configure commitlint.config.js file to extend from conventional config (Reference Link)

# Install and configure if needed
npm install --save-dev @commitlint/{cli,config-conventional}
# For Windows:
npm install --save-dev @commitlint/config-conventional @commitlint/cli

# Configure commitlint to use conventional config
echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js

8. To follow conventional commit format and use commit-msg hooks to validate commit message against extended conventional config (Reference Link), update below code to .husky/commit-msg file

#!/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: Are you following conventional commit rules"
⧗ input: foo: Are you following conventional commit rules
✖ subject must not be sentence-case, start-case, pascal-case, upper-case [subject-case]
✖ type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]

✖ found 2 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

husky - commit-msg hook exited with code 1 (error)

Conclusion:

By integrating ESLint/ Prettier into your git workflow with the pre-commit hooks, you can catch errors and inconsistencies very early on.

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.

Further Resources:

To know more about ESLint, Prettier, Husky, Lint-staged, you can refer to the below documentation of these technologies to discover more and ways to use git hooks.

--

--