DEV Community

Cover image for Learn to configure ESLINT and PRETTIER in react
Suprabha
Suprabha

Posted on

Learn to configure ESLINT and PRETTIER in react

Why linting your code is important?

Linting will checks out the code without executing it.

The best part of a linter is finding potential errors in your code that don’t look like them.

ESLint ✍️

ESLint parses your code, analyses it, and runs linting rules. These rules may trigger warnings or errors to let you know if your code is right or wrong.

Example:

// ❌ Oops, what is multiple?
const output = multiple(1, 2);
Enter fullscreen mode Exit fullscreen mode

ESLint wouldn’t know what add refers to and would throw an error at you. You need to explicitly declare add to correct it:

// ✅ Correct
function multiple() {}
const output = multiple(1, 2);
Enter fullscreen mode Exit fullscreen mode

Install Eslint:

Globally

$ npm install eslint -g
Enter fullscreen mode Exit fullscreen mode

OR

$ npm install eslint eslint-plugin-react lint-staged --save-dev
Enter fullscreen mode Exit fullscreen mode

NOTE: If you are using VS code, then install the plugin: ESLint extension for VSCode. It will highlight errors and warnings directly in your code.

Configure ESLint ⚙︎

ESLint is highly configurable. Just add .eslintrc file at the root of your project, and then you can run ESLint on any files you want.

If you want to skip eslint for some code then add the comment to your code: // eslint-disable-next-line

Exmaple:

// eslint-disable-next-line
const result = multiple(1, 2);
Enter fullscreen mode Exit fullscreen mode

NOTE: Use it with caution, It’s very bad idea to disable ESLint every time it spots errors.

ESLint CLI ☀︎

ESLint has a CLI to lint files. You can find all the options on ESLint’s docs. The one you will use the most is the --fix option, which fixes the files when ESLint can.

package.json:

{
  "scripts": {
        "pre-commit": "lint-staged",
    "lint": "eslint .", // lint the codebase
  },
    "lint-staged": {
    "*.+(js|jsx)": [
      "eslint --fix", // try to fix whatever it can fix
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

ESLint Configuration ⚙︎

.eslintrc.js:

// eslint-disable-next-line no-undef
module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: ["eslint:recommended", "plugin:react/recommended"],
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: "module",
  },
  plugins: ["react"],
  rules: {
        "no-console": "warn",
        "import/first": "error"
    "react/prop-types": 0,
    "linebreak-style": ["error", "unix"]
  },
}
Enter fullscreen mode Exit fullscreen mode

Once you add above snippet, you will get type error. To fix it add:
.eslintrc.js:

// eslint-disable-next-line no-undef
module.exports = {
  ...
}
Enter fullscreen mode Exit fullscreen mode

The above ESLint config meets the following requirements:

Checkout CRA for more interesting config.

Prettier 🗽

It helps in formatting the codebase.

Using Prettier, we can follow common code style.

Install Prettier:

$ npm install prettier --save-dev
Enter fullscreen mode Exit fullscreen mode

NOTE:

If you are using VS code, then install the plugin: Prettier extension for VSCode. It will highlight errors and warnings directly in your code.

Configure Prettier ⚙︎

It will format your code, but sometimes you won't like it. You can modify the prettier config via .prettierrc or via prettier key in package.json.

  • singleQuotetrue if you want to use single quotes, false otherwise.
  • printWidth: a number that specifies the line length that the printer will wrap on.
  • semitrue if you want to print semicolons at the end of every statement, false otherwise.

Check this out for prettier option.

.eslintrc.js:

extends: ["prettier"],
  plugins: ["prettier"],
  rules: {
    "prettier/prettier": "error",
    "linebreak-style": ["error", "unix"],
    "arrow-body-style": "off",
    "prefer-arrow-callback": "off",
  },
}
Enter fullscreen mode Exit fullscreen mode

Prettier CLI ☀︎

Using --write option which is similar to --fix in eslint.

package.json:

{
     "lint-staged": {
    "*.+(js|jsx)": [
      "prettier --write --ignore-unknown"
    ],
    "*.+(json|css|md)": [
      "prettier --write"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Enable formatOnSave in Vscode

Look for formatOnSave and check the checkbox, or add this line to settings.json:

"editor.formatOnSave": true,
Enter fullscreen mode Exit fullscreen mode

Integrate Prettier with ESLint ⛩

ESLint has formatting rules too like max-len (similar to printWidth) or quotes.

Prettier replaces ESLint’s formatting rules but doesn’t replace code-quality rules.

Thus, you can integrate Prettier in your ESLint configuration by installing the following:

$ npm install eslint-config-prettier eslint-plugin-prettier --save-dev
Enter fullscreen mode Exit fullscreen mode

eslint-config-prettier disables rules that conflict with Prettier. At the same time eslint-plugin-prettier adds the rule that format content using Prettier. You can enable this configuration by using the recommended one:

.eslintrc.js:

{
  "extends": ["plugin:prettier/recommended"]
}
Enter fullscreen mode Exit fullscreen mode

Prettier Configuration:

.prettierrc.json:

{
  "printWidth": 85,
  "arrowParens": "always",
  "semi": false,
  "tabWidth": 2
}
Enter fullscreen mode Exit fullscreen mode

Basically, it means that Prettier:

  • Will wrap on line that exceeds 85 characters.
  • Will always use parenthesis around arrow functions, even if there is one argument.
  • Won’t print semicolons at the end of every statement.
  • Will use two spaces per indentation level.

Lint and format at each commit 🗺

You can lint and run a codebase, great. But does it mean that now you should lint and format your code whenever you want? No!

If you are using GIT, you can make use of Git hooks to run ESLint and Prettier before each commit or each push.

husky 🐶

It's not dog. We’re talking about the tool that allows you to set up Git hooks very easily

Let’s say your package.json has the following scripts, and you want to run lint and format at each commit:

package.json:

{
  "scripts": {
        "postinstall": "husky install && cd app && yarn install",
  },
  "devDependencies": {
    "husky": "^6.0.0",
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Install husky as a dev dependency:

Then, you can add Git hooks in two easy steps:

  1. Install husky
  2. Add pre commit

  3. Install husky

$ npm install husky --save-dev
Enter fullscreen mode Exit fullscreen mode
  1. Add pre commit Adding pre-commit to your project by 2 approach:

Approach 1:

Create .husky in root and pre-commit file:

.husky/pre-commit:

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

yarn run pre-commit
Enter fullscreen mode Exit fullscreen mode

Approach 2:

Insert the following code in your package.json:
package.json

{
  "husky": {
    "hooks": {
      "pre-commit": "npm run lint && npm run format"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

That’s all. At each commit, the command associated with pre-commit will be run. So your codebase will be linted and formatted.

pre-commit is the most used Git hook by far, but you can also use other hooks like pre-push or post-commit.

lint-staged 🚀

The more your codebase will grow, the more linting and formatting will be longer. Imagine you have more than 1000 components. You don’t want to wait for ESLint to lint all your codebase, don’t you? In the end, the only files that need to be linted are the ones that just have been modified. For that, you can use lint-staged.

Install lint-staged:

$ npm install --save-dev lint-staged
Enter fullscreen mode Exit fullscreen mode

Then, you have to add a lint-staged key to your package.json file for the configuration. According to lint-staged docs, the configuration should be an object where each value is one or more commands to run, and its key is a glob pattern to use for these commands.

package.json:

{
  "lint-staged": {
    "*.+(js|jsx)": "eslint --fix",
    "*.+(json|css|md)": "prettier --write"
  }
}
Enter fullscreen mode Exit fullscreen mode

The above configuration will allow you to run ESLint and fix both .js and .jsx files. In the same time, it will run Prettier on .json, .css and .md files.

Then, let’s tell ESLint we’ll use Prettier's configuration:

.eslintrc.js:

{
  extends: ["prettier"],
  plugins: ["react", "prettier"]
}
Enter fullscreen mode Exit fullscreen mode

Once done, we need to specify the options to Prettier. For that, either create a .prettierrc file or add a prettier key to the package.json. We’ll choose the first option:

.prettierrc.json:

{
  "semi": false,
  "singleQuote": false,
  "tabWidth": 2,
  "printWidth": 80
}
Enter fullscreen mode Exit fullscreen mode

Let’s add the pre-commit hook on staged files. We need to install both husky and lint-staged in the devDependencies for that:

$ npm install --save-dev husky lint-staged
Enter fullscreen mode Exit fullscreen mode

Then, we’ll add the pre-commit hook itself by adding a husky key to package.json:

package.json

{
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

If we leave this as-is, it will fail because we haven’t specified the configuration for lint-staged, so let’s do it right away:

{
  "lint-staged": {
    "*.+(js|jsx)": [
      "eslint --fix",
      "prettier --write --ignore-unknown"
    ],
    "*.+(json|css|md)": [
      "prettier --write"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Here we use ESLint to lint and format JS and JSX files. We also use Prettier to format json, css and markdown files. You’re perfectly set up.

Here is the full package.json file:

package.json

{
  "name": "react-eslint-prettier-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    ...
  },
  "scripts": {
    "postinstall": "husky install && cd app && yarn install",
        "test": "cd app && yarn test",
        "pre-commit": "lint-staged",
        ...
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "*.+(js|jsx)": [
      "eslint --fix",
      "prettier --write --ignore-unknown"
    ],
    "*.+(json|css|md)": [
      "prettier --write"
    ]
  }
  "devDependencies": {
        "eslint": "^7.24.0",
    "eslint-config-prettier": "^8.1.0",
    "eslint-plugin-prettier": "^3.3.1",
    "eslint-plugin-react": "^7.23.2",
    "husky": "^6.0.0",
    "lint-staged": "^10.5.4",
    "prettier": "2.2.1",
  }
}
Enter fullscreen mode Exit fullscreen mode

.eslintrc.js:

// eslint-disable-next-line no-undef
module.exports = {
  env: {
    browser: true,
    es2021: true,
  },
  extends: ["eslint:recommended", "plugin:react/recommended", "prettier"],
  parserOptions: {
    ecmaFeatures: {
      jsx: true,
    },
    ecmaVersion: 12,
    sourceType: "module",
  },
  plugins: ["react", "prettier"],
  rules: {
    "prettier/prettier": "error",
    "react/prop-types": 0,
    "linebreak-style": ["error", "unix"],
    "arrow-body-style": "off",
    "prefer-arrow-callback": "off",
  },
}
Enter fullscreen mode Exit fullscreen mode

NOTE:

After making above changes, if the code doesn't work then restart your code editor.

🌟 Twitter 👩🏻‍💻 suprabha.me 🌟 Instagram

Top comments (2)

Collapse
 
penguintheorem profile image
Attilio Urbani

Hello,

thanks for the article, it's very helpful! I had to install eslint-plugin-import first before setting this rule "import/first": "error", is that correct?

Collapse
 
alyahyaoui profile image
alyahyaoui

It comes pre configured with create react app