ESLint
===
## Install ESLint
```clike
npm install eslint eslint-plugin-react
```
## Initilize ESLint
```clike
npx eslint --init
```
ESLint will ask you some questions to set up some basic settings:
```bash
√ How would you like to use ESLint? · style
√ What type of modules does your project use? · esm
√ Which framework does your project use? · react
√ Does your project use TypeScript? · No / Yes
√ Where does your code run? · browser
√ How would you like to define a style for your project? · prompt
√ What format do you want your config file to be in? · JSON
√ What style of indentation do you use? · 4
√ What quotes do you use for strings? · single
√ What line endings do you use? · windows
√ Do you require semicolons? · No / Yes
```
After initialization, ESLint will create a config file `.eslintrc` or `.eslintrc.*`.
According to our selection, ESLint creates a file `.eslintrc.json`:
```json
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"react"
],
"rules": {
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"windows"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
}
}
```
## Set up ESLint Config
According to the [recommandation](https://github.com/yannickcr/eslint-plugin-react#configuration) by `
eslint-plugin-react `, let's append the following code to `.eslintrc.json`
```json
"settings": {
"react": {
"createClass": "createReactClass", // Regex for Component Factory to use,
// default to "createReactClass"
"pragma": "React", // Pragma to use, default to "React"
"fragment": "Fragment", // Fragment to use (may be a property of <pragma>), default to "Fragment"
"version": "detect", // React version. "detect" automatically picks the version you have installed.
// You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
// default to latest and warns if missing
// It will default to "detect" in the future
"flowVersion": "0.53" // Flow version
},
"propWrapperFunctions": [
// The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.
"forbidExtraProps",
{"property": "freeze", "object": "Object"},
{"property": "myFavoriteWrapper"}
],
"linkComponents": [
// Components used as alternatives to <a> for linking, eg. <Link to={ url } />
"Hyperlink",
{"name": "Link", "linkAttribute": "to"}
]
```
To Change the number of spaces in indent, we can replace the value of `"indent"` by:
```json
"indent": [
"error",
2
],
```
Now our `.eslintrc.json` looks like:
```json
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended"
],
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"react"
],
"rules": {
"indent": [
"error",
2
],
"linebreak-style": [
"error",
"windows"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
},
"settings": {
"react": {
"createClass": "createReactClass", // Regex for Component Factory to use,
// default to "createReactClass"
"pragma": "React", // Pragma to use, default to "React"
"fragment": "Fragment", // Fragment to use (may be a property of <pragma>), default to "Fragment"
"version": "detect", // React version. "detect" automatically picks the version you have installed.
// You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
// default to latest and warns if missing
// It will default to "detect" in the future
"flowVersion": "0.53" // Flow version
},
"propWrapperFunctions": [
// The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.
"forbidExtraProps",
{"property": "freeze", "object": "Object"},
{"property": "myFavoriteWrapper"}
],
"linkComponents": [
// Components used as alternatives to <a> for linking, eg. <Link to={ url } />
"Hyperlink",
{"name": "Link", "linkAttribute": "to"}
]
}
}
```
## Run ESLint
```npx
npx eslint src/
```
Message:
```clike
C:\Users\lab\react-hello-world2\src\App.js
2:40 error 'Link' is defined but never used no-unused-vars
8:20 error Missing semicolon semi
14:1 error Expected indentation of 8 spaces but found 10 indent
15:1 error Expected indentation of 10 spaces but found 12 indent
16:1 error Expected indentation of 8 spaces but found 10 indent
✖ 5 problems (5 errors, 0 warnings)
4 errors and 0 warnings potentially fixable with the `--fix` option.
```
Check the file `C:\Users\lab\react-hello-world2\src\App.js`:
```javascript=
import React, { Component } from 'react';
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom';
import HelloWorld from './helloWorld';
class App extends Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<BrowserRouter>
<Switch>
<Route exact path='/' component={HelloWorld} />
</Switch>
</BrowserRouter>
);
}
}
export default App;
```
## Fix errors
### Fix Problems Automatically
```clike
npx eslint src/ --fix
```
Message:
```clike
C:\Users\lab\react-hello-world2\src\App.js
2:40 error 'Link' is defined but never used no-unused-vars
✖ 1 problem (1 error, 0 warnings)
```
Check again the file `C:\Users\lab\react-hello-world2\src\App.js`:
```javascript=
import React, { Component } from 'react';
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom';
import HelloWorld from './helloWorld';
class App extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
return (
<BrowserRouter>
<Switch>
<Route exact path='/' component={HelloWorld} />
</Switch>
</BrowserRouter>
);
}
}
export default App;
```
We can find that there is still a problem, let's manually fix it.
### Fix Problem Manually
Remove `, Link` in the line 2 in `C:\Users\lab\react-hello-world2\src\App.js`.
Run ESLint again, we can find that there is no ouput message, which means there is no errors.