# 重新配置 React 專案的 ESLint
## 升級 `react-scripts`
1. 移除 `node-modules/`
1. 執行 `npm install --save --save-exact react-scripts@5.0.0`
1. 執行 `npm i`
## 補安裝缺少的 query-string
執行 `npm i query-string`
## 初始化 ESLint
執行 `eslint --init`
問答中會自幫升級 ESLint(對應到 react-scripts)

## 補安裝 hooks 相關 Lint
執行 `npm i -D eslint-plugin-react-hooks`
並加入至 `plugins`
```diff=
plugins: [
'react',
+ 'react-hooks',
],
```
## 添加 ESLint rules
為了遷就現有風格。
``` js
rules: {
'new-cap': 'off',
'no-unused-vars': 'warn',
'space-before-function-paren': ['error', {
anonymous: 'always',
named: 'never',
asyncArrow: 'always'
}],
'jsx-quotes': ['warn', 'prefer-double'],
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'react/jsx-indent': ['warn', 2, {
checkAttributes: true,
indentLogicalExpressions: true
}],
'react/jsx-indent-props': ['warn', 2],
'react/jsx-closing-bracket-location': ['warn', 'tag-aligned'],
'react/jsx-curly-spacing': ['warn', { when: 'never', children: true }],
'react/jsx-tag-spacing': ['warn', {
closingSlash: 'never',
beforeSelfClosing: 'always',
afterOpening: 'never',
beforeClosing: 'never'
}],
'react/self-closing-comp': 'warn',
'react/jsx-fragments': 'warn',
'react/jsx-equals-spacing': [2, 'never'],
// TODO: 正在遷移至新 ESLint 配置中,待修正完成後應移除以下 warning
'react/prop-types': 'off',
'no-case-declarations': 'off',
'react/jsx-key': 'warn',
'no-array-constructor': 'warn',
'react/jsx-no-duplicate-props': 'warn',
'array-callback-return': 'warn',
'react/no-unescaped-entities': 'warn',
'no-constant-condition': 'warn',
'valid-typeof': 'warn'
}
```
## 修改 IDE 工作區設定
編輯 `.vscode/settings.json`
新增:
```diff
+ "editor.codeActionsOnSave": {
+ "source.fixAll.eslint": true
+ },
```
並移除其他不必要的設定值,以防自動排版衝突:
```diff
- "editor.formatOnSave": true,
- "prettier.eslintIntegration": true,
```
## 執行自動修復
修復排版相關錯誤。
執行 `eslint --fix . --ext .js,.jsx`
## 移除 package.json 的 `eslintConfig`
當存在 `.eslint.rc` 時, `eslintConfig` 是多餘的。
## 🌟 指定 parser
執行 `npm i -D @babel/eslint-parser @babel/preset-react`
在 `.eslintrc` 加入以下:
```diff
+ parser: "@babel/eslint-parser",
parserOptions: {
...,
+ requireConfigFile: false,
+ babelOptions: {
+ presets: ['@babel/preset-react']
+ }
},
```
## 新增 `extends`
React 17 可以省略匯入 `react`,在 extends 加入 `plugin:react/jsx-runtime`。
https://zh-hant.reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html
```diff
extends: [
'plugin:react/recommended',
+ 'plugin:react/jsx-runtime',
'standard'
],
```
## 指定 React 版本
```diff=
+ settings: {
+ react: {
+ version: 'detect'
+ }
+ },
```
## Ref.
https://dev.to/brayanarrieta/integrate-eslint-with-your-react-project-javascript-29p
https://eslint.org/docs/user-guide/configuring/plugins#specifying-parser
https://github.com/facebook/create-react-app/issues/11771