Setting up precommit hooks for prettier, EsLint, jest
Published: 2021-01-10 19:13:08

# Introduction

Hello Developers. Today I am going to explain how to set up pre-commit hooks for prettier, EsLint & jest for your project.
Let me first explain what these are and their importance.

**Jest** is a javascript testing framework that can be used with many popular javascript frameworks. It allows us to run multiple tests and test suites and view the results in beautiful formats.

**EsLint** is a static code analyzer and javascript linter for your code.

**prettier** is a code formatter that helps you in formatting your code.

# Why are these required

As your application grows bigger, it gets difficult and costly to test your whole application. This also increases the possibility of bugs creeping into your application. You cannot be confident of the changes you made which in turn also slows down development. All these problems can be solved if you have tests that can automatically run and test your applications. Jest helps you write and run these tests and shows you the results of these tests.

Also, as the product grows, the number of people working on the codebase also increases. Each developer has his own style of formatting code. If everyone is allowed to use their own styles, the code written by one developer starts being esoteric to others. This again increases bugs in the software and slows down the development process. But, at the same time, developers do not like to be forced to follow standards. This is where prettier and Eslint come in. Eslint searches your code statically for javascript errors and ensures that the codebase is linted according to the standards specified. Prettier also formats your code so that it follows common standards. This ensures your code remains standardized and maintainable. 

# Installation

Lets start with installing these tools. As usual, npm makes the installation process very easy
```
npm install prettier --save-dev
npm install eslint --save-dev
npm install jest --save-dev
```

the --save-dev flag ensures that the packages are saved as a devDependency

Along with these, to configure eslint to use prettier, we need some other packages.
```
npm install eslint-plugin-prettier --save-dev
npm install eslint-config-prettier --save-dev
```

# Configuration

Since this tutorial is based on add a pre-commit hook, I will not go into the details about setting up jest tests. You can find various articles on the way to set up and run these tests.

For configuration prettier, create a .prettierrc file in the repository's root directory. Add the following to the file
```
{
  "printWidth": 85,
  "arrowParens": "always",
  "semi": true,
  "tabWidth": 2,
  "useTabs": false,
  "singleQuote": true,
  "trailingComma": "none",
  "bracketSpacing": true,
  "jsxBracketSameLine": true
}
```

This is a sample prettier configuration file - which defines how the code is to be formatted. This file states that all statements should end with a semi-colon. There shouldn't be a trailing comma, and angular brackets should be on the same line as the function. All tabs should be changed to spaces and the indentation width should be 2 spaces. You can create your own file by referring to the various configurations allowed by prettier.

For configuring EsLint, create a .eslintrc.json file. Here's a sample configuration for this file

```
{
  "env": {
    "browser": true,
    "es6": true,
    "jest": true
  },
  "extends": ["plugin:prettier/recommended"],
  "globals": {
    "Atomics": "readonly",
    "SharedArrayBuffer": "readonly"
  },
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 11,
    "sourceType": "module"
  },
  "plugins": ["prettier"],
  "rules": {
    "semi": [2, "always"],
    "react/no-unescaped-entities": 0,
    "react/prop-types": 0,
    "react/jsx-key": 0,
    "react/no-find-dom-node": 0,
    "no-unused-vars": 0,
    "no-array-constructor": 0,
    "new-cap": 0,
    "space-before-function-paren": 0,
    "prettier/prettier": "error"
  }
}
```

This file contains a lot of configuration info, but the important parts are the plugins part which tells eslint which plugin to use, and the rules that eslint should check for. Along with this configuration file, you also need to add a .eslintignore file to define the files and folders that are to be ignored by eslint. Here's a simple file which ignores the node_modules and the build folder:
```
**/build/*
**/dependencies/*
```

This completes the configuration step.

# Execution
To run jest automated test, just type
```
jest

```
This should run all the tests and show you the results of the tests in your terminal.

To run eslint type,
```
eslint . 
```
i.e eslint <folder-name>
eslint recursively checks all folders from the folder_name to search for lining errors and prints them on the screen. To automatically fix those errors. Type
```
eslint . --fix
```
This should fix all the automatically fixable errors.

To just run prettier type,
```
prettier . --write
```
This will run prettier recursively for all files inside the current directory and updating them in-place if it finds any inconsistencies

# Setting up precommit hook

With jest, eslint and prettier configured and executing successfully, the last step is to set up a pre-commit hook to run these tools automatically, every time a developer commits some changes to the repository. This will reduce the burden of running these scripts every time, before committing and also prevent cases where a developer may forget to run some of these tools.

To set up this pre-commit hook, we would be using 2 more tools. husky and lint-staged, install those tools using, yes you guessed it right, npm
npm install husky lint-staged --save-dev

Update your package.json to contain the following fields
```
... // other contents of package.json
"devDependencies": {
    ... // all your dev dependencies would be here.
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.{js,jsx}": [
      "prettier --write",
      "eslint --fix",
      "jest --findRelatedTests",
      "git add"
    ],
    "*.{html,css,less,ejs,json}": [
      "prettier --write",
      "git add"
    ]
  }
} // close package.json
```

husky sets up a pre-commit hook. It calls lint-staged before every commit. Depending on the type of file that is being committed, lint-staged runs certain commands. For E.g if it is a .js or .jsx file it runs prettier --write and eslint --fix on the file to update the file to appropriate standard, and then tests a subset of the tests to ensure that the changes do not cause tests to fail. If everything works, it adds the file to the staging area and commits it.

This way, all files being committed by you, are automatically
 formatted to ensure that they follow the code formatting rules, without you having to worry about it.

That's it. You're done.
Reach out to me if you need help setting up your project. I'll be happy to help.