VSCode + TypeScript + React で開発を行うための ESLint + Prettier の環境構築 2021

## はじめに

前提として [VSCode](https://code.visualstudio.com) と [Node.js](https://nodejs.org/ja/) のインストールが済んでいるものとします．
React のプロジェクトを TypeScript 用に作成するだけなら，次のコマンドを実行するだけで完了です．カレントディレクトリに `ts-react-project` という名前でフォルダが新たに作成されます．

```zsh:ターミナル
npx create-react-app ts-react-project --template typescript
```

この状態でも TypeScript + React による開発は十分に可能です．しかし複数人でコードを書く際は，開発効率の維持という観点からソースコードの一貫性も重要になるため，コードの書式を整形・統一するツールを利用することが多いです．ここでは JavaScript/TypeScript の linter（コードの静的解析を行い問題部分をチェックするツール）である ESLint と，フォーマッタ（コードの整形を設定に沿って自動で行うツール）である Prettier を導入して環境構築を行います．
ESLint と Prettier の連携について調べると多くのページがヒットしますが，ややこしかったり，現在は非推奨なやり方で説明しているものもあって非常に悩ましいと思います．そこで VSCode で環境構築する手順について，2021年2月現在で最善と思われるものを備忘録としてまとめてみました．参考になれば幸いです．

## ESLint の導入

### 1. ESLint 本体について
   通常は `yarn add eslint --dev` によってインストールしますが，今回は `create-react-app` でプロジェクトを作成した際に ESLint が導入されています．バージョンの確認は `eslint -v` or `eslint --version` で可能ですが，

```zsh:ターミナル
npm ls eslint
```

とすると，バージョンだけでなく，プロジェクトフォルダ内の `node_modules` に ESLint があることが確認できます．

###2. 拡張機能の追加
VSCode 拡張機能「 [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) 」を追加します．このプラグインによって， VSCode の「設定」から ESLint のセッティングが可能です．

###3. ESLint の設定

   `node_modules/.bin/eslint --init` を実行します（ VSCode のコマンドパレットを開き `ESLint: Create ESLint Configuration` を実行するのと同じ）．次のように入力していくと `.eslintrc.js` と `package.json` が作成されます．
![lintrc-setting.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745597/de2c1caf-d32c-6197-b2c0-e87e55520806.jpeg)

特に気をつけなければならないのは

   - Which framework does your project use?:
     今回は **`React`** を選択（ `Vue` もある）．
   - Does your project use TypeScript?: **Yes**
   - What format do you want your config file to be in?:
     `.json` の形式で設定することもできますが，今回は `.js` の場合を説明します．
   - Would you like to install them now with npm?: **No**

   入力を終えるとプロジェクトフォルダの中に `.eslintrc.js` が作成されるので，以下のようになっているか確認します．

```javascript:.eslintrc.js
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: 12,
    sourceType: "module",
  },
  plugins: ["react", "@typescript-eslint"],
  rules: {},
 };
 ```

   試しに `rules` の部分を

```javascript
{
  rules: {
    quotes: ['error', 'double'],
  }
}
```

   として，ダブルクオーテーションでないとエラーが出るように設定してみましょう．写真のようになれば， ESLint が動いていることが確認できるはずです．
![lint-check.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/745597/f93eb729-698d-121c-0853-8df6a66f646e.jpeg)

   また ESLint の設定は `.eslintrc.js` でなされているので，`package.json` の `eslintConfig` の部分は削除します（残しておいた場合も `.eslintrc.js` の方の設定が優先されます）．

```javascript:package.json
{
  ...,
  "eslintConfig": {  //削除
    "extends": "react-app"
  },
  ...,
}
```

## Prettier の導入

###1. Prettier のインストール
```zsh:ターミナル
yarn add --dev prettier
```

###2. 拡張機能の追加
VSCode の拡張機能「 [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) 」を追加します．

###3. `.prettierrc` の作成・記述

   VSCode のコマンドパレットから `Prettier: Create Configuration File`，又は

```zsh:ターミナル
echo {}> .prettierrc
```
を実行し，Prettier の設定ファイルである `.prettirrc` をプロジェクトフォルダ内に作成します．
   記述の際は Prettier の [Options](https://prettier.io/docs/en/options.html) にて設定可能なオプションが説明されているので参考にします．例：

```javascript:.prettierrc
{
  "printWidth": 100,
  "trailingComma": "es5"
}
```

## ESLint と Prettier の連携

連携させる際に考えるべきは次の二つです．
1. コーディング中は ESLint と Prettier を定期的に実行する．
2. ESLint にもコード整形のルールがあるため，それらを off にして Prettier との競合を防ぐ．

1 についてはユーザー側でいちいち気をつけるのは面倒なので，ファイル保存時に自動で走るように VSCode の設定を行います[^plugin]．2 については `eslint-config-prettier`というパッケージをインストールすることで解決できます．

[^plugin]: 自動化にあたっては ESLint から Prettier を呼び出すためのプラグイン，`eslint-plugin-prettier` もインストールして，ESLint から一括でコードの解析・整形を行う方法がメジャーでした．しかし直接 Prettier を実行するよりも遅かったり，レイヤーの不整合が起こりうるという問題もあるため，現在この方法は推奨されていません（ソース：[Integrating with Linters - Prettier](https://prettier.io/docs/en/integrating-with-linters.html)）．そのためここでは `eslint-plugin-prettier` はインストールせず，ESLint と Prettier を別々で実行するやり方を取ります．

###1. VSCode の設定

`settings.json` に次の内容[^formatonsave]を加えます．

```json:settings.json
{
  "[typescript]": {
  "editor.defaultFormatter": "esbenp.prettier-vscode" // formatter: prettier
  },
  "editor.formatOnSave": true, // format by prettier when saving a file
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true // execute ESLint when saving a file
  }
}
```

[^formatonsave]: ここでは Prettier を TypeScript 入力時のコードフォーマッタとして指定し， `editor.formatOnSave` によってファイル保存時に実行されるように設定します．一方，ESLint をファイル保存時に実行する場合は `editor.formatOnSave` ではなく `editor.codeActionsOnSave` で設定することが推奨されています（引用は VSCode ESLint Extention の `eslint.format.enable` より）．
       > Although you can also use the formatter on save using the setting `editor.formatOnSave` it is recommended to use the `editor.codeActionsOnSave` feature since it allows for better configurability.

###2. `eslint-config-prettier` のインストール・適用

```zsh:ターミナル
yarn add --dev eslint-config-prettier
```

   を実行します．インストールの完了後，`.eslintrc.js` の `"extends"` を以下のように書き加えて保存します．

```javascript:.eslintrc.js
{
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended", //no-unused-varsのエラーを非表示にするために追加
    "prettier", // configを参照するために追加
  ],
}
```

###3. 動作確認
   `app.tsx` に適当にスペースを加えたり，セミコロンを抜いたりしてフォーマットを乱してみてください．保存した際に自動整形されれば ESLint と Prettier が動いていることが確認できます．

## 参考資料

日本語で書かれた各種 Web サイトだけでなく公式のドキュメントも参照する方が良い（サイトによって情報が曖昧だったり，そもそも情報の移り変わりが激しいため，かつて取られた方法が非推奨になっているケースがあるから）です．調べた中で参考になると感じた記事を示します．

- [Prettier 入門 ～ ESLint との違いを理解して併用する～](https://qiita.com/soarflat/items/06377f3b96964964a65d)
  Prettier と ESLint の違い，併用する意義について分かりやすくまとめられています．

- [ESLint の Plugin と Extend の違い](https://blog.ojisan.io/eslint-plugin-and-extend)
- [Prettier と ESLint の組み合わせの公式推奨が変わり plugin が不要になった](https://blog.ojisan.io/prettier-eslint-cli)
ESLint の設定や Prettier との連携について悩んでいた際，非常に参考になりました．

- [TypeScript のプロジェクトに ESLint と Prettier を導入する方法（+VSCode での設定）](https://qiita.com/yuma-ito-bd/items/cca7490fd7e300bbf169)
今回 VSCode で環境構築を行う際に参考にしました．

- [ESLint: Getting Started with ESLint](https://eslint.org/docs/user-guide/getting-started)
- [Prettier: Install](https://prettier.io/docs/en/install.html)
公式のドキュメントです．