How to setup your next react project(typescript + eslint + prettier + husky + lint-staged + cz-cli)
Tags: react, typescript, javascript, webdev
Published: 2022-01-22 09:00:52

Who doesn't like auto code formatting, right?
But when it comes to Js/Ts it's comparatively difficult to configure it properly.
I spent may hours googling, finding our how to do it properly.
This is the compilation has worked out best for me. Hope it helps the restless souls who are looking for a good step by step guide to setup their next big projects.

## Step 1: Basic Setup
We'll be using `Create-react-app` with typescript for our basic setup
run
```bash
npx create-react-app my-app --template typescript
cd my-app
```

##  Step 2: Eslint
Setup eslint in the repository
```bash
npm install eslint --save-dev
npm init @eslint/config
```
the cli will ask you some questions, you can answer them according to your needs to generate your specific eslint configuration.
In this project these answers are selected 

> Q. How would you like to use ESLint? 
> Ans. To check syntax, find problems, and enforce code style

> Q. What type of modules does your project use?
> Ans. JavaScript modules (import/export)

> Q.Which framework does your project use?
> Ans. React

>Q. Does your project use Typescript?
>Ans. Yes

> Q. Where does your code Run?
> Ans. Browser

> Q. How would you like to define a style for your project?
> Ans. Use a popular style guide

>Q. Which style guide do you want to follow?
>Ans. Airbnb: https://github.com/airbnb/javascript

>Q. What format do you want your config file to be in?
>Ans. JSON

>Q. Would you like to install them now with npm?
>Ans. Yes

at this point a `.eslintrc.json` file should be generated in your project root folder.
Navigate to App.tsx , you should notice eslint taking effect.
Hover over the error block, you should see some error message like this

> JSX not allowed in files with extension '.tsx'eslint[react/jsx-filename-extension](https://github.com/yannickcr/eslint-plugin-react/tree/master/docs/rules/jsx-filename-extension.md)

allow JSX on tsx files by adding this rule to your `.eslintrc.json` rules

```json
  "react/jsx-filename-extension": [
      1,
      { "extensions": [".js", ".jsx", ".ts", ".tsx"] }
    ]

```
now eslint will allow Jsx on .ts and .tsx files as well.

add this rule to allow importing files without specifying extensions

```json
 "import/extensions": "off"
```

For typescript project, you'll get [import/no-unresolved](https://github.com/import-js/eslint-plugin-import/blob/v2.25.4/docs/rules/no-unresolved.md) error. We can disable this error in the rules. But a better way to solve this is to use [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import).

run 
```bash
npm install eslint-plugin-import --save-dev
```
add the plugin in `.eslintrc.json` file

```json
  "extends": [
	 ...,
    "plugin:import/recommended",
    "plugin:import/typescript",
    ...
  ],
```

Now, the errors should be gone.

## Step 3: Prettier
 ### installing prettier
 
 ```bash
npm install --save-dev --save-exact prettier
```

create a `.prettierrc.json` file in your project root repository, add your prettier configs there.

add rules in your .prettierrc.json. Eg:
```json
{
    "tabWidth": 2,
    "semi": false,
    "singleQuote": true,
    "trailingComma": "es5",
    "useTabs": false
}
```

### configuring prettier with eslint
eslint may conflict with prettier rules , **[eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier)** resolves this issue for us.
run
```bash
npm install --save-dev eslint-plugin-prettier
npm install --save-dev eslint-config-prettier
```

add the plugin in eslint 

```json
  "extends": [
	 ...,
    "plugin:prettier/recommended",
    ...
  ],
```
at this point all the eslint conflicts with prettier should be resolved

## Step 4: Husky
We'll be adding husky to add eslint fix and prettier formatting in our pre-commit hook.

### install husky
```bash
npm install husky -D
npm set-script prepare "husky install"
npm run prepare
```
if the installation is successful a `prepare` script will be added to the `package.json`.

### adding lint-staged
We'll be using [int-staged](https://github.com/okonet/lint-staged) to run eslint and prettier on our staged files.
Add `.lintstagedrc.json` in the project root repository.
populate the file with your commands
```json
{
  "*.{js,jsx,ts,tsx}": ["prettier --write", "eslint --fix", "git add"],
  "*.{html,css,less,ejs}": ["prettier --write", "git add"]
}
```

### integrating lint-staged with husky
run
```bash
npx husky add .husky/pre-commit "npx lint-staged"
git add .husky/pre-commit
```
now husky pre-commit hook has been configured to run lint-staged.
and every time before committing the hook will run and fix eslint-errors and run prettier on staged files

## Step 5: Commitizen
Commit messages are very important for maintaining a project.
It can get difficult to maintain a similar commit convention when you are working in a larger team.
[cz-cli](https://github.com/commitizen/cz-cli) is here to help , we can enforce committing format by using the amazing tool.
We'll be using [conventional-changelog](https://github.com/ajoslin/conventional-changelog). configuration to follow [AngularJS's commit message convention](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines).

run
```bash
npm i --save-dev commitizen 
npx commitizen init cz-conventional-changelog --save-dev --save-exact
```

add this commit script in your `package.json`
```json
  "scripts": {
	...,
    "commit": "cz"
    ...
  }
```
add the following confi
add the following configuration to the project's  `package.json`  file:

```json
"husky": {
  "hooks": {
    "prepare-commit-msg": "exec < /dev/tty && git cz --hook || true"
  }
}
```

now for committing , instead of using `git commit`  use `npm run commit`/ `yarn commit`.
You'll get suggestions for commit messages.


That's all . Now your project is all ready to be linted, formatted and it'll be easier for your teammates to follow a similar code convention throughout the code base.

You can find all the code in this [repo](https://github.com/FahadAminShovon/react-setup-ts)