Setting up Eslint(airbnb configuration), Prettier and Husky pre-commit hooks in CRA 
Tags: codequality, eslint, prettier, huskycommit
Published: 2021-10-04 11:51:38

Talk is cheap, lets directly get into how to get setting up eslint, prettier and husky pre-commit hook DONE.
## 1. Install eslint as dev dependency
  * `npm install eslint --save-dev` 
  * if using yarn `yarn add eslint --dev`

## 2. Setup eslint configuration 
 * `npx eslint --init`
 * if using yarn `yarn run eslint --init`
 * above will ask for few configurations I had selected for my purpose below configuration
  * eslint to check syntax and find problems, project react, project uses typescript yes, typeof module JavaScript, format of configuration .json.
* ![ESLint configuration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3u17omxfjxsozjlnw1x.png)

## 3. Install airbnb style guide
 * `npm install eslint-config-airbnb —-save-dev` or `yarn add eslint-config-airbnb --dev`
 * if copying above command doesn't work type the same
 * `npx install-peerdeps --dev eslint-config-airbnb`

## 4. Edit `.eslintrc.json` file created in *step 2*
 * Add inside `extends` rule `"airbnb"`
 * my current extends rule inside .eslintrc.json
 
```json
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/recommended",
        "airbnb"
    ]    
```

## 5. Lets test if everything is working fine till now 
 * create a `test.js (or .ts, .jsx, .tsx)` file 
 * write some code which is against the airbnb style guide
 * e.g 
```javascript
var a   = 4;
```
 * then run command `./node_moduels/.bin/eslint test.js`
 * it should throw eslint erros with specific rules
 ![Linting Errors](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3tjkt8giisw9iy76sonf.png)
* If you are getting above linting errors implies your eslint set up is correct till now

## 6. Set up `prettier`
 * `npm install prettier --save-dev` or `yarn add prettier --dev`
 * since prettier and eslint have their own set of formatting rules to avoid conflicts lets install plugin
 * `npm install eslint-config-prettier --save-dev` or `yarn add eslint-config-prettier --dev`
 * I wanted prettier to be run as eslint rule to do that add another plugin
 * `npm install eslint-plugin-prettier --save-dev` or `yarn add eslint-plugin-prettier --dev`
 * now add above plugins in `extends` rule of `.eslintrc.json` i.e eslint configuration file
 * add to the existing rule of extends : `"plugin:prettier/recommended"`
* Currently `extends` is
```json
"extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/recommended",
        "airbnb",
        "plugin:prettier/recommended"
    ],
``` 
* [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier)  [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier)

## 7. Now lets again run the test.js file using command 
 * `./node_modules/.bin/eslint test.js` prettier errors should also be reported ideally
![Formatting errors are overridden by Prettier](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mrqcv8o8c8dr69zxebrc.png)
* Observe the difference between this image and image at step 5

## 8. VS Code eslint extenstion to rescue
 * It is unrealistic to run this command on every file we will be coding manually , here comes the VS code [eslint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) to rescue, once restart after installing it, now as you code it will highlight the linting errors hurreeyy 
e.g
![VSCode eslint extension](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e7w8bdfftgjrr87q0kms.png)

## 9. Now I wan't scripts (which will lint and format the changes done by me in a commit) 
 * Lets first include the scripts then we will come to husky
 * include below scripts inside `scripts` in `package.json`
  ```json
 "scripts": {
     "_lint": "eslint --config ./.eslintrc.json --ext js --ext jsx --ext tsx --ext ts",
    "lint": "npm run _lint -- ./src/",
    "lint:fix": "npm run _lint -- --fix ./src/",
    "format": "prettier --write './**/*.{js,jsx,ts,tsx,css,scss,md,json}' --config ./.prettierrc",
}
```
* [reason why -- is added](https://stackoverflow.com/questions/40271230/how-to-run-eslint-fix-from-npm-script/58954298#comment117386806_58954298)

* you can create `.prettierrc` file in root location i.e `/`
* sample `.prettierrc` file
```json
{
	"printWidth": 80,
	"tabWidth": 2,
	"trailingComma": "none",
	"semi": true,
	"htmlWhitespaceSensitivity": "css",
	"quoteProps": "as-needed",
  "overrides": [
    {
      "files": "*.css",
      "options": {
        "parser": "css"
      }
    },
    {
      "files": "*.scss",
      "options": {
        "parser": "scss"
      }
    }
  ]
}
```
 * [prettier options](https://prettier.io/docs/en/options.html)



## 10. Now lets integrate linting to be run on all staged files included in a commit 
 * here comes to rescue [lint-staged](https://github.com/okonet/lint-staged)

## 11. I know its a lot, one more final step
 * as official docs say only command is enough to set up and here it is 
`npx mrm@2 lint-staged`
 * this command will install and configure [husky](https://github.com/typicode/husky) and [lint-staged](https://github.com/okonet/lint-staged) 
 * now add change lint-staged configuration in package.json
```json 
"lint-staged": {
    "src/**/*.{js,ts,jsx,tsx}": [
      "eslint --config ./.eslintrc.json --ext js --ext ts --ext jsx --ext tsx"
    ]
  }
```
* or if you want eslint to automatically fix linting errors possible by eslint, add below configuration(like it replaces var with const or let, it adds a new line at the end of file automatically, etc)
```json 
"lint-staged": {
    "src/**/*.{js,ts,jsx,tsx}": [
      "eslint --config ./.eslintrc.json --ext js --ext ts --ext jsx --ext tsx --fix"
    ]
  }
```
* what this does is what ever .js, .ts, .jsx, .tsx staged files are present in src directory in a commit are linted by eslint.
![DEMO](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xy6w7292se47iq9g98v.png)
* Note that I have not added `"prettier --write"` in the array of commands to be run in pre-commit hook since eslint will do it for us due to plugin [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier)
* I personally don't like including --fix since I don't get to know mistakes done by me.


* as you can see prettier formatted the code and added in staging, and eslint showed errors hence commit was not successful



**Ahh finally we are done, now you can start your development server `npm run start` **


I am sure you got some errors if(there would have been any eslint erros in your code base src directory), 
* whats happening is react-scripts doesn't start the server if there are any eslint errors 
* Tell me how to avoid it
* add `ESLINT_NO_DEV_ERRORS='true'` just before `react-scripts start` command

Now you are good to do development, hope everything goes well while doing deployment



But its not so
* when you do `npm run build` again `react-scripts build` doesn't build if there are any eslint errors
* add `DISABLE_ESLINT_PLUGIN='true'` before `react-scripts build`

Now yes nothing else is remaining, 
I always wanted to set up eslint, prettier husky pre-commit hook from the day I had seen this cool stuff, had ready various blogs docs, were not able to setup it properly, finally this weekend I did it, hurrreyyy.



## Better Code Quality, easier PR reviews across team.