AK

Ankur Kedia

Ankur

BlogProjects

Gear up your React codebase with Prettier and ESLint Automation

Improve your codebase and commits with Prettier, ESLint, Husky and Commitlint

6 Sep, 20214 min read
React Starter

Recently, I noticed that there were repetitive tasks that I was doing for all the new projects. So, I decided to document them so as not to repeat the mistakes. This article is about setting up Prettier, ESLint, Husky in your project.

This article can help you with:

  • Keeping your code clean.
  • Following standard practices in your code.
  • Ensuring that all the tests pass before commit.
  • Improving commit quality by adhering to the conventional commit format.

Steps to setup

  • Create a React app any way you like. I prefer to do it with NPX.

    For TypeScript project:
    npx create-react-app my-app --template typescript
    For JavaScript project:
    npx create-react-app my-app
    You can also use Yarn or NPM. You can check out CRA docs for more details.
  • Open the project: cd my-app.
  • Installing dependencies:

    With TypeScript:
    yarn add -D eslint eslint-plugin-react prettier prettier-eslint eslint-plugin-jest eslint-plugin-react-hooks @typescript-eslint/eslint-plugin @typescript-eslint/parser husky @commitlint/{config-conventional,cli}
    The versions of packages at the time of writing are:
    package.json
    {
    "devDependencies": {
    "@commitlint/cli": "^13.1.0",
    "@commitlint/config-conventional": "^13.1.0",
    "@typescript-eslint/eslint-plugin": "^4.29.0",
    "@typescript-eslint/parser": "^4.29.0",
    "eslint": "^7.32.0",
    "eslint-plugin-jest": "^24.4.0",
    "eslint-plugin-react": "^7.24.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "husky": "^7.0.1",
    "prettier": "^2.3.2",
    "prettier-eslint": "^13.0.0"
    }
    }
    With JavaScript:
    yarn add -D eslint eslint-plugin-react prettier prettier-eslint eslint-plugin-jest eslint-plugin-react-hooks husky @commitlint/{config-conventional,cli}
    The versions of dependencies at the time of writing are:
    package.json
    {
    "devDependencies": {
    "@commitlint/cli": "^13.1.0",
    "@commitlint/config-conventional": "^13.1.0",
    "eslint": "^7.32.0",
    "eslint-plugin-jest": "^24.4.0",
    "eslint-plugin-react": "^7.24.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "husky": "^7.0.1",
    "prettier": "^2.3.2",
    "prettier-eslint": "^13.0.0"
    }
    }
  • Add Prettier config: create .prettierrc with this content. Also, install the Prettier plugin in VSCode.
    .prettierrc
    {
    "singleQuote": true,
    "jsxBracketSameLine": false,
    "useTabs": false,
    "eslintIntegration": false,
    "tslintIntegration": true,
    "requireConfig": false,
    "stylelintIntegration": false,
    "arrowParens": "always",
    "bracketSpacing": true,
    "embeddedLanguageFormatting": "auto",
    "htmlWhitespaceSensitivity": "css",
    "insertPragma": false,
    "jsxSingleQuote": true,
    "tsxSingleQuote": true,
    "printWidth": 80,
    "proseWrap": "preserve",
    "quoteProps": "as-needed",
    "requirePragma": false,
    "semi": true,
    "tabWidth": 2,
    "trailingComma": "es5"
    }

    Note: I prefer this config, you can use Playground and choose what works for you. You can check out the rationale and the options to understand the rules better.

  • Add ESLint config: create .eslintrc.json with this config. Also, install the ESLint plugin in VSCode.

    For TypeScript:
    .eslintrc.json
    {
    "settings": {
    "react": {
    "version": "detect"
    }
    },
    "env": {
    "browser": true,
    "es2021": true,
    "node": true
    },
    "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:react-hooks/recommended"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
    "ecmaFeatures": {
    "jsx": true
    },
    "ecmaVersion": 12,
    "sourceType": "module"
    },
    "plugins": ["react"],
    "rules": {
    "no-bitwise": 0,
    "react/react-in-jsx-scope": "off",
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn",
    "@typescript-eslint/ban-ts-comment": "off",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/no-explicit-any": "off"
    }
    }
    For JavaScript:
    .eslintrc.json
    {
    "settings": {
    "react": {
    "version": "detect"
    }
    },
    "env": {
    "browser": true,
    "es2021": true,
    "node": true,
    "jest": true
    },
    "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:react-hooks/recommended"
    ],
    "parserOptions": {
    "ecmaFeatures": {
    "jsx": true
    },
    "ecmaVersion": 12,
    "sourceType": "module"
    },
    "plugins": ["react"],
    "rules": {
    "no-bitwise": 0,
    "react/react-in-jsx-scope": "off",
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn"
    }
    }
    The rules I have used are basically to override the recommended settings. The only addition being the rules of hooks.

    Note: Again, these are rules that I prefer, you can add the ones that work for you. You can check ESLint configuration docs to create your rules.

  • Add scripts to package.json

    For TypeScript:
    package.json
    {
    "scripts": {
    "lint": "eslint \"**/*.{ts,tsx,js,jsx}\"",
    "prepare": "husky install",
    "test": "react-scripts test"
    }
    }
    For JavaScript:
    package.json
    {
    "scripts": {
    "lint": "eslint \"**/*.{js,jsx}\"",
    "prepare": "husky install",
    "test": "react-scripts test"
    }
    }
  • Resolve lint errors: run yarn lint and resolve all warnings and errors (if any). You might see warnings and errors like this:
    warning 'temp' is assigned a value but never used @typescript-eslint/no-unused-vars
    1 problem (0 errors, 1 warning)
  • Add Commitlint config:
    echo "module.exports = {extends: ['@commitlint/config-conventional']};" > commitlint.config.js
    Conventional config is used here, you can also define your config with different rules.
  • Install git hooks yarn prepare / npm prepare

    Note: Using Husky with Yarn 2 requires different steps.

  • Add hooks: you can add any number of hooks you need. In this case, we are adding a pre-commit hook that will check the linting and run tests. We are also adding a Commitlint hook.
    npx husky add .husky/pre-commit 'yarn lint && yarn test --watchAll=false'
    npx husky add .husky/commit-msg 'npx --no-install commitlint --edit $1'
    For more specific use cases for Husky, you can check the recipes.

Et voila, this is all you needed to do. You can test the hooks by simply committing.

git commit -m "foo: this will fail"
You should see this in the terminal.
⧗ input: foo: this will fail
type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]
✖ found 1 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
husky - commit-msg hook exited with code 1 (error)

Note: If you want to skip these hooks, you can commit directly with -n/--no-verify option like git commit -m "yolo!" --no-verify

If you are starting with a new project, you can clone these repos with all the steps already done.

theankurkedia/react-starter-ts-template

A React TypeScript starter project with basic optimal configuration for development

github.com

theankurkedia/react-starter-template

A React starter project with basic optimal configuration for development

github.com

Discuss on Twitter

Share on