Why use ESLint
Currently, there are no worthy competitors for ESLint, it is a project that has been maintained by a very large community. Most coding programs support it, we will not have trouble using it with VSCode, Vim, Emac, WebStorm, Sublime, Atom, …
Because of that, why waste such a delicious package ^^
Install ESLint
Like any other package, ESLint can be installed at two levels:
- One is global, always install
npm -g
- And the second is to go by project
The global implementation of ESLint makes sense since we want to use it in every project. However, it makes sense to install separately on each project if you need the following elements:
- ESLint versions differ from project to project
- Publicly you depend on ESLint for that project
- Colleagues and automated tools (like the CI guys) can install ESlint like any other package.
Install ESLint in the project directory
1 2 |
npm i eslint --save-dev |
Run ESLint in the project
1 2 |
npx eslint |
To create a shortcut to the command that runs eslint. Inside the package.json
file add the following line:
1 2 3 4 |
<span class="token string">"scripts"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"lint"</span> <span class="token operator">:</span> <span class="token string">"eslint ."</span> <span class="token punctuation">}</span> |
Parameters . lets run ESLint inside the current directory, we run the command via the shortcut
1 2 |
npm run lint |
ESLint installation file
The ESLint installation file can be placed in many locations. If there are no special needs, a single file in the outermost directory (root) is sufficient.
ESLint allows to use many types of files:
- Javascript
- JSON
- YAML
Use YAML in this example. Create a file named .eslintrc.yaml
, this if you run eslint init in the src/
directory of the project it will ask if you want to create, it creates.
1 2 |
eslint <span class="token operator">--</span> init |
If you want to add logic with code, you need to use javascript type
The first thing to care about is to tell ESLint what language we are writing, which version, and the environment in which the code will run. Without the information, ESLint won’t run.
1 2 3 4 5 |
parserOptions <span class="token operator">:</span> ecmaVersion <span class="token operator">:</span> <span class="token number">6</span> env <span class="token operator">:</span> node <span class="token operator">:</span> <span class="token boolean">true</span> |
Pure Javascript
With the project is pure javascript, the entire file is .js, can be defined from the beginning, but that is quite time consuming, difficult to maintain, not sure because it depends on your understanding of javascript.
Many big companies like Google, Airbnb, and Facebook spend billions of billions of time maintaining and updating these settings.
Use the ten thousand favorite settings, Airbnb
1 2 |
npx install <span class="token operator">-</span> peerdeps <span class="token operator">--</span> dev eslint <span class="token operator">-</span> config <span class="token operator">-</span> airbnb <span class="token operator">-</span> base |
There are articles on the net that will ask you to install eslint-config-airbnb
, which includes the React, React Hooks, … settings. Not necessary in case the project is just regular javascript.
Notice we are NOT using npm
to install, but using npx install-peerdeps
. It will install which packages the eslint-config-airbnb-base
depends on. When we use ESLint we will see it all the time, because it almost depends on a few other packages.
Once installed, declare it will inherit Airbnb’s installation
1 2 3 |
<span class="token keyword">extends</span> <span class="token operator">:</span> <span class="token operator">-</span> airbnb <span class="token operator">-</span> base |
Airbnb’s settings can be said to be very popular and trusted by many large and small projects. We can use it with peace of mind without much change.
summary
1 2 3 4 5 6 |
<span class="token string">"devDependencies"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"eslint"</span> <span class="token operator">:</span> <span class="token string">"^6.1.0"</span> <span class="token punctuation">,</span> <span class="token string">"eslint-config-airbnb-base"</span> <span class="token operator">:</span> <span class="token string">"^14.0.0"</span> <span class="token punctuation">,</span> <span class="token string">"eslint-plugin-import"</span> <span class="token operator">:</span> <span class="token string">"^2.20.0"</span> <span class="token punctuation">(</span> peer dependency <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 |
parserOptions <span class="token operator">:</span> ecmaVersion <span class="token operator">:</span> <span class="token number">6</span> env <span class="token operator">:</span> node <span class="token operator">:</span> <span class="token boolean">true</span> <span class="token keyword">extends</span> <span class="token operator">:</span> <span class="token operator">-</span> eslint <span class="token operator">:</span> recommended <span class="token operator">-</span> airbnb <span class="token operator">-</span> base |
TypeScript settings
The main problem with TypeScript is that ESLint cannot automatically parse, we have to add a parser @typescript-eslint/parser
.
Setting
1 2 |
npm install @typescript-eslint/parser --save-dev |
Parse reads the input file and creates a version that ESLint understands.
Declare to use this parser
1 2 |
parser <span class="token operator">:</span> <span class="token string">"@typescript-eslint/parser"</span> |
Also update package.json
and tell ESLint not to check the file .js
but to check the file .ts
1 2 3 4 |
<span class="token string">"scripts"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"lint"</span> <span class="token operator">:</span> <span class="token string">"eslint . --ext .ts"</span> <span class="token punctuation">}</span> |
Similar to javascript, we use Airbnb’s settings
1 2 3 |
npx install <span class="token operator">-</span> peerdeps <span class="token operator">--</span> dev eslint <span class="token operator">-</span> config <span class="token operator">-</span> airbnb <span class="token operator">-</span> typescript npm i eslint <span class="token operator">-</span> plugin <span class="token operator">-</span> <span class="token keyword">import</span> <span class="token operator">--</span> save <span class="token operator">-</span> dev |
eslint-plugin-import
must be installed separately, manually, for no reason why.
Update the ESLint config file again
1 2 3 4 |
<span class="token keyword">extends</span> <span class="token operator">:</span> <span class="token operator">-</span> airbnb <span class="token operator">-</span> typescript <span class="token operator">/</span> base <span class="token operator">-</span> plugin <span class="token operator">:</span> @typescript <span class="token operator">-</span> eslint <span class="token operator">/</span> recommended |
You may be wondering, why haven’t we installed @typescript-eslint
that we can use, actually when we installed eslint-config-airbnb-typescript
we installed it with npx install-peerdeps
Maybe another rule can be directly referenced from the documentation on github
Finally, you will find there are a lot of articles out there, only you set up
1 2 3 |
plugins <span class="token operator">:</span> <span class="token operator">-</span> <span class="token string">"@typescript-eslint"</span> |
If the recommended ESLint settings are not used, this is not necessary. The reason is that Airbnb has already enabled such rules.
summary
package.json
1 2 3 4 5 6 7 8 |
<span class="token string">"devDependencies"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"@typescript-eslint/eslint-plugin"</span> <span class="token operator">:</span> <span class="token string">"^2.17.0"</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> peer dependency <span class="token punctuation">)</span> <span class="token string">"@typescript-eslint/parser"</span> <span class="token operator">:</span> <span class="token string">"^2.17.0"</span> <span class="token punctuation">,</span> <span class="token string">"eslint"</span> <span class="token operator">:</span> <span class="token string">"^6.8.0"</span> <span class="token punctuation">,</span> <span class="token string">"eslint-config-airbnb-typescript"</span> <span class="token operator">:</span> <span class="token string">"^6.3.1"</span> <span class="token punctuation">,</span> <span class="token string">"eslint-plugin-import"</span> <span class="token operator">:</span> <span class="token string">"^2.20.0"</span> <span class="token punctuation">}</span> |
.eslintrc.yaml
1 2 3 4 5 6 7 8 9 10 |
parserOptions <span class="token operator">:</span> ecmaVersion <span class="token operator">:</span> <span class="token number">6</span> env <span class="token operator">:</span> node <span class="token operator">:</span> <span class="token boolean">true</span> <span class="token keyword">extends</span> <span class="token operator">:</span> <span class="token operator">-</span> airbnb <span class="token operator">-</span> typescript <span class="token operator">/</span> base <span class="token operator">-</span> plugin <span class="token operator">:</span> @typescript <span class="token operator">-</span> eslint <span class="token operator">/</span> recommended |
React settings
Adding ESLint settings for React is incredibly simple, everything Airbnb
has to worry about.
One of the common mistakes is to assume that writing like below will enable React support
.eslintrc.yaml
1 2 3 4 |
parserOptions <span class="token operator">:</span> ecmaFeatures <span class="token operator">:</span> jsx <span class="token operator">:</span> <span class="token boolean">true</span> |
React uses JSX, but in a way that ESLint can’t understand. In order for React and ESLint to talk to each other, we have to use eslint-plugin-react
React Javascript
Install the package
1 2 |
npx install-peerdeps --dev eslint-config-airbnb |
.eslintrc.yaml
1 2 3 4 5 |
<span class="token keyword">extends</span> <span class="token operator">:</span> <span class="token operator">-</span> airbnb env <span class="token operator">:</span> browser <span class="token operator">:</span> <span class="token boolean">true</span> |
package.json
1 2 3 4 |
<span class="token string">"scripts"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"lint"</span> <span class="token operator">:</span> <span class="token string">"eslint . --ext .js,.jsx"</span> <span class="token punctuation">}</span> |
If you use React Hook, you should add the following settings (accessibility checking is omitted).
.eslintrc.yaml
1 2 3 4 5 |
<span class="token keyword">extends</span> <span class="token operator">:</span> <span class="token operator">-</span> airbnb <span class="token operator">-</span> base <span class="token operator">-</span> airbnb <span class="token operator">/</span> rules <span class="token operator">/</span> react <span class="token operator">-</span> airbnb <span class="token operator">/</span> hooks |
summary
package.json
1 2 3 4 5 6 7 8 9 |
<span class="token string">"devDependencies"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"eslint"</span> <span class="token operator">:</span> <span class="token string">"^6.1.0"</span> <span class="token punctuation">,</span> <span class="token string">"eslint-config-airbnb"</span> <span class="token operator">:</span> <span class="token string">"^18.0.1"</span> <span class="token punctuation">,</span> <span class="token string">"eslint-plugin-import"</span> <span class="token operator">:</span> <span class="token string">"^2.20.0"</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> peer dependency <span class="token punctuation">)</span> <span class="token string">"eslint-plugin-jsx-a11y"</span> <span class="token operator">:</span> <span class="token string">"^6.2.3"</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> peer dependency <span class="token punctuation">)</span> <span class="token string">"eslint-plugin-react"</span> <span class="token operator">:</span> <span class="token string">"^7.18.0"</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> peer dependency <span class="token punctuation">)</span> <span class="token string">"eslint-plugin-react-hooks"</span> <span class="token operator">:</span> <span class="token string">"^1.7.0"</span> <span class="token punctuation">(</span> peer dependency <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
.eslintrc.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 |
parserOptions <span class="token operator">:</span> ecmaVersion <span class="token operator">:</span> <span class="token number">6</span> env <span class="token operator">:</span> browser <span class="token operator">:</span> <span class="token boolean">true</span> <span class="token keyword">extends</span> <span class="token operator">:</span> <span class="token operator">-</span> airbnb <span class="token operator">-</span> airbnb <span class="token operator">/</span> hooks rules <span class="token operator">:</span> react <span class="token operator">/</span> react <span class="token operator">-</span> <span class="token keyword">in</span> <span class="token operator">-</span> jsx <span class="token operator">-</span> scope <span class="token operator">:</span> off |
Free to sit and watch all this
React TypeScript
If we use TypeScript, we cannot install npx install-peerdeps
, but we must install it independently
1 2 3 4 5 6 7 8 |
npm install eslint <span class="token operator">-</span> config <span class="token operator">-</span> airbnb <span class="token operator">-</span> typescript eslint <span class="token operator">-</span> plugin <span class="token operator">-</span> <span class="token keyword">import</span> eslint <span class="token operator">-</span> plugin <span class="token operator">-</span> jsx <span class="token operator">-</span> a11y eslint <span class="token operator">-</span> plugin <span class="token operator">-</span> react eslint <span class="token operator">-</span> plugin <span class="token operator">-</span> react <span class="token operator">-</span> hooks @typescript <span class="token operator">-</span> eslint <span class="token operator">/</span> eslint <span class="token operator">-</span> plugin <span class="token operator">--</span> save <span class="token operator">-</span> dev |
.eslintrc.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
parserOptions <span class="token operator">:</span> ecmaVersion <span class="token operator">:</span> <span class="token number">6</span> env <span class="token operator">:</span> browser <span class="token operator">:</span> <span class="token boolean">true</span> <span class="token keyword">extends</span> <span class="token operator">:</span> <span class="token operator">-</span> airbnb <span class="token operator">-</span> typescript <span class="token operator">-</span> airbnb <span class="token operator">/</span> hooks <span class="token operator">-</span> plugin <span class="token operator">:</span> @typescript <span class="token operator">-</span> eslint <span class="token operator">/</span> recommended rules <span class="token operator">:</span> react <span class="token operator">/</span> react <span class="token operator">-</span> <span class="token keyword">in</span> <span class="token operator">-</span> jsx <span class="token operator">-</span> scope <span class="token operator">:</span> off |
package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="token string">"devDependencies"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"eslint"</span> <span class="token operator">:</span> <span class="token string">"^6.8.0"</span> <span class="token punctuation">,</span> <span class="token string">"@typescript-eslint/eslint-plugin"</span> <span class="token operator">:</span> <span class="token string">"^2.17.0"</span> <span class="token punctuation">,</span> <span class="token string">"eslint-config-airbnb-typescript"</span> <span class="token operator">:</span> <span class="token string">"^6.3.1"</span> <span class="token punctuation">,</span> <span class="token string">"eslint-plugin-import"</span> <span class="token operator">:</span> <span class="token string">"^2.20.0"</span> <span class="token punctuation">,</span> <span class="token string">"eslint-plugin-jsx-a11y"</span> <span class="token operator">:</span> <span class="token string">"^6.2.3"</span> <span class="token punctuation">,</span> <span class="token string">"eslint-plugin-react"</span> <span class="token operator">:</span> <span class="token string">"^7.18.0"</span> <span class="token punctuation">,</span> <span class="token string">"eslint-plugin-react-hooks"</span> <span class="token operator">:</span> <span class="token string">"^2.3.0"</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token string">"scripts"</span> <span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"lint"</span> <span class="token operator">:</span> <span class="token string">"eslint . --ext .ts,.tsx"</span> <span class="token punctuation">}</span> |
Install for VSCode
VSCode has a pretty godly plugin to support ESLint. My favorite settings
Automatically run lint when saving
1 2 |
<span class="token string">"eslint.run"</span> <span class="token operator">:</span> <span class="token string">"onSave"</span> |
VSCode will check on JS, JSX, TS, TSX
1 2 3 4 5 6 7 |
<span class="token string">"eslint.validate"</span> <span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"javascript"</span> <span class="token punctuation">,</span> <span class="token string">"javascriptreact"</span> <span class="token punctuation">,</span> <span class="token string">"typescript"</span> <span class="token punctuation">,</span> <span class="token string">"typescriptreact"</span> <span class="token punctuation">]</span> |
Choose a single quote pattern
1 2 3 |
<span class="token string">"javascript.preferences.quoteStyle"</span> <span class="token operator">:</span> <span class="token string">"single"</span> <span class="token punctuation">,</span> <span class="token string">"typescript.preferences.quoteStyle"</span> <span class="token operator">:</span> <span class="token string">"single"</span> <span class="token punctuation">,</span> |
Automatically update file location
1 2 3 |
<span class="token string">"javascript.updateImportsOnFileMove.enabled"</span> <span class="token operator">:</span> <span class="token string">"always"</span> <span class="token punctuation">,</span> <span class="token string">"typescript.updateImportsOnFileMove.enabled"</span> <span class="token operator">:</span> <span class="token string">"always"</span> <span class="token punctuation">,</span> |