React18がリリースされたので、開発環境をゼロから構築してみる。【終編】


[前編](https://qiita.com/kztmk_media_pep/items/a00631a5e1bb1cd13597)
[中編](https://qiita.com/kztmk_media_pep/items/1a5da1e989a0da5bc215)
[後編](https://qiita.com/kztmk_media_pep/items/a9cc5186cdaa3771e2ab)

からの続きです。

## eslintの導入
eslintは、書いたコードが決められたルールに則っているかをチェックし指摘・修正してくれる優れものです。

では、そのルールは誰が決めるのでしょうか？


それは、私よりも経験豊富で大規模プロジェクトを経験してきた先人達が、いろいろなルールを提案してくれたものがあります。

例えば、民泊で有名な「airbnb」やコミュニティが提案してくれている「React向け」などがあります。


それでは、eslintをインストールします。


### eslintのインストール

ターミナルに以下のコマンドを入力し、エンターキーを押すと質問が始まるので、カーソルキー、エンターキーにて回答していきます。

```shell
npx eslint --init
Need to install the following packages:
  eslint
Ok to proceed? (y) 
You can also run this command directly using 'npm init @eslint/config'.
Need to install the following packages:
  @eslint/create-config
Ok to proceed? (y) 
✔ How would you like to use ESLint? · problems
✔ 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
✔ What format do you want your config file to be in? · JavaScript
Local ESLint installation not found.
The config that you've selected requires the following dependencies:

eslint-plugin-react@latest @typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest eslint@latest
✔ Would you like to install them now with npm? · No / Yes
Installing eslint-plugin-react@latest, @typescript-eslint/eslint-plugin@latest, @typescript-eslint/parser@latest, eslint@latest

added 134 packages, and audited 1061 packages in 12s

122 packages are looking for funding
  run `npm fund` for details

10 high severity vulnerabilities

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.
A config file was generated, but the config file itself may not follow your linting rules.
Successfully created .eslintrc.js file in /Users/yaruo-react-redux/zero-start-react18
```

これで、eslintがインストールされ設定ファイルである「.eslintrc.js」も作成されます。

最新の「create-react-app」で作成したプロジェクトの場合は、eslint関連は以下のようになっています。

```shell
 npm ls eslint
r18v501@0.1.0 /Users/yaruo-react-redux/r18v501
└─┬ react-scripts@5.0.1
  ├─┬ eslint-config-react-app@7.0.1
  │ ├─┬ @babel/eslint-parser@7.17.0
  │ │ └── eslint@8.13.0 deduped
  │ ├─┬ @typescript-eslint/eslint-plugin@5.19.0
  │ │ ├─┬ @typescript-eslint/type-utils@5.19.0
  │ │ │ └── eslint@8.13.0 deduped
  │ │ ├─┬ @typescript-eslint/utils@5.19.0
  │ │ │ └── eslint@8.13.0 deduped
  │ │ └── eslint@8.13.0 deduped
  │ ├─┬ @typescript-eslint/parser@5.19.0
  │ │ └── eslint@8.13.0 deduped
  │ ├─┬ eslint-plugin-flowtype@8.0.3
  │ │ └── eslint@8.13.0 deduped
  │ ├─┬ eslint-plugin-import@2.26.0
  │ │ └── eslint@8.13.0 deduped
  │ ├─┬ eslint-plugin-jest@25.7.0
  │ │ ├─┬ @typescript-eslint/experimental-utils@5.19.0
  │ │ │ └── eslint@8.13.0 deduped
  │ │ └── eslint@8.13.0 deduped
  │ ├─┬ eslint-plugin-jsx-a11y@6.5.1
  │ │ └── eslint@8.13.0 deduped
  │ ├─┬ eslint-plugin-react-hooks@4.4.0
  │ │ └── eslint@8.13.0 deduped
  │ ├─┬ eslint-plugin-react@7.29.4
  │ │ └── eslint@8.13.0 deduped
  │ ├─┬ eslint-plugin-testing-library@5.3.1
  │ │ └── eslint@8.13.0 deduped
  │ └── eslint@8.13.0 deduped
  ├─┬ eslint-webpack-plugin@3.1.1
  │ └── eslint@8.13.0 deduped
  ├─┬ eslint@8.13.0
  │ └─┬ eslint-utils@3.0.0
  │   └── eslint@8.13.0 deduped
  └─┬ react-dev-utils@12.0.1
    └─┬ fork-ts-checker-webpack-plugin@6.5.1
      └── eslint@8.13.0 deduped
```

こちらの現在のeslint関連は、以下の通りです。
```shell
npm ls eslint
yaruo-start-template-react18@1.0.0 /Users/yaruo-react-redux/zero-start-react18
├─┬ @typescript-eslint/eslint-plugin@5.19.0
│ ├─┬ @typescript-eslint/type-utils@5.19.0
│ │ └── eslint@8.13.0 deduped
│ ├─┬ @typescript-eslint/utils@5.19.0
│ │ └── eslint@8.13.0 deduped
│ └── eslint@8.13.0 deduped
├─┬ @typescript-eslint/parser@5.19.0
│ └── eslint@8.13.0 deduped
├─┬ eslint-plugin-react@7.29.4
│ └── eslint@8.13.0 deduped
└─┬ eslint@8.13.0
  └─┬ eslint-utils@3.0.0
    └── eslint@8.13.0 deduped
```

ここに、「eslint-config-react-app」をインストールすれば「create-react-app」で作成したものと同じものがインストールされます。「create-react-app」と同じ状態にしたいのであれば、以下のコマンドでインストールしてください。

```shell
npm install -D eslint-config-react-app
```

### eslintのルールの確認

以下のコマンドを実行すると、現在のルールが「current_rules.txt」に書き出されます。


```shell
npx eslint --print-config .eslintrc.js > current_rules.txt
```

現在のルール
```json
{
  "env": {
    "browser": true,
    "es2021": true
  },
  "globals": {},
  "parser": "/Users/kazuyainaba/Documents/Devs_kz/Project_技術書展202012/yaruo_react_sample/yaruo-start-template-react18/node_modules/@typescript-eslint/parser/dist/index.js",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": "latest",
    "sourceType": "module"
  },
  "plugins": [
    "@typescript-eslint",
    "react"
  ],
  "rules": {
    "@typescript-eslint/adjacent-overload-signatures": [
      "error"
    ],
    "@typescript-eslint/ban-ts-comment": [
      "error"
    ],
    "@typescript-eslint/ban-types": [
      "error"
    ],
    "no-array-constructor": [
      "off"
    ],
    "@typescript-eslint/no-array-constructor": [
      "error"
    ],
    "no-empty-function": [
      "off"
    ],
    "@typescript-eslint/no-empty-function": [
      "error"
    ],
・
・
中略
・
・
      "error"
    ],
    "@typescript-eslint/no-non-null-assertion": [
      "warn"
    ],
    "@typescript-eslint/no-this-alias": [
      "error"
    ],
    "@typescript-eslint/no-unnecessary-type-constraint": [
      "error"
    ],
    "no-unused-vars": [
      "off"
    ],
    "@typescript-eslint/no-unused-vars": [
      "warn"
    ],
    "@typescript-eslint/no-var-requires": [
      "error"
    ],

      "error"
    ],
 
    "no-with": [
      "error"
    ],
    "require-yield": [
      "error"
    ],
    "use-isnan": [
      "error"
    ],
    "valid-typeof": [
      "error"
    ]
  },
  "settings": {},
  "ignorePatterns": []
}
```

現時点での「.eslintrc.js」
```javascript
module.exports = {
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/recommended"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "@typescript-eslint"
    ],
    "rules": {
    }
}
```

これに、「airbnb」のルールを追加します。eslintのルールは、「eslint-config-XXX」のような命名ルールで作成されています。「airbnb」のルールは、「eslint-config-airbnb」となります。

```shell
npm install -D eslint-config-airbnb
```

eslint設定ファイル「.eslintrc.js」にインストールした「airbnb」のルールを追加します。

```javascript
module.exports = {
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/recommended",
        "airbnb"
    ],
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": "latest",
        "sourceType": "module"
    },
    "plugins": [
        "react",
        "@typescript-eslint"
    ],
    "rules": {
    }
}
```

diffで、「eslint-config-airbnb」追加前と追加後を比較するとルールが格段に増えているのが分かります。

![eslint01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4849/d56e4ccd-b663-6528-21f8-fb5fe9ec6d4b.png)


設定ファイル「.eslintrc.js」のextendsに追加されているものがルールを順番に上書きします。

これらのルールを自前で変更したい場合には、設定ファイル「.eslintrc.js」のrulesに追加すると最後にルールを上書きしてくれます。

例えば、現時点ではjsxのファイル拡張子は「.jsx」以外はエラーとなりますが、「.tsx」を追加したいので変更します。

現時点
```json
    "react/jsx-filename-extension": [
      "error",
      {
        "extensions": [
          ".jsx"
        ]
      }
    ],
```

rulesに追加
```json
"rules": {
    "react/jsx-filename-extension": [
      "error",
      {
        "extensions": [
          ".jsx",
          ".tsx"
        ]
      }
    ],
}
```

また、eslintの検査対象から除外したい場合には、「.eslintignore」ファイルを作成し、除外したいファイル・フォルダを書き込みます。

自分自身「.eslintrc.js」を除外する場合には、[.eslintignore]を編集します。
[.eslintignore]
```
.eslintrc.js
```

### コードフォーマッター「prettier」のインストール

コードをフォーマットしてくれる「prettier」をインストールします。eslintもコードフォーマットの機能がありますが、フォーマットは「prettier」へ任せます。eslintへprettierのルールを追加するため「eslint-config-prettier」もインストールします。

```shell
npm install -D prettier eslint-config-prettier
```

prettierでフォーマットする設定ファイルを作成します。prettier設定ファイル「.prettierrc」にオプションを指定します。

[prettierのオプション](https://prettier.io/docs/en/options.html)から自分の好みでオプションを追加してください。

以下は、私の好みです。

[.prettierrc]
```json
{
  "singleQuote": true,
  "jsxSingleQuote": true
}
```

eslint設定ファイル「.eslintrc.js」へprettierのルールを追加します。

```javascript
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:@typescript-eslint/recommended",
        "airbnb",
        "prettier"
    ],
```

### eslintとprettierの衝突

eslintもフォーマットの機能があるため、eslintが指摘・修正したものをprettierが指摘・修正と無限ループにならないかを確認します。

```shell
npx eslint-config-prettier 'src/**/*.{js, jsx, ts, tsx}'
No rules that are unnecessary or conflict with Prettier were found.
```

### package.jsonへscriptの追加

コマンドでeslintのチェック・修正、prettireでコードフォーマットができるように「package.json」へscriptを追加します。

```json
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --config webpack.prod.js",
    "build:dev": "webpack --config webpack.config.dev.js",
    "build:prod": "webpack --config webpack.config.prod.js",
    "start": "webpack serve --config webpack.config.dev.js",
    "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'",
    "fix": "npm run format && npm run lint:fix",
    "format": "prettier --write 'src/**/*.{js,jsx,ts,tsx}'",
    "lint:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx}'"
  },
```

以上で、ゼロからReact(TypeScript)での開発環境が完成しました。


eslintで私のルール入りのものが、以下から取得できます。

```shell
git clone -b 08_eslint-install https://github.com/yaruo-react-redux/yaruo-start-template-react18.git
```


ここをスタートとして、React、Redux、Redux-toolkitの解説をしたものがこちらになります。



https://techbookfest.org/product/4616093891035136?productVariantID=4899714673672192