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.