ReactのプロジェクトにESLintとPrettierを導入してVSCodeで使ってみた

2022年2月12日プログラミング

アイキャッチreact2

静的解析ツールのESLintとPrettierを使ってreactの開発環境を整えていきたいと思います.

Reactのプロジェクト作成までも過去の記事でご紹介していますので参考にしてください。

完成しているものはこちらにあげています

ESLintとは

静的解析ツールと呼ばれるものです。

簡単な構文エラーや、特定のルールに基づいてコードを解析してくれます。

例えば、使ってない変数や関数を見つけて波線をつけて警告してくれたり、インデントがスペースかタブかとかをチェックしてくれます。

Prettierとは

フォーマッターです。

改行、折り返し、インデントの方法(tab/スペース)、「" “」か「’ '」などコードの書き方をエラーにならない範囲で自動で整形してくれるやつです。

なぜやるのか

一人で書いていても、途中から「" “」と「’ '」が混ざったり、末尾の「;」が抜けたり、変数と{}の間のスペースが入ったりなかったりとコードのルールがごちゃごちゃしてしまいます。

一人でやっていてそうなのだから複数人でやったらもっとごちゃごちゃになってしまいますよね。。

このような、ルールをプロジェクト内で統一するために導入します。

業務で開発したことがないので実体験ではないが、みんなそれぞれ好き勝手に書いていたらレビュアーが大変そう。。

ESLintの導入

yarnにしろ、npxにしろ、create-react-appで作成したプロジェクトには、すでにESLintが入っているので新たにインストールは行はないでください。

プロジェクトを開始した時に、異なるバージョンのeslintが検知されて怒られます。。

なので、ESLintの導入は設定からです。

ESLintの設定

以下のコマンドを実行して初期設定を行います。

$ yarn run eslint --init

このコマンドを実行すると、対話形式でESLintの設定を行うことができます。

聞かれる内容は以下の通りです。

質問今回の回答補足
How would you like to use ESLint? …To check syntax, find problems, and enforce code styleESLintをどのように使うか
What type of modules does your project use?JavaScript modules (import/export)
Which framework does your project use?React利用するフレームワーク
Does your project use TypeScript?No今回はTypeScriptをつかはないのでNo
Where does your code run?Browser実行環境
How would you like to define a style for your project?Use a popular style guide有名どころの設定を使うかどうか
Which style guide do you want to follow?Airbnb: https://github.com/airbnb/javascriptAribnbの設定を使う
What format do you want your config file to be in?YAMLeslintの設定ファイルの形式。
Would you like to install them now with npm?Noyarnでパッケージの管理をしたかったのでNo

最後Noを選択すると必要なパッケージがインストールされずにエラーが表示されるが次で入れるので問題ないです。

$ yarn add -D eslint-plugin-react eslint-config-airbnb eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react-hooks

ここまででESLintに必要なインストールは完了です。

ESLint設定ファイルの編集

$ yarn run eslint --initの内容に応じてプロジェクトファイル内にeslintの設定ファイルが作成されます。

YAMLを選択していた場合初期状態は以下のようになっています。

env:
  browser: true
  es2021: true
extends:
  - 'plugin:react/recommended'
  - airbnb # Which style guide do you want to follow?で選択したよく使われている解析設定
parserOptions:
  ecmaFeatures:
    jsx: true
  ecmaVersion: 12
  sourceType: module
plugins:
  - react
rules: {}

env

プロジェクトの実行環境を指定します。

$ yarn run eslint --initで実行環境をbrowserと指定したためbrowserがtrueになっています。

他に設定できる項目はありますが、公式サイトをご覧ください。

plugins

.eslintrc.yml内での順番は、少し後ですが、extendsと関連があるので先に書きます。

ここでは、extendsのところで書いたように外部から取得したルール群をeslintに追加することができます。

今回の場合reactというプラグインをeslintに追加していますね。

追加するだけでは、ルールは適用されません。

後述するextendsのブロックで有効化してあげる必要があります。

extends

プラグインで追加したルール群やeslint標準のルール群を有効化するブロックです。

今回の例を見てみると'plugin:react/recommended'という記述があります。

「react」というプラグインの「recommended」のルール群を有効化しているという意味になります。

ちなみに「recommended」はプラグイン開発者がベストプラクティスと思うルール群を定義している範囲で、このプラグインの場合、ほかに「all」を指定することができます。

「all」を指定すると、このプラグインに入っている全てのルールを有効にすることができます。

READMEなどを読むと、どのようにルール群が定義されているかがわかるのでお好みの範囲を有効化しましょう。

rules

こちらも、ファイル内では最後に出てきますがpluginと関連があるので先に書きます。

このブロックにはルールごとの個別の設定を記述します。

今までのpluginとextendsだけでは、plugin開発者の定義した範囲での有効/無効しか設定できません。

例えば、pluginは入れたけど一部有効化したくないルールがある場合にそれだけを選んで無効化したりできます。(逆もまた然りです。)

parserOptions

構文チェックの対象や、ecmaScriptのバージョンを指定します。

ecmaScript(ES)はjavascriptの標準規格でeslintはデフォルトでES5の構文をサポートしています。

新しいものを使うにはecmaVersionで指定してあげる必要があります。

sourceTypeはモジュールのタイプで、moduleと指定してあげないとimportやexportなどがエラーになります。

ここがエラーになる

import logo from './logo.svg';

ecmaFeatureは追加の構文を指定します。

標準では、.jsファイルしか認識してくれません。

.jsxなどを使う場合はここで追加してあげる必要があります。

eslintを実行

試しに、コマンドラインからeslintを実行して構文をチェックしてみましょう。

$ yarn create react-appした後の何も変更していないApp.jsに対してチェックを行います。

$ yarn run eslint ./src/App.js
yarn run v1.22.17
$ /Users/tohi/RaiseTech/react/task/task5/hitolog/node_modules/.bin/eslint ./src/App.js

/Users/tohi/RaiseTech/react/task/task5/hitolog/src/App.js
   6:5   error  'React' must be in scope when using JSX        react/react-in-jsx-scope
   6:5   error  JSX not allowed in files with extension '.js'  react/jsx-filename-extension
   7:7   error  'React' must be in scope when using JSX        react/react-in-jsx-scope
   8:9   error  'React' must be in scope when using JSX        react/react-in-jsx-scope
   9:9   error  'React' must be in scope when using JSX        react/react-in-jsx-scope
  12:11  error  'React' must be in scope when using JSX        react/react-in-jsx-scope
  16:9   error  'React' must be in scope when using JSX        react/react-in-jsx-scope

✖ 7 problems (7 errors, 0 warnings)

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

結構出ますねw

手動チェックする場合は、毎回$ yarn run eslint [対象]を実行してチェックしないといけませんがVSCodeと連携すると保存した時に自動で赤い波線が表示されるのですぐわかります。

この構文チェックも.eslintrc.*で設定した内容に基づいてチェックされているので不要だなと感じたらチェック対象から外すこともできます。

試しに、.eslintrc.ymlrulesreact/react-in-jsx-scope: 0と記述し無効にします。

再度、eslintを実行すると、、

$ yarn run eslint  ./src/App.js                                                                                                16s  火 11/ 9 20:43:25 2021
yarn run v1.22.17
$ /Users/tohi/RaiseTech/react/task/task5/hitolog/node_modules/.bin/eslint ./src/App.js

/Users/tohi/RaiseTech/react/task/task5/hitolog/src/App.js
  6:5  error  JSX not allowed in files with extension '.js'  react/jsx-filename-extension

✖ 1 problem (1 error, 0 warnings)

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

react/react-in-jsx-scopeがチェック対象から外れエラーがひとつになりました。

Prettierの導入

prettierをプロジェクトに導入するにはパッケージをインストールする必要があります。

$ yarn add -D prettier

eslintに設定追加

まず、eslint側でprettierと設定が競合しないように一部の設定をOFFにする必要があります。

これは、ひとつづつ選んでOFFにするのではなく、公開されている設定セットを外部から取ってきて使います。

$ yarn add -D eslint-config-prettier

これを.eslintrc.*のextendsで指定するとprettierと競合する設定を自動で無効にしてくれます。

ちなみにこれはプラグインというわけではなく、もともとeslintに備わっている設定をOFFにするだけのものなのでpluginに追加する必要はありません。

公式のREADMEに倣ってextendsに追加します。

env:
  browser: true
  es2021: true
extends:
  - 'plugin:react/recommended'
  - airbnb
  - prettier # <=ここ
parserOptions:
  ecmaFeatures:
    jsx: true
  ecmaVersion: 12
  sourceType: module
plugins:
  - react
rules: {}

公式のREADMEにもありますが、prettierの記述は必ずextendsブロックの最後に記述してください。

追記したprettierより後ろの設定は無効になりません。

Prettier設定ファイルの編集

こっちは自動で作成されないので、自分で作成します。

デフォルトの設定はこちらです。

.prettierrc内で特に指定がなければ、デフォルトの設定が適用されます。

	{
		"printWidth": 80,               //80文字で1行を折り返す
		"tabWidth": 2,                  //タブのサイズを2につす
		"useTabs": false,               //インデントにスペースを使う
		"semi": true,                   //末尾のセミコロンを付ける
		"singleQuote": false,           //""ではなく''をつかう
		"quoteProps": "as-needed",    //必要な場合(間に'-'が入っていたり)オブジェクトのプロパティー名をQuoteで囲む
		"jsxSingleQuote": false,        //jsxにおいて""ではなく''を使う
		"trailingComma": "none",        //可能な場合,をつける
		"bracketSpacing": true,         //{}の前後に空白を入れる=> {foo:bar} => { foo:bar }
		"jsxBracketSameLine": false,    //jsxでhtmlを記述する時、タグの終わり「>」を同じ行に記述する
		"arrowParens": "avoid",         //アロー関数の引数が1つの時カッコで囲まない
		"rangeStart": 0,                //ファイル内を範囲指定でフォーマットする。開始位置の指定
		"rangeEnd": Infinity,           //ファイル内を範囲指定でフォーマットする。終了位置の指定
		"parser": "none",               //パーサーを指定=>prettierは自動で判別するため設定不要
		"filepath": "none",             //使用するパーサーを推測するために使用するファイル名を指定
		"requirePragma": false,         //@formatのコメントが入っているコードのみフォーマットする
		"insertPragma": false,          //requirePragmaで必要なコードを挿入する
		"proseWrap": "preserve",        //マークダウンをそのまま折り返す
		"htmlWhitespaceSensitivity": "css", //htmlのフォーマットをいい感じにしてくれる
		"vueIndentScriptAndStyle": false, //vueファイルの<script>タグの中をインデントしない
		"endOfLine": "auto",            //既存の改行コードを使う
    "embeddedLanguageFormatting"   //ファイルに埋め込まれた引用コードをPrettierが認識できればフォーマットする
	}

今回はとりあえず以下の設定で。

{
  "singleQuote": true,
  "trailingComma": "all"
}

指定していない設定はデフォルト値が勝手に入ります。

Prettierを実行

ESLintと同じくこちらも一回手動で実行してみます。

テスト用に、./src/App.jsに適当に一行追加します。

import logo from './logo.svg';
import './App.css';

function App() {
  console.log("test") # <<<<===ここ
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit
          {' '}
          <code>src/App.js</code>
          {' '}
          and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

.prettierrcで"を使うように設定しているため、実行後にはconsole.log('test');のようになっているはずです。

いざ実行

$ yarn run prettier ./src/App.js
yarn run v1.22.17
$ /Users/tohi/RaiseTech/react/task/task5/hitolog/node_modules/.bin/prettier ./src/App.js
import logo from './logo.svg';
import './App.css';

function App() {
  console.log('test');  #<<<<<<<======ここ!
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;
✨  Done in 1.08s.

整形後のソースコードが出力されます。該当箇所は設定通り整形されていますね。

末尾の;は特に設定していませんがデフォルト値のため勝手に追加してくれています。

プラグインのインストール

今回やりたいことは、VSCode上で先ほど手動で行ったeslintとprettierのチェックを自動で行うことです。

なので、VSCode側でも少し準備が必要です。

まずはプラグインを2つインストールします。

ESLint

Prettier – Code formatter

VSCodeの設定

プラグインの設定が終わったらVSCode側でESLintとPrettierを実行する準備をします。

プロジェクトディレクトリのルートに.vscodeディレクトリを作成しその中にsetting.jsonを作成します。

$ ls                                                                                                                                 火 11/ 9 21:24:19 2021
README.md    node_modules package.json public       src          yarn.lock
$ mkdir .vscode
$ touch settings.json

このsetting.jsonはワークススペースに対しての設定を記述できます。

ワークスペースに対しての設定は、VSCode全体の設定やユーザ設定よりも優先されます。

setting.jsonは以下のような記述をします。

{
  "eslint.format.enable": false,
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}
eslint.format.enableESLintのフォーマット機能を無効にしています。
editor.formatOnSave保存実行時にフォーマットを行う設定を有効にしています。
editor.defaultFormatterデフォルトで使うフォーマッターをPrettierに設定しています。

確認

ここまでできたら、VSCodeを開き直して試します。

ちょっと赤線がすごいですが、5,6行目を追加します。

そのまま保存をすると、、、

お見事、"'に代わり、末尾に;がつきましたね!

以上で基本的な設定は完了です。

この先は、自分やチームに合わせてフォーマットや、コードのルールを追加していきましょう。

プログラミング

Posted by kotaro