ESLint and Prettier setup on VSCode for React dev
I find that I'm setting up ESLint and Prettier way too often nowadays, fumbling through blog posts, stack overflow questions, and official docs every time! π
So I think it's time that I write about it now and copy-paste it later. Hopefully you'll find it as useful as my future self would. βοΈ
What is linting and why do we need it?
You want to automate the enforcement of a code style guide for your (or your team's) JS code:
- detect bugs and errors early during dev time π
- have them fixed automatically to save effort and mental energy π€
π More on Style Guides: Prettier - Building and enforcing a style guide
You probably don't need this guide if:
You use a framework with ESLint baked in, like
- Gatsby
- an un-ejected Create React App
- codesandbox
You need this guide if:
You use a bare-bones React setup like
Let's see how you can simplify your tooling once and for all! First let's clarify the difference between ESLint and Prettier.
ESLint - a linter
- linter, aka static code analysis tool
- identify and report bugs and problematic patterns, like syntax and semantic errors
- e.g. undefined variables, modification of constants, implicit globals, use of
==
, ... - extremely configurable - rules to enable/disable, parsers, plugins
Prettier - a formatter
- formatter, aka prettifier or pretty print tool
- reprints your code to adhere to formatting rules of a style guide
- e.g. fixes max line length, whitespace, tabs, spaces, semicolon, comma, ...
In short, ESLint for code quality and Prettier for code formatting
Initial repo
Here's an example React repo using bare-bones Parcel and Babel.
Focus on src/Hello.jsx
with a lot of formatting errors, which we want to lint.
- Github repo before fixes: react eslint prettier
π Parcel is a zero-config bundler as an alternative to Webpack. Babel compiles JSX and other new-gen JS to regular JS that browsers understand.
ESLint - install and config
# install eslint as a dev dep on your project
npm install eslint -D
# initial config
npx eslint --init
eslint --init
shows a wizard-like CLI to setup ESLint and install deps at the end.
npx
is a tool included with npm to run not-global tools via CLI
Here's the options I picked:
Results:
.eslintrc.js
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: [
'plugin:react/recommended',
'airbnb',
],
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12,
sourceType: 'module',
},
plugins: [
'react',
],
rules: {
},
};
The eslint
wizard also installed configs and plugins for us.
package.json
"devDependencies": {
// ...
"eslint": "^7.12.0",
"eslint-config-airbnb": "^18.2.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0",
// ...
}
π Full details on config options here: Configuring ESLint
You can also run eslint CLI manually, e.g. npx eslint --fix src/Hello.jsx
for a specific file and npx eslint --fix .
to autofix all files, but I want to focus here on integrating with VSCode
VSCode ESLint extension
Install this ESLint extension from VSCode's extension tab
We'll do the config for autofix on save later
Watch out for global and local ESLint conflicts
If you have ESLint installed and configured both globally (in your machine) and locally (in your project), you might get this error.
I suggest to "Allow" local config to be used, to respect individual repo's ESLint rules. Any plugins you use must be installed locally anyways.
Look ma, lints!
At this point, you should see some lints on Hello.jsx
π It would be nice to fix the formatting issues, and for that we need Prettier.
Prettier - install and config
# install prettier to dev deps with exact version
npm install -DE prettier
# create an empty config file, initialize with an empty object
echo {}> .prettierrc.json
Put this initial config:
.prettierrc.json
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": false,
"singleQuote": false,
"trailingComma": "all",
"bracketSpacing": true,
"jsxBracketSameLine": false
}
Feel free to customize to your liking. Here's a quick rundown of some options:
printWidth
: max line length. More than that, Prettier wraps to next linetabWidth
: number of spaces per indentsemi
: semicolons required if truesingleQuote
: strings must be 'single quoted' if true, "double quoted" if falsejsxBracketSameLine
andbracketSpacing
are IMPORTANT FOR JSX to make component tags more readable
There's only a few options to configure for Prettier, compared to ESLint.
π More details at Prettier install and initial config
You can also run prettier
CLI manually, e.g. npx prettier --write src/
. But we'll focus here on integrating Prettier with ESLint, to have auto-fix on save with VSCode.
Integrating ESLint with Prettier
Run Prettier from ESLint
We'll use an ESLint plugin that runs Prettier as if it was a linter rule.
npm install -D eslint-plugin-prettier
- Add
prettier
plugin to ESLint config as the last item. - In the
rules
object, add prettier "error" as the last item.
..eslintrc.js
{
// ...
"plugins": [
// ...
"prettier"
],
"rules": {
// ...
"prettier/prettier": "error"
}
// ...
}
π The other way to integrate is to run both ESLint and Prettier separately. See Prettier ESLint
Eliminate conflicting rules
Fundamentally, it's better to leave code quality to ESLint, and code formatting to Prettier.
But ESLint also have stylistic rules that can conflict with Prettier, like semicolon and quotes rules.
To resolve this, we'll use a config to turn off ESLint rules that conflicts with Prettier.
npm install -D eslint-config-prettier
Add prettier/recommended
config rules in ESLint config extends
. If it's not yet an array, make it an array and add prettier as the last entry.
.eslintrc.js
{
// ...
"extends": [
// ...
"plugin:prettier/recommended"
]
// ...
}
This is the Recommended Configuration when using eslint-plugin-prettier
plugin and eslint-config-prettier
config.
π€ Last piece is to have VSCode automatically fix issue on save.
VSCode - fixing issues automatically on save
Note that since we are using ESLint to run Prettier, we only need the ESLint extension, not the Prettier one.
In VSCode, go to Settings (CTRL + SHIFT + P) then search for "Open Settings JSON". Choose the "Folder" option - Preferences: Open Folder Settings (JSON)
This creates a .vscode/settings.json
in our project folder (if it doesn't exist yet). This settings is scoped only to our project so it won't conflict with the other repos you have.
If you intend to apply this globally on all folders in VSCode, you can use global(user) instead Preferences: Open Settings (JSON).
Add these configs in the object:
settings.json
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
π For other options: VSCode ESLint extension
Update: You don't need VSCode's Prettier extension and formatOnSave
setting
If you're using ESLint to run Prettier as defined here, make sure to either:
- Disable or remove Prettier VSCode extension.
- Leave the default or set VSCode's
editor.formatOnSave
tofalse
. HavingcodeActionsOnSave
set toeslint
is the right way to go.
Fixing time!
Go to all the files that has lint errors, and just save them. That simple! π
I showed File > Save in the gif, but you can just Ctrl + S as usual
Do the same for hooks.jsx
and .eslintrc.js
which had some formatting issues as well.
"Unfixable" errors
ESLint can only fix "auto-fixable" problems.
In this example, you'll have to manually add PropTypes
and add name
to your prop types validation.
Bonus: Hooks linting
If you check hooks.jsx
, there are a lot of violations to React Rules of Hooks that are left undetected.
For that, we'll need a ESLint plugin
npm install -D eslint-plugin-react-hooks
Add it to the extends
.eslintrc.js
{
// ...
"extends": [
// ...
"plugin:react-hooks/recommended"
]
// ...
}
Now we're getting lint errors for using hooks in functions that are not components or custom hooks. π
Update: Fix for weird formatting on JSX - use prettier/react
I noticed recently that even though auto fix was working fine on functions and hooks, JSX gets weird after a few indentation levels.
But why?
We fixed conflicting rules above above.
But since we are using Airbnb preset, which enables eslint-plugin-react
behind-the-scenes, this causes some conflicts! π±
Thus, the "tug of war" between ESLint and Prettier indentation and spacing rules. βοΈ
Add prettier/react
exclusion
As explained here, it's not enough to use 'prettier' or 'prettier-recommended' under eslint-config-prettier
to override the other configs like Airbnb.
We also have to add prettier/react
at the end to override those rules.
Update 06/2021: Use prettier
instead of prettier/react
or any prettier/*
- Since
eslint-config-prettier
8.0.0, all theprettier/*
configs have been merged intoprettier
. See the changelog for details
.eslintrc.js
{
// ...
"extends": [
"plugin:react/recommended",
"airbnb",
"plugin:prettier/recommended",
"plugin:react-hooks/recommended",
// ...
"prettier", // <--- add this; `prettier/react` for eslint-config-prettier < 8.0.0
]
// ...
}
π For additional exclusions and more info eslint-config-prettier installation
Code
- Github repo after fixes: react eslint prettier
Conclusion
Hope this helps π€, because this will definitely help me. π€
Update: I've looked at this guide myself at least 5 times in the last few months.
Worth it! π
Catch you in the next one! Enjoy fixing those errors. β β‘οΈ β