DEV Community

Cover image for How To Add Prettier and ESLint Automation to a React Codebase
swyx
swyx

Posted on • Edited on • Originally published at swyx.io

How To Add Prettier and ESLint Automation to a React Codebase

"Civilization advances by extending the number of important operations which we can perform without thinking about them." β€” Alfred North Whitehead

I've just implemented Prettier + ESLint on my React codebase at work and figured I'd better share my notes in case others need to figure this out.

My setup includes:

  • See lint violations inline in VSCode
  • Prettify after PR merge with GitHub actions
  • Prettify before git commit (some folks dislike this)
  • Ability to manually run checks locally

Even if you use TypeScript, you'll want BOTH Prettier and ESLint in your codebase. Prettier doesn't always do what you mean and ESLint checks things that Prettier doesn't. For historical reasons, this codebase doesn't use TypeScript, don't @ me, my love for TypeScript is well documented.

Step 1: Dependencies

yarn add -D eslint eslint-plugin-react husky lint-staged prettier

# or npm i -D eslint eslint-plugin-react husky lint-staged prettier
Enter fullscreen mode Exit fullscreen mode

as of time of writing these are the versions I am working with:

{
  "devDependencies": {
    "eslint": "^7.27.0",
    "eslint-plugin-react": "^7.23.2",
    "husky": "^6.0.0",
    "lint-staged": "^11.0.0",
    "prettier": "^2.3.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Note that this setup requires more work if you using Husky v6 with Yarn 2.

Step 2: Scripts

add stuff to package.json...

{
  "scripts": {  
    "format": "prettier --write .",
    "prepare": "husky install"
  },
  "lint-staged": {
    "**/*": "prettier --write --ignore-unknown"
  },
}
Enter fullscreen mode Exit fullscreen mode

You can now run npm run format to prettify your existing codebase as a oneoff.

In case you were wondering:

  • Husky adds a git commit hook so that...
  • Lint-staged only runs Prettier on new stuff that you stage in git

Step 3: Prettier Settings

Commence bikeshedding! Use the Prettier Playground to decide on what settings your team wants.

Put this in .prettierrc.json

{
    "arrowParens": "always",
    "bracketSpacing": false,
    "embeddedLanguageFormatting": "auto",
    "htmlWhitespaceSensitivity": "css",
    "insertPragma": false,
    "jsxBracketSameLine": false,
    "jsxSingleQuote": false,
    "printWidth": 80,
    "proseWrap": "preserve",
    "quoteProps": "as-needed",
    "requirePragma": false,
    "semi": true,
    "singleQuote": false,
    "tabWidth": 2,
    "trailingComma": "es5",
    "useTabs": false,
  } 
Enter fullscreen mode Exit fullscreen mode

Step 4: ESLint

You know you gotta...

module.exports = {
    "env": {
        "browser": true,
        "es2021": true,
        "node": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended"
    ],
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 12,
        "sourceType": "module"
    },
    "plugins": [
        "react"
    ],
    "rules": {
        "react/prop-types": [0, {}], // this is dumb, why is this still recommended
        "react/no-unescaped-entities": [0, {}],
        "no-unused-vars": [1, {}],
    }
};
Enter fullscreen mode Exit fullscreen mode

Recommended: also enable the ESLint VSCode plugin to see the eslint feedback in your editor!!!

Step 5: Automate

We'll just add a nifty little GitHub Action in .github/workflows/autoformat.yml:

name: Continuous Integration

# This action works with pull requests and pushes
on:
  pull_request:
  push:
    branches:
      - master

jobs:
  prettier:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v2
        with:
          # Make sure the actual branch is checked out when running on pull requests
          ref: ${{ github.head_ref }}

      - name: Prettify code
        uses: creyD/prettier_action@v3.3
        with:
          # This part is also where you can pass other options, for example:
          prettier_options: --write **/*.{js,md}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

That's it!

Top comments (4)

Collapse
 
mendoza profile image
David Mendoza (He/Him)

I'm not 100% sure if you take this in mind, but basically since husky 5 they don't get the script from the package.json you could use
npm i husky@4

Collapse
 
swyx profile image
swyx

hmm i checked the docs and for husky v6 it seems fine with the prepare script typicode.github.io/husky/#/?id=manual

Collapse
 
mendoza profile image
David Mendoza (He/Him)

Ohh I see, great I didn't knew that command.

Collapse
 
swyx profile image
swyx

ohh thats annoying. ok thank you!