How to add ESlint, Prettier, and Husky (Git Hook) in React JS 2022

nerdjfpb

Muhammad Ali (Nerdjfpb)

Posted on February 18, 2022

How to add ESlint, Prettier, and Husky (Git Hook) in React JS 2022

Introduction

Today we are going to make our life easier a little bit! As developers, we have to work in a team (in most cases). Different person has different styles, so it's hard to follow a specific coding pattern. Also, some people like four spaces as a tab, and some like 2. So code format also looks weird if there are no specific rules. Today we are going to fix the problem together. Let's enforce a coding style using eslint and format our code automatically using prettier!

Motivation

There is a reason why I'm writing this blog. I learned to program from tutorials (mostly udemy ones)! I never saw anyone is showing how to add eslint/prettier anywhere. But I learned about it while working with a side project (as freelance work). Around 2020 I was getting a good amount of leads from Fiverr to work. But it was hard for me to work on the projects because I started my current full-time. So, I took the help of my friend, and honestly, the code he wrote looks bad formatted and does not properly follow any coding styles. I always used eslint & prettier in my vscode, so I never faced this issue about formatting & following coding styles. But I wasn't really interested in setup his IDE because it's not something I can force on someone. Then I learned about eslint & prettier more. I made a setup, which helped me gain what I was trying too hard to get. It made my life so easier. After setting up both, I never saw terrible formatting in the app, and minor issues like not using any variables are gone! This is why I'm showing this to you. Maybe it'll save a lot of time for you! If this helps, share it with a person who needs this. Let's make the dev team strong with knowledge sharing! But before that, lets jump into the next section -

Things I’m using

  • Visual studio code
  • nodejs
  • create react app
  • npm packages
    • eslint
    • prettier
    • eslint-plugin-prettier
    • husky
    • lint-staged

Basic React app

We'll start with a basic React app, and we'll use create-react-app -

npx create-react-app your-app-name
Enter fullscreen mode Exit fullscreen mode

This will be a react app and we're not going to change anything because this tutorial is not related to reactjs. We're going to work directly on the next step! The more straightforward step of this tutorial is prettier. So let's dive into it!

Prettier

We use prettier to auto-format our code. This saves a lot of time for me. I've also installed a vscode extension, which helps me a lot. So let's install it.

npm i prettier -D
Enter fullscreen mode Exit fullscreen mode

We're using a -D for only installing it as dev dependencies. We don't need to send this into our build. Once it is installed, let's try to format our code with prettier. But to do that, we need to create a prettier config file. Because prettier doesn't know how to format our codes, let's create that file. It'll be on our root folder, and the file name will be .prettierrc.

{
 "trailingComma": "es5",
 "tabWidth": 2,
 "semi": false,
 "singleQuote": true
}
Enter fullscreen mode Exit fullscreen mode

You can configure a lot of things with it. Click here to find out more. But We're going with a simple configuration. I like tabWidth two spaces, and I don't like semicolons much. All will be handled using prettier now. Isn't this awesome???

Eslint

Eslint helps us to enforce a coding style. You can define your own coding style. Mostly I use airbnb style. So let's install it. But if you have time, read the rules from eslint website -

npm i eslint -D
Enter fullscreen mode Exit fullscreen mode

Sadly it's not going to end here. You need to create a config file for eslint. There are two ways to do it; you can do it by

  • Eslint
  • Manual

I prefer to use Eslint and I'll show that way because it's easier. Let's start the process by typing -

./node_modules/.bin/eslint --init
Enter fullscreen mode Exit fullscreen mode

Then it'll popup

? How would you like to use ESLint? ...
  To check syntax only
  To check syntax and find problems
> To check syntax, find problems, and enforce code style
Enter fullscreen mode Exit fullscreen mode

I'll choose To check syntax, find problems, and enforce code style because I want to check syntax, find problems, and enforce code style! Then it'll show -

? What type of modules does your project use? ...
> JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these
Enter fullscreen mode Exit fullscreen mode

I'll choose Javascript modules (import/export) because I want to use import/export, not the old require/exports. Select and then -

? Which framework does your project use? ...
> React
  Vue.js
  None of these
Enter fullscreen mode Exit fullscreen mode

Choose the framework you are using, and this is a dumb question, right? We're using this inside reactjs. Let's select that -

? Does your project use TypeScript? » No / Yes
Enter fullscreen mode Exit fullscreen mode

We're not using Typescript so let's click at no! Then it'll show -

? Where does your code run? ...  (Press <space> to select, <a> to toggle all, <i> to invert selection)
√ Browser
√ Node
Enter fullscreen mode Exit fullscreen mode

We'll use the browser to check the results, so select and -

? How would you like to define a style for your project? ...
> Use a popular style guide
  Answer questions about your style
Enter fullscreen mode Exit fullscreen mode

I'll choose the Use a popular style guide one. Because that's easy to install and many developers already know about it. But if you want manual styles, just go with the Answer questions about your style option. Let's select it -

? Which style guide do you want to follow? ...
> Airbnb: https://github.com/airbnb/javascript
  Standard: https://github.com/standard/standard
  Google: https://github.com/google/eslint-config-google
  XO: https://github.com/xojs/eslint-config-xo
Enter fullscreen mode Exit fullscreen mode

There are a few style guides already. I choose airbnb most of the time. Go with the one you like!

What format do you want your config file to be in? ...
> JavaScript
  YAML
  JSON
Enter fullscreen mode Exit fullscreen mode

I normally just choose JSON because it's the easiest to read. But you can choose whatever you like too!

Checking peerDependencies of eslint-config-airbnb@latest
Local ESLint installation not found.
The config that you've selected requires the following dependencies:

eslint-plugin-react@^7.28.0 eslint-config-airbnb@latest eslint@^7.32.0 || ^8.2.0 eslint-plugin-import@^2.25.3 eslint-plugin-jsx-a11y@^6.5.1 eslint-plugin-react-hooks@^4.3.0
? Would you like to install them now with npm? » No / Yes
Enter fullscreen mode Exit fullscreen mode

Let's install the packages now! It'll take a little bit of time. Finally, we'll see the .eslintrc.json file! Have a first look at it.

Our eslint setup is done, but it will not work with prettier well. We need to do some more configuration to enable both to work together!

Configure eslint & prettier together

This section also starts with installing an npm package called eslint-plugin-prettier, which will help us configure eslint and prettier together. We'll install it with -

npm i eslint-plugin-prettier -D
Enter fullscreen mode Exit fullscreen mode

We need to add this plugin inside .eslintrc.json file -

{
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "plugin:react/recommended",
        "airbnb"
    ],
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "plugins": [
        "react", "prettier"
    ],
    "rules": {
      "semi": 0,
      "comma-dangle": 0,
      "prettier/prettier": "error",
      "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }]
    }
}
Enter fullscreen mode Exit fullscreen mode

I updated the last two-part - plugins and rules. This will help us to work prettier and eslint together. Don't worry; there is no more configuration needed for eslint and prettier.

Also, let's add two scripts to our package.json file. This will help us to lint files by npm run lint and format our code by npm run pretty -

 "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "lint": "eslint --fix",
    "pretty": "prettier --write ."
  }
Enter fullscreen mode Exit fullscreen mode

One quick note: In your project, maybe some files you don't want to lint or format. So you can add them to .eslintignore file -

node_modules
public
build
Enter fullscreen mode Exit fullscreen mode

For the ignore format, you can use .prettierignore

# Ignore artifacts:
build
coverage

# Ignore all HTML files:
*.html
Enter fullscreen mode Exit fullscreen mode

But there is still a problem remaining. This all will work if you use an IDE with extensions like - eslint & prettier. Without it'll not format automatically. We can force it by using script in package.json file. But let's find a better solution!

Husky

To force our coding style & format, we will use git hook. So that if anyone commits any code, it runs some linting and check if there is any issue with it. For this, we're going to use husky and lint-staged -

npm i husky lint-staged -D
Enter fullscreen mode Exit fullscreen mode

This will just install the package. But for using lint-staged we need to edit our package.json file. Let's add some lines -

 "lint-staged": {
  "**/*.{js,jsx}": [
    "npm run lint",
    "prettier --write"
  ]
 }
Enter fullscreen mode Exit fullscreen mode

With these four lines, we are just linting and formatting our code. But it's not called from anywhere now. So we need to call it from somewhere. But before that, we need to install husky properly to run it -

npx husky-init && npm install
Enter fullscreen mode Exit fullscreen mode

This will create a folder called .husky and inside it a file called pre-commit which will run npm test before committing. But for the current project, we don't want to run the npm test, so we are going to change it into -

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

# npm test
npx lint-staged
Enter fullscreen mode Exit fullscreen mode

Now we can try committing in git, and it'll show us if there is an error! Now we are finally ready to test our project!

Result and Testing

We'll not explore the git today with this tutorial. Because git is a big topic and that needs another blog. You can quickly do a crash course on the git. Then came back here to see what I was doing from this point. First, I'll change a little bit on the app.js file; going to add an extra line that we don't need (Just to showcase what we have done so far)

import React from 'react'
import logo from './logo.svg'
import './App.css'

function App() {
  const tempVar = 5

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit
          <code>src/App.js</code>
          and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  )
}

export default App
Enter fullscreen mode Exit fullscreen mode

I just added the const tempVar = 5 after the function, and let's try to commit this into the github repo. I'm using

git add .
git commit -m "Initial Commit"
Enter fullscreen mode Exit fullscreen mode

Now I'm getting an error.

[STARTED] Preparing lint-staged...
[SUCCESS] Preparing lint-staged...
[STARTED] Running tasks for staged files...
[STARTED] package.json — 10 files
[STARTED] **/*.{js,jsx} — 2 files
[STARTED] npm run lint
[FAILED] npm run lint [FAILED]
[FAILED] npm run lint [FAILED]
[SUCCESS] Running tasks for staged files...
[STARTED] Applying modifications from tasks...
[SKIPPED] Skipped because of errors from tasks.
[STARTED] Reverting to original state because of errors...
[SUCCESS] Reverting to original state because of errors...
[STARTED] Cleaning up temporary files...
[SUCCESS] Cleaning up temporary files...

✖ npm run lint:
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! react-eslint-prettier@0.1.0 lint: `eslint --fix "C:/Users/demo/Desktop/nerdworks/Blogs Examples/react-eslint-prettier/src/App.js" "C:/Users/demo/Desktop/nerdworks/Blogs Examples/react-eslint-prettier/src/index.js"`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the react-eslint-prettier@0.1.0 lint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\demo\AppData\Roaming\npm-cache\_logs\2022-02-18T18_07_55_543Z-debug.log

> react-eslint-prettier@0.1.0 lint C:\Users\demo\Desktop\nerdworks\Blogs Examples\react-eslint-prettier
> eslint --fix "C:/Users/demo/Desktop/nerdworks/Blogs Examples/react-eslint-prettier/src/App.js" "C:/Users/demo/Desktop/nerdworks/Blogs Examples/react-eslint-prettier/src/index.js"


C:\Users\demo\Desktop\nerdworks\Blogs Examples\react-eslint-prettier\src\App.js
  6:9  error  'tempVar' is assigned a value but never used  no-unused-vars

✖ 1 problem (1 error, 0 warnings)

husky - pre-commit hook exited with code 1 (error)
Enter fullscreen mode Exit fullscreen mode

Maybe it'll look overwhelming at first. But if you read from last, you'll understand what we are doing here. Here the problem is showing on.

6:9  error  'tempVar' is assigned a value but never used  no-unused-vars
Enter fullscreen mode Exit fullscreen mode

So that tempVar we created is creating an issue. Why? Because we are not using this variable. So just delete this and try to commit again. This time it'll just work fine -

STARTED] Preparing lint-staged...
[SUCCESS] Preparing lint-staged...
[STARTED] Running tasks for staged files...
[STARTED] package.json — 10 files
[STARTED] **/*.{js,jsx} — 2 files
[STARTED] npm run lint
[SUCCESS] npm run lint
[STARTED] prettier --write
[SUCCESS] prettier --write
[SUCCESS] **/*.{js,jsx} — 2 files
[SUCCESS] package.json — 10 files
[SUCCESS] Running tasks for staged files...
[STARTED] Applying modifications from tasks...
[SUCCESS] Applying modifications from tasks...
[STARTED] Cleaning up temporary files...
[SUCCESS] Cleaning up temporary files...
[master 205b14e] Initial Commit
13 files changed, 449 insertions(+), 119 deletions(-)
 create mode 100644 .eslintignore
 create mode 100644 .eslintrc.json
 create mode 100644 .husky/pre-commit
 create mode 100644 .prettierignore
 create mode 100644 .prettierrc
 rewrite README.md (99%)
 delete mode 100644 src/App.test.js
 rewrite src/index.js (78%)
 delete mode 100644 src/reportWebVitals.js
 delete mode 100644 src/setupTests.js
Enter fullscreen mode Exit fullscreen mode

This way, all the files will be used eslint & prettier before going to our GitHub repository!

Outro

I hope that this one helps you to work with your team in a better manner. That was the primary goal of this blog! Also, we can easily see the Eslint error and prettier automatically using vscode extensions. I also use some other extensions; you can check it here -

Github Repo

You can find it from here - https://github.com/nerdjfpb/react-eslint-prettier

Questions?

Drop a dm on - twitter

Want to be part of an amazing programming community and participate in free programming events?

Join our Discord server

Want to hire me for your next project?

Connect me with linkedin

💖 💪 🙅 🚩
nerdjfpb
Muhammad Ali (Nerdjfpb)

Posted on February 18, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related