ViteでReact(TypeScript)プロジェクトを作成し、ESLint及びPrettierを導入するまで

# 概要

開発環境はWindows + VSCodeです。
下記の手順で進めます。

1. ViteでReact(TypeScript)プロジェクトを作成
1. sampleソースの実行
1. ESLintのインストール
1. Prettierのインストール
1. 各種設定
1. 静的解析, 自動修正, 自動整形の実行
1. VSCodeとの連携

各ツールの詳細に関しては、公式サイトをご覧ください。
後述する各項目では関連する公式サイトのリンクを記述します。

- [Vite : https://ja.vitejs.dev/](https://ja.vitejs.dev/)
- [React : https://ja.reactjs.org/](https://ja.reactjs.org/)
- [TypeScript : https://www.typescriptlang.org/](https://www.typescriptlang.org/)
- [ESLint : https://eslint.org/](https://eslint.org/)
- [Prettier : https://prettier.io/](https://prettier.io/)

## ViteでReact(TypeScript)プロジェクトを作成

[Vite : 最初の Vite プロジェクトを生成する](https://ja.vitejs.dev/guide/#%E6%9C%80%E5%88%9D%E3%81%AE-vite-%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%82%92%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B)

```powershell
> yarn create vite
yarn create v1.22.17
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Installed "create-vite@2.9.4" with binaries:
      - create-vite
      - cva
√ Project name: ... react-ts-sample
√ Select a framework: » react
√ Select a variant: » react-ts

Scaffolding project in ...\react-ts-sample...

Done. Now run:      

  cd react-ts-sample
  yarn
  yarn dev

Done in 35.84s.
```

## sampleソースの実行

```powershell
> cd react-ts-sample
> yarn
yarn install v1.22.17
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 5.75s.
```

この時点でのディレクトリ構成。

```
.react-ts-sample
├── node_modules
├── src
│   ├── App.css
│   ├── App.tsx
│   ├── favicon.svg
│   ├── index.css
│   ├── logo.svg
│   ├── main.tsx
│   └── vite-env.d.ts
├── .gitignore
├── index.html
├── package.json
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── yarn.lock
```

sampleソースの実行

```powershell
> yarn dev
yarn run v1.22.17
$ vite

  vite v2.9.9 dev server running at:

  > Local: http://localhost:3000/
  > Network: use `--host` to expose

  ready in 358ms.
```

[http://localhost:3000/](http://localhost:3000/)へアクセスし、下記画面が出ることを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58725/d07127ad-c774-74d7-9bab-34e83a4374bb.png)

## ESLintのインストール

[ESLint : Installation and Usage](https://eslint.org/docs/user-guide/getting-started)

```powershell
> yarn add eslint --dev
yarn add v1.22.17
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 68 new dependencies.
info Direct dependencies
└─ eslint@8.16.0
info All dependencies
├─ @eslint/eslintrc@1.3.0
...
└─ word-wrap@1.2.3
Done in 2.29s.
```

### .eslintrc.jsonの作成

各選択はプロジェクト毎に任意のものを選択してください。
今回選択したものは画像付きで後述します。

```powershell
> yarn create @eslint/config
yarn create v1.22.17
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Installed "@eslint/create-config@0.2.0" with binaries:
      - create-config
√ 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? · guide
√ Which style guide do you want to follow? · airbnb      
√ What format do you want your config file to be in? · JSON
Checking peerDependencies of eslint-config-airbnb@latest   
The config that you've selected requires the following dependencies:

eslint-plugin-react@^7.28.0 @typescript-eslint/eslint-plugin@latest eslint-config-airbnb@latest eslint@^7.32.0 || ^8.2.0 eslint-plugin-import@^2.25.3 eslint-plugin-jsx-a11y@^6.5.1 eslint-plugin-react-hooks@^4.3.0 @typescript-eslint/parser@latest
√ Would you like to install them now? · No / Yes
√ Which package manager do you want to use? · yarn
Installing eslint-plugin-react@^7.28.0, @typescript-eslint/eslint-plugin@latest, eslint-config-airbnb@latest, eslint@^7.32.0 || ^8.2.0, eslint-plugin-import@^2.25.3, eslint-plugin-jsx-a11y@^6.5.1, eslint-plugin-react-hooks@^4.3.0, @typescript-eslint/parser@latest
yarn add v1.22.17
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 89 new dependencies.
info Direct dependencies
├─ @typescript-eslint/eslint-plugin@5.26.0
...
└─ eslint@8.16.0
info All dependencies
├─ @babel/runtime-corejs3@7.18.0
...
└─ yallist@4.0.0
Done in 16.27s.
Successfully created .eslintrc.json file in ...\react-ts-sample
Done in 437.44s.
```

#### ESLintをどのように使うか？

- To check syntax only : 構文チェックのみ
- To check syntax and find problems : 構文チェック, 問題の発見
- [選択] To check syntax, find problems, and enforce code style : 構文チェック, 問題の発見, コードスタイルの適用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58725/572c61ca-6d19-5ae9-e44c-dbd4d6e4dd49.png)

#### プロジェクトにどのタイプのモジュールを使うか？

- [選択] JavaScript modules (import/export)
- CommonJS (require/exports)
- None of these

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58725/4e462696-e8f5-738a-5257-1ac816055cd7.png)

#### プロジェクトに使うフレームワークはどれか？

- [選択] React
- Vue.js
- None of these

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58725/49db91ea-a8c8-6305-7712-b742d12d7283.png)

#### プロジェクトにTypeScriptを使うか？

- No
- [選択] Yes

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58725/74b40a2a-7feb-8dde-6f7e-8c9f475a398b.png)

#### コードを実行する場所は？

- [選択] Browser
- Node

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58725/95aa707a-391f-c95b-9ddd-b1dca5238d7a.png)

#### プロジェクトのスタイルをどのように定めるか？

- [選択] Use a popular style guide : 一般的なスタイルガイドを使用
- Answer questions about your style : 自分のスタイルに関する質問に答える

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58725/02504d03-1ee1-bdc0-aa0f-d1587648589b.png)

#### どのスタイルガイドに従うか？

各選択肢に関しては、下記サイトが参考になりました。
[Airbnb vs Standard – ESLint のスタイルは何を選ぶべきか？](https://delicateprogrammer.com/airbnb-vs-standard/)

- [選択] Airbnb: https://github.com/airbnb/javascript
- Standard: https://github.com/standard/standard
- Google: https://github.com/google/eslint-config-google
- XO: https://github.com/xojs/eslint-config-xo

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58725/06f1d1aa-a4e2-4c03-a9ea-c3643f846d3d.png)

#### ESLint設定ファイルはどの形式にするか？

- JavaScript
- YAML
- [選択] JSON

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58725/4003a294-64ab-d5bb-2596-a641c70901fd.png)

#### これらのパッケージを今インストールするか？

- No
- [選択] Yes

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58725/6175cbb4-0884-2d82-a240-73e7e8ec0e6a.png)

#### パッケージマネージャはどれを使うか？

- npm
- [選択] yarn
- pnpm

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58725/b4a4a621-7402-90cb-34b9-927a8c05c11e.png)

### eslint-config-airbnb-typescriptのインストール

スタイルガイドにAirbnbを選択したため、TypeScriptと対応する[eslint-config-airbnb-typescript](https://www.npmjs.com/package/eslint-config-airbnb-typescript)をインストールします。

```powershell
> yarn add --dev eslint-config-airbnb-typescript
yarn add v1.22.17
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ eslint-config-airbnb-typescript@17.0.0
info All dependencies
└─ eslint-config-airbnb-typescript@17.0.0
Done in 1.99s.
```

## Prettierのインストール

```
> yarn add --dev prettier
yarn add v1.22.17
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ prettier@2.6.2
info All dependencies
└─ prettier@2.6.2
Done in 2.41s.
```

Prettierと競合するESLintのルールを無効化するために[prettier/eslint-config-prettier](https://github.com/prettier/eslint-config-prettier)も合わせてインストールします。

```
> yarn --dev add eslint-config-prettier      
yarn add v1.22.17
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
info Direct dependencies
└─ eslint-config-prettier@8.5.0
info All dependencies
└─ eslint-config-prettier@8.5.0
Done in 1.90s.
```

### .prettierrc.jsonの作成

設定可能なオプションは[Prettier : Options](https://prettier.io/docs/en/options.html)で確認できます。
後述する各種設定で追記するため、ここでは空ファイルを作成しておきます。

## 各種設定

### package.json

package.jsonはscripts部分だけ抜粋します。
このコマンドはWindows powershellからの実行コマンドであることに注意してください。

```json:package.json
{
  ...
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"",
    "format": "eslint --cache --fix \"src/**/*.{js,jsx,ts,tsx}\" && prettier --write \"src/**/*.{js,jsx,ts,tsx}\""
  },
  ...
}
```

### .eslintrc.json

```json:.eslintrc.json
{
  "env": {
    "browser": true,
    "es2021": true
  },
  "extends": [
    "airbnb",
    "airbnb-typescript",
    "airbnb/hooks",
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking",
    "prettier"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": "latest",
    "sourceType": "module",
    "project": ["./tsconfig.json"]
  },
  "plugins": ["react", "@typescript-eslint"],
  "ignorePatterns": ["build"],
  "rules": {
    "@typescript-eslint/no-use-before-define": ["error"],
    "react/function-component-definition": [
      2,
      {
        "namedComponents": "arrow-function",
        "unnamedComponents": "arrow-function"
      }
    ],
    "react/react-in-jsx-scope": "off",
    "react/prop-types": "off"
  },
  "settings": {
  }
}

``` 

主に下記の点を変更しています。

- extends
  - airbnb-typescript
  - airbnb/hooks
  - plugin:@typescript-eslint/recommended
  - plugin:@typescript-eslint/recommended-requiring-type-checking
  - prettier
- ignorePatterns
  - build
- rules
  - @typescript-eslint/no-use-before-define
    - ["error"]
  - react/function-component-definition
    - [2, {"namedComponents": "arrow-function", "unnamedComponents": "arrow-function"}]
  - react/react-in-jsx-scope : off
  - react/prop-types : off

その他の設定方法は[Configuring ESLint](https://eslint.org/docs/user-guide/configuring/)をご覧ください。

### .prettierrc.json

```json:.prettierrc.json
{
  "singleQuote": true,
  "semi": true,
  "tabWidth": 2,
  "useTabs": false
}
```

- singleQuote: 「true」でダブルに代わりシングルクオーテーションを使う
- semi: 「true」で行末にセミコロンを追加
- tabWidth: 「2」でtabのスペース数が2
- useTabs: 「false」でスペースをtabに代えない

その他の設定方法は[Prettier : Configuration File](https://prettier.io/docs/en/configuration.html)をご覧ください。

### .eslintignore

ESLintから特定のフォルダやファイルを無視したい場合は下記ファイルに追記します。

```.eslintignore
**/node_modules/
``` 

### 最終的なディレクトリ構成

```
.react-ts-sample
├── node_modules
├── src
├── .eslintrc.json
├── .prettierrc.json
├── .gitignore
├── index.html
├── package.json
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── yarn.lock
```

## 静的解析, 自動修正, 自動整形の実行

ESLintによる静的解析は下記コマンドで実行します。

```powershell
yarn lint
```

ESLint及びPrettierによる自動修正と自動整形は下記コマンドで実行します。
自動修正が行えない場合、エラーが表示されますので、その部分は手動で修正してください。

```powershell
yarn format
```

## VSCodeとの連携

最後にVSCodeの拡張機能であるESLintとPrettierを使用し、
ファイル保存時にフォーマットが自動で行われるような設定を行います。

まず、VSCodeの拡張機能に下記をそれぞれインストールします。

- [Microsoft/vscode-eslint](https://github.com/Microsoft/vscode-eslint)
- [prettier/prettier-vscode](https://github.com/prettier/prettier-vscode)

続いて、VSCodeの設定画面を開き、setting.jsonへ下記を追記します。

```json:setting.json
  ...,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
```

- editor.defaultFormatter: 「esbenp.prettier-vscode」でデフォルトフォーマットにprettierを指定
- editor.formatOnSave: 「true」で保存のタイミングでフォーマットを行う
- editor.codeActionsOnSave: 「{source.fixAll.eslint : true}」でESLintに対応しているファイルは保存時にESLintによるフォーマットを行う

その他の設定方法は[VSCode : User and Workspace Settings](https://code.visualstudio.com/docs/getstarted/settings)をご覧ください。

## あとがき

Reactを触る必要が出てきたので、備忘録がてら環境構築の手順をまとめました。
各ツールの進化が早いので、この設定方法もそのうち使えなくなるとは思いますが、どなたかの助けになれば幸いです。