🌀

Viteで作成したReact(TypeScript)プロジェクトにEsLintとPrettierを導入する(2022/02)

2022/02/04に公開
2

2022年02月04日 Windows11での情報です。

今回は、Viteで作成したReact(TypeScript)プロジェクトにEsLintとPrettierを導入していきます。
いろいろな記事がありましたが、何をインストールして、どう設定すればいいのか?
かなり混乱したので、記事にまとめておきます。

環境

  • vite: v2.7.2
  • node: v16.13.2
  • react: v17.0.2
  • typescript: v4.4.4

Reactプロジェクト作成

まずはReact(TypeScript)新規プロジェクトの作成からです。
既存のプロジェクトにEsLintを導入するとエラーで真っ赤になって心が折れちゃうので、新規プロジェクトにEsLintを導入します。
Viteで作成しています。
(create-react-appで作成している場合は導入方法が違うのかもしれません。)

Viteでプロジェクトを作成するコマンドです。
npm v7 以上は「npm init vite」コマンドでオプション指定する際はダブルダッシュ(--)が必要です。
※ダブルダッシュ(--)はオプションの解析を終了させる記号です。
「code .」でVsCodeでプロジェクトが起動します。

npm init vite mylint-app -- --template react-ts
cd mylint-app
npm init
code .

VsCodeの設定

VsCodeの拡張機能EsLintとPrettierをインストールしている場合は、動作確認のため一旦無効にしておきます。

EsLintの導入

まずはEslintの導入から始めます。
EsLintとは、静的解析ツールで、構文エラーやコーディング規約に外れたコードをエラー表示してくれます。

1. eslint のインストール

まずはeslintをインストールします。

npm install eslint --save-dev

2. eslint の初期化

2022/05/17 コマンドが変わりました。

(旧)
npx eslint --init
(新)
npm init @eslint/config

対話式で設定が行われます。

● ESLintをどのように使いますか?
? How would you like to use ESLint? (Use arrow keys)
  To check syntax only
  To check syntax and find problems
❯ To check syntax, find problems, and enforce code style

To check syntax, find problems, and enforce code style
(構文の確認、問題の発見、コードスタイルの強制) を選択

● プロジェクトではどのタイプのモジュールを使っていますか?
? What type of modules does your project use? (Use arrow keys)
❯ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

tsconfig.jsonのmoduleを確認する
「EsNext」が指定されているので、None of these を選択
2022/05/17 追記
ES2015のimport/exportを使うので「JavaScript modules (import/export)」を選択するようです。

● どのフレームワークを使いますか?
? Which framework does your project use? ...
❯ React
  Vue.js
  None of these

Reactを選択

● プロジェクトでTypeScriptを使っていますか?
? Does your project use TypeScript? » No / Yes

Yes を選択

● コードはどこで実行されますか?
Where does your code run? ...  (Press <space> to select, <a> to toggle all, <i> to invert selection)
√ Browser
  Node

フロントエンドなのでBrowserを選択
(aキーをクリックすると両方選択できる。)

● プロジェクトのスタイルをどのように定義しますか?
? How would you like to define a style for your project? (Use arrow keys)
❯ Use a popular style guide
  Answer questions about your style
  Inspect your JavaScript file(s)

Use a popular style guide(人気のあるスタイルガイドを使う) を選択

● どのスタイルガイドに従いますか?
? Which style guide do you want to follow? (Use arrow keys)
❯ Airbnb: https://github.com/airbnb/javascript
  Standard: https://github.com/standard/standard
  Google: https://github.com/google/eslint-config-google

Airbnbを選択しました。
Airbnbが最も人気があるようです。

Airbnb JavaScript スタイルガイド
https://mitsuruog.github.io/javascript-style-guide/

それぞれの比較表
https://zenn.dev/tapioca/articles/5685d794f6452b

● 設定ファイルをどのフォーマットにしますか?
? What format do you want your config file to be in? (Use arrow keys)
  JavaScript
❯ YAML
  JSON

YAMLを選択

● npmで今すぐインストールしますか?
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 with npm? » No / Yes    

関連パッケージをnpmでインストールするかどうか
yesを選択

3. airbnbスタイルのTypeScript用の共有設定をインストール

airbnbスタイルのTypeScript用の共有設定をインストールします。

npm install eslint-config-airbnb-typescript --save-dev

4.「package.json」ファイルの確認

package.jsonの状態です。

package.json
"devDependencies": {
    ・・・中略・・・
    "eslint": "^8.8.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-airbnb-typescript": "^16.1.0",
    "eslint-plugin-import": "^2.25.4",
    "eslint-plugin-jsx-a11y": "^6.5.1",
    "eslint-plugin-react": "^7.28.0",
    "eslint-plugin-react-hooks": "^4.3.0",

npx eslint --initで以下のプラグインもインストールされますが、今回は使用しません。
eslint-plugin-import
eslint-plugin-jsx-a11y

eslint-plugin-react-hooksは、React Hooksを使用するときに使いそうなので、導入しておくことにします。

5.「.eslintrc.yml」ファイルの設定を修正

eslintの設定ファイル「.eslintrc.yml」ができています。
変更前の状態です。

.eslintrc.yml
env:
  browser: true
  es2021: true
parser: '@typescript-eslint/parser'
parserOptions:
  ecmaFeatures:
    jsx: true
  ecmaVersion: latest
plugins:
  - react
  - '@typescript-eslint'
extends:
  - plugin:react/recommended
  - airbnb
rules: {}

数か所を変更します。

.eslintrc.yml
env:
  browser: true
  es2021: true
parser: '@typescript-eslint/parser'
parserOptions:
  ecmaFeatures:
    jsx: true
  ecmaVersion: latest
+  project: ./tsconfig.json    
plugins:
  - react
+  - react-hooks
  - '@typescript-eslint'
extends:
  - plugin:react/recommended
+  - plugin:react-hooks/recommended
  - airbnb
+  - airbnb-typescript 
rules: 
+  react-hooks/rules-of-hooks: error
+  react-hooks/exhaustive-deps: warn
修正1:parserOptions の project に 「./tsconfig.json」を指定する

EsLintでTypeScriptの型チェックを行う際に、内部でTypeScriptのコンパイラが使用されるため、parserOptions.projectに 、tsconfig.json ファイル(TypeScriptコンパイル設定ファイル)を指定します。

修正2:pluginsに「react-hooks」を指定する

plugins に、ReactHooksでコードを書く際にチェックをしてくれるプラグイン「eslint-plugin-react-hooks」を追加しておきます。
「eslint-plugin-」部分は省略できます。

修正3:extendsに「plugin:react-hooks/recommended」、「airbnb-typescript」を指定する

plugins はルールを追加する項目です。
pluginsにルールを登録しても、ルールのオン/オフは指定されていないので、ルールはまだ適用されていません。
extendsは複数のルールのオン/オフを設定した、設定ファイルを指定します。
プラグインに設定値が同梱されている場合もあります。
extendsに設定するファイルは、後から指定したファイルの設定が優先されるため、ファイルを指定する順番に注意が必要です。

ここではextendsに、プラグインに同梱されているreact-hooksのおすすめ設定(recommended)と、airbnbのtypescript用の設定ファイルを指定します。

修正4:rulesに追加

rulesにReactHooks用の設定を加えます。
「react-hooks/rules-of-hooks: error」は、フックのルールに準拠するようにコードを強制します。
「react-hooks/exhaustive-deps: warn」useEffectの関数内で依存関係を引き起こす変数が、依存配列に指定されていないと警告を発します。

6.「package.json」ファイルの修正

scriptsに "lint"、"lintfix"を追記します。

package.json
"scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
+    "lint": "eslint --ext .tsx,.ts src/",
+    "lintfix": "npm run lint -- --fix"
  },

これで下記コマンドで、srcファイル直下のts、tsxファイルのチェックが行われます。

npm run lint

また、下記のコマンドでエラーになるコードのうち、修正できるものは自動修正してくれます。

npm run lintfix

7.動作確認

試しに、vsCodeのターミナルで下記コマンドを実行してみます。

npm run lint

ターミナル上にエラーが表示されますが、エラーが発生しているファイルApp.tsxには何も表示されていません。

8.VsCodeの拡張機能「EsLint」を有効にする

VsCodeの拡張機能「EsLint」をインストールします。
すでにインストール済みの場合は有効にします。
拡張機能「EsLint」がエラー表示をしてくれ、App.tsxが真っ赤になりました。
(まだエラーの修正はしません。続いてPritterのインストールで設定がかわります。)

Prettierの導入

1.Prettierをインストール

下記コマンドでprettierをインストールします。

npm install prettier --save-dev

2. eslint-config-prettier 共有設定をインストール

eslint-config-prettierは、
eslintとprettierで競合する設定は、eslint側のルールをoffにしてくれるものです。
下記のコマンドでインストールします。

npm install eslint-config-prettier --save-dev

3.「package.json」ファイルの確認

package.jsonの状態です。

package.json
"devDependencies": {
    ・・・中略・・・
    "eslint": "^8.8.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-airbnb-typescript": "^16.1.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-import": "^2.25.4",
    "eslint-plugin-jsx-a11y": "^6.5.1",
    "eslint-plugin-react": "^7.28.0",
    "eslint-plugin-react-hooks": "^4.3.0",
    "prettier": "^2.5.1",

今回追加されたものが記載されています。
"eslint-config-prettier": "^8.3.0"
"prettier": "^2.5.1",

4.「.eslintrc.yml」ファイルの設定を修正

extendsの最後に「prettier」を追記します。
これでeslintとprettierで競合する設定は、eslint側のルールをoffにする「eslint-config-prettier」を指定しています。(eslint-config- は省略した形で指定できる)

.eslintrc.yml
env:
  browser: true
  es2021: true
  node: true
extends:
  - plugin:react/recommended
  - airbnb
  - airbnb-typescript
  - prettier  #追加
parser: '@typescript-eslint/parser'
parserOptions:
  ecmaFeatures:
    jsx: true
  ecmaVersion: latest
  project: ./tsconfig.json
plugins:
  - react
  - '@typescript-eslint'
rules: {}

5.「.prettierrc.yml」ファイルを作成

Prettierの設定ファイルです。
私はYAMLファイルで作成しました。
設定はお好みで。

.prettierrc.yml
tabWidth: 2
singleQuote: true
trailingComma: "none"
semi: false
useTabs: false

6.「package.json」ファイルの修正

scriptsに"format": "prettier --write \"**/*.+(js|json|yml|ts|tsx)\""を追記します。

package.json
"scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "lint": "eslint --ext .tsx,.ts src/",
    "format": "prettier --write \"**/*.+(js|json|yml|ts|tsx)\""
  },

これで下記コマンドで、node_modulesフォルダを除く全フォルダで、拡張子「js,json,yml,ts,tsx」ファイルのフォーマットが行われます。

npm run format

7.VsCodeの拡張機能「Prettier」を有効にする

VsCodeの拡張機能「Prettier」をインストールします。
すでにインストール済みの場合は有効にします。
コマンドパレット(ctrl + shift + p で開く)から、「ドキュメントのフォーマット」が実行できるようになります。
ショートカット Shift + Alt + Fでも実行できます。
これは、現在アクティブなファイルのフォーマットを行ってくれます。

8.「.eslintrc.yml」に個別ルール設定を行う

再度、下記のコマンドでコードの解析を行ってみます。

npm run lint


いくつかエラーが表示されますので、修正していきます。

修正1:エラー「'React' must be in scope when using JSX」の対応

「.eslintrc.yml」のrulesに個別のルール設定「react/react-in-jsx-scope: off」を追加します。
これは、tsxファイルに「import React from "react"」を書かないと、EsLintに「'React' must be in scope when using JSX」と怒られます。
React v17からは「import React from "react"」は不要になったので、その対応としてEsLintに怒られないよう設定でoffにします。

.eslintrc.yml
rules: 
  react/react-in-jsx-scope: off

この状態で、再度コマンド「npm run lint」を実行します。

修正2:エラー「'count' is already declared in the upper scope」の対応

App.tsxの下記部分の「count」がエラーになります。

<button type="button" onClick={() => setCount((count) => count + 1)}>

すでに上部で「count」が使われているというエラーです。
「count」を他の名前に変えてあげればいいだけです。

<button type="button" onClick={() => setCount((preCount) => preCount + 1)}>
修正3:semiの設定をする

App.tsxの一部のimport文の末尾だけにセミコロンを付けてみます。

この状態で、再度コマンド「npm run lint」を実行します。
特にエラーは発生しません。
そこで、文末のセミコロンはエラーになるようルールを追記します。(これは好みで)

.eslintrc.yml
rules: 
  react/react-in-jsx-scope: off
  semi:
    - error
    - never

この状態で、再度コマンド「npm run lint」を実行します。
先ほど、セミコロンを付けたimport文がエラーになりました。

まとめ

・・・非常に疲れました😵
他に必要な設定があればどうか教えてください。

Discussion

nabeyangnabeyang

カンマの付け方が逆か、各順序が上下反対かなと思いました。

package.json
"scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
-    "lint": "eslint --ext .tsx,.ts src/"
-    "lintfix": "npm run lint -- --fix",
+    "lint": "eslint --ext .tsx,.ts src/",
+    "lintfix": "npm run lint -- --fix"
  },
piyokopiyoko

ご指摘ありがとうございます。
カンマの付け方が逆ですね!修正しておきます。