create-react-appで作成した雛形 + VSCodeにESLintとPrettierを導入する

前回、DockerでReact + Swagger 環境を作ろうという記事を書いたのですが、VSCode に ESLint 導入時に少し手間取ったので別記事にしました。
あわせてコード整形ツールである Prettier も導入したので、その手順を書いておきます。

※この記事はQiitaからの転載です。

※2021/03/22追記 eslint-plugin-prettierが非推奨になったりと情報が古くなったので、全体的に書き直しました。
※TypeScript 環境での対応は記載していないのでご注意ください。

ESLint #

公式:ESLint

静的解析ツールです。
コーディングする上でのルールを決められるので、チーム開発するうえでコードのスタイルを統一することができます。

セットアップの確認 #

create-react-app で作成された雛形では、すでに ESLint に関するパッケージが導入されており、yarn.lock でreact-scriptsの依存関係となっているのを確認できます。

以下はcreate-react-app@4.0.3で作成した React プロジェクトの例です。

※一部抜粋
react-scripts@4.0.3:
  version "4.0.3"
  resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-4.0.3.tgz#b1cafed7c3fa603e7628ba0f187787964cb5d345"
  integrity sha512-S5eO4vjUzUisvkIPB7jVsKtuH2HhWcASREYWHAQ1FP5HyCv3xgn+wpILAEWkmy+A+tTNbSZClhxjT3qz6g4L1A==
  dependencies:
    "@babel/core" "7.12.3"
    "@pmmmwh/react-refresh-webpack-plugin" "0.4.3"
    "@svgr/webpack" "5.5.0"
    "@typescript-eslint/eslint-plugin" "^4.5.0"
    "@typescript-eslint/parser" "^4.5.0"
    babel-eslint "^10.1.0"
    babel-jest "^26.6.0"
    babel-loader "8.1.0"
    babel-plugin-named-asset-import "^0.3.7"
    babel-preset-react-app "^10.0.0"
    bfj "^7.0.2"
    camelcase "^6.1.0"
    case-sensitive-paths-webpack-plugin "2.3.0"
    css-loader "4.3.0"
    dotenv "8.2.0"
    dotenv-expand "5.1.0"
    eslint "^7.11.0"
    eslint-config-react-app "^6.0.0"
    eslint-plugin-flowtype "^5.2.0"
    eslint-plugin-import "^2.22.1"
    eslint-plugin-jest "^24.1.0"
    eslint-plugin-jsx-a11y "^6.3.1"
    eslint-plugin-react "^7.21.5"
    eslint-plugin-react-hooks "^4.2.0"
    eslint-plugin-testing-library "^3.9.2"
    eslint-webpack-plugin "^2.5.2"
    file-loader "6.1.1"
    fs-extra "^9.0.1"
    html-webpack-plugin "4.5.0"
    identity-obj-proxy "3.0.0"
    jest "26.6.0"
    jest-circus "26.6.0"
    jest-resolve "26.6.0"
    jest-watch-typeahead "0.6.1"
    mini-css-extract-plugin "0.11.3"
    optimize-css-assets-webpack-plugin "5.0.4"
    pnp-webpack-plugin "1.6.4"
    postcss-flexbugs-fixes "4.2.1"
    postcss-loader "3.0.0"
    postcss-normalize "8.0.1"
    postcss-preset-env "6.7.0"
    postcss-safe-parser "5.0.2"
    prompts "2.4.0"
    react-app-polyfill "^2.0.0"
    react-dev-utils "^11.0.3"
    react-refresh "^0.8.3"
    resolve "1.18.1"
    resolve-url-loader "^3.1.2"
    sass-loader "^10.0.5"
    semver "7.3.2"
    style-loader "1.3.0"
    terser-webpack-plugin "4.2.3"
    ts-pnp "1.2.0"
    url-loader "4.1.1"
    webpack "4.44.2"
    webpack-dev-server "3.11.1"
    webpack-manifest-plugin "2.2.0"
    workbox-webpack-plugin "5.1.4"
  optionalDependencies:
    fsevents "^2.1.3"

設定に関してはpackage.jsonに記述があり、デフォルトではこの設定で ESLint が動作します。

"eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },

最低限のセットアップはすでに行われているので、あとはそれをカスタマイズしていくだけです。

CLI で動かしてみる #

チェックを行いたいファイルパスを指定して実行します。

コマンド例

$ yarn run -s eslint './src/**/*.{js,jsx}'

自動整形までやりたい場合は--fixをつけて実行します。

コマンド例

$ yarn run -s eslint './src/**/*.{js,jsx}' --fix

注意点として、自動整形は必ずしも全ての問題個所を直してくれるわけではありません。
自動整形で対応できない箇所は、自分たちで直す必要があります。

VSCode エディタ上で ESLint を動作させる際は、あまりコマンドを使用しないかもしれませんが、CI でのテスト時に使用したりということがあります。
使いやすいようにpackage.jsonの scripts にコマンドを設定しておくとよいです。

"scripts": {
  .
  .
  .
  "lint:eslint": "yarn run -s eslint './src/**/*.{js,jsx}'",
  "fix:eslint": "yarn run -s eslint './src/**/*.{js,jsx}' --fix"
}

VSCode 上で動かす #

VSCode 拡張:ESLint

インストールして再起動。
特に問題なければこれだけでチェックが動作します。

ファイル保存時に自動整形を走らせたい場合は、VSCode の設定ファイルにその旨追記します。

.vscode/settings.jsonの例

{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "editor.formatOnSave": false,
}

ESLint の設定ファイル #

設定の定義の仕方としては、以下の4パターンがあります。

  • package.jsonの eslintConfig に書く
  • JavaScript ファイル(例 .eslintrc.js)に書く
  • JSON ファイル(例 .eslintrc.json)に書く
  • YAML ファイル(例 .eslintrc.yml)に書く

個人的な好みとしては2番目です。
別ファイルにしておいた方が、一度作成した設定を別プロジェクトで使いまわしたりしやすいです。

設定の記述方式は公式をご参照ください。
ESLint - Configuring ESLint

それと、ESLint のチェックから除外したいファイルがある場合は、.eslintignore ファイルを作って書いておくことで対応できます。

node_modules/

ESLint の設定ファイルを対話式で作成 #

ESLint の設定ファイルは対話式で作成することも可能です。
まずこれで雛形を作成して、そこからカスタマイズしていくとよいです。

以下は回答の流れの例です。

$ yarn run -s eslint --init

ESLintをどのように使用しますか?

? How would you like to use ESLint?
  To check syntax only
  To check syntax and find problems
❯ To check syntax, find problems, and enforce code style

どんなモジュールを使用していますか?

? What type of modules does your project use?
❯ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

どのフレームワークを使用していますか?

? Which framework does your project use?
❯ React
  Vue.js
  None of these

TypeScriptは使用していますか?

? Does your project use TypeScript? No / Yes
  No

コードはどこで実行されますか?

? Where does your code run? (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ Browser
 ◯ Node

プロジェクトのスタイルをどのように定義しますか?

? How would you like to define a style for your project?
❯ Use a popular style guide
  Answer questions about your style
  Inspect your JavaScript file(s)

どのスタイルガイドをフォローしますか?

? 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)

設定ファイルのフォーマットはどれにしますか?

? What format do you want your config file to be in? (Use arrow keys)
❯ JavaScript
  YAML
  JSON

npm でこれらのパッケージをインストールしますか?
(yarn でインストールしたい場合は No を選択して、案内されたパッケージを手動でインストールする必要があります)

eslint-plugin-react@^7.14.3 eslint-config-airbnb@latest eslint@^5.16.0 || ^6.1.0 eslint-plugin-import@^2.18.2 eslint-plugin-jsx-a11y@^6.2.3 eslint-plugin-react-hooks@^1.7.0
? Would you like to install them now with npm? No / Yes
  No

スタイルガイドの導入 #

ESLint の設定ファイルを対話式で作成時の回答にもありましたが、企業などのスタイルガイドを準拠した ESLint の共有設定が存在します。
全く一からルール設定をするのは大変なので、この共有設定を適用して、適宜カスタマイズするとよいです。

以下は Airbnb の共有設定を使用する例です。

パッケージをインストール

$ yarn add -D eslint-config-airbnb

設定の extends に追加(.eslintrc.jsでの例)

extends: [
  'plugin:react/recommended',
  'airbnb', // 追記
]

トラブルシューティング #

ルート階層に設定ファイルがない場合 #

VSCode の ESLint 拡張は、ワークスペースに追加したフォルダの直下に設定ファイル(.eslintrc.jspackage.jsonなど)がある前提で動作します。
直下にない場合は、VSCode の設定ファイルで別途指定する必要があります。

※例(app 直下に設定ファイルがある場合)

{
  "eslint.workingDirectories": [
	"./app"
  ]
}

React のバージョン検知ができない場合 #

Docker コンテナの中に Node.js 環境があるが、ローカルの VSCode 上で ESLint 拡張を動かしている(ローカルに Node.js 環境がない)など、環境によって以下の Warning が出ることがあります。

Warning: React version was set to "detect" in eslint-plugin-react settings, but the "react" package is not installed. Assuming latest React version for linting.

eslint-plugin-react でプロジェクトの React のバージョンを指定しているのですが、デフォルトが detect となっており、自動でバージョンを検知するようになっている模様。
上記のような環境においては、さすがにバージョン検知ができないようです。

ESLint の設定に、明示的にバージョンを指定することで対応できます。

eslintrc.jsの例

settings: {
  react: {
    version: '17.0.1'
  }
}

Prettier #

公式:Prettier

幅広いファイル形式に対応したコードフォーマッタです。
ESLint とあわせて導入しておくと、さらなるコードの品質向上に繋がります。

react-scriptsの依存関係に Prettier に関するものはないので、追加でライブラリをインストールしていく必要があります。

連携セットアップ #

ライブラリインストール

$ yarn add -D prettier eslint-config-prettier

ESLint の設定ファイルに追記(.eslintrc.jsの例)

extends: [
  'plugin:react/recommended',
  'airbnb',
  'prettier', // 追記
],

ESLint と Prettier はルールが競合することがあるので、eslint-config-prettier を適用することで競合するルールを無効化して調整します。
その性質上、追加するのは extends の最後にしてください。

ちなみに eslint-config-prettier は、競合しているルールがないかチェックする CLI ツールを持っていたりします。

コマンド例

$ yarn run -s eslint-config-prettier './src/**/*.{js,jsx}'

問題なければ以下のような表示になります。

No rules that are unnecessary or conflict with Prettier were found.

CLI で動かしてみる #

チェックを行いたいファイルパスを指定して実行します。

コマンド例

$ yarn run -s prettier --check .

自動整形までやりたい場合は--writeをつけて実行します。

コマンド例

$ yarn run -s prettier --check . --write

このコマンドも ESLint の時と同様に、package.jsonの scripts に追加しておくとよいです。

"scripts": {
  .
  .
  .
  "lint:prettier": "yarn run -s prettier --check .",
  "fix:prettier": "yarn lint:prettier -- --write",
}

ESLint とセットで1コマンドで実行したい場合は、下記のようにする手もあります。

"scripts": {
  .
  .
  .
  "lint": "yarn lint:eslint && yarn lint:prettier",
  "lint:eslint": "yarn run -s eslint './src/**/*.{js,jsx}'",
  "lint:prettier": "yarn run -s prettier --check .",
  "fix": "yarn fix:eslint && yarn fix:prettier",
  "fix:eslint": "yarn lint:eslint -- --fix",
  "fix:prettier": "yarn lint:prettier -- --write",
}

VSCode 上で動かしてみる #

VSCode 拡張:Prettier

インストールして必要に応じて再起動。

VSCode の設定ファイルに以下を追記(.vscode/settings.jsonの例)

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[javascript]": {
    "editor.formatOnSave": true
  },
  "[javascriptreact]": {
    "editor.formatOnSave": true
  },
  "[json]": {
    "editor.formatOnSave": true
  },
}

VSCode のデフォルトのフォーマッタに Prettier を設定。
加えて、上記3つのファイル形式において、保存時に自動整形が動作するようにしています。

Prettier の設定ファイル #

設定の定義の仕方としては、以下の6パターンがあります。

  • package.jsonの prettier に書く
  • .prettierrcファイルに書く
  • JavaScript ファイル(例 .prettierrc.js)に書く
  • JSON ファイル(例 .prettierrc.json)に書く
  • YAML ファイル(例 .prettierrc.yml)に書く
  • TOML ファイル(例 .prettierrc.toml)に書く

個人的な好みとしては2番目です。
ESLint と同様に別ファイルにしておいた方が、一度作成した設定を別プロジェクトで使いまわしたりしやすいです。

設定の記述方式は公式をご参照ください。
Prettier - Configuration File

それと、Prettier のチェックから除外したいファイルがある場合は、.prettierignoreファイルを作って書いておくことで対応できます。

参考リンクまとめ #