React環境構築①では、create-react-appコマンドを使って、まずは基本のReact環境を作成するとこまで完了。
今回は引き続き、この作成したReact環境に対して、ESLintとPrettierを導入していく。
ESLintとは?
ESLintはJavaScriptの静的解析ツール。
文法的に間違っていたり、使用されない変数や関数があったりすると、検出してくれる。(バグの温床になりうるコードになるのを防いでくれる。)
ちなみに、組込み系のC言語の場合だと、コンパイル時にある程度文法解析はされるものの、それ以外にいろんな静的解析ツールをかけてた。でも、そのツールは各社全く異なっていて、ESLintのように、JavaScriptならコレ!みたいな、王道的なやつはなかったな・・・。
JavaScriptの静的検証ツールは、いくつか王道はあるものの、概ねデファクトスタンダードがあるというか、この中のどれか設定しておけばいいんじゃない?っていうのがあるのは、とてもいい。
ESLintを使うことで、プロジェクトのコーディングルールが統一される。(特に複数人で開発する場合は威力を発揮する。)
ESLintのスタイル
ESLintの王道のスタイルはいくつかあるらしい。
- Airbnb
- Standard
- XO
npm trendsというページに、どのコンフィグが一番ダウンロードされたかっていう情報が載っているんだけど、Airbnb独り勝ちww
Airbnbは、セミコロンを省略しないルール。Standardは、セミコロンを省略するのがルールになるから、セミコロンを省略したくない派の私は、Airbnb一択だな。
とは言え、ルールは後でカスタマイズ可能らしいので、正直何を選んでもいいような気がする。
Airbnbはどちらかというと厳しい側のルールになるらしいので、これに慣れておけばいいのでは?と勝手に思っている。
Prettierとは?
Node.js上で動くコード形成ツール。(コードフォーマッタ)
自動で空白や改行を入れてくれたりするので、コードのスタイルの統一が可能。
コードフォーマッタを使えば、内容的に同じソースコードで、改行や空白の有り無しによる差分が出ることを防ぐことができるので、お便利。(かつ見やすい)
コードフォーマットの機能は、ESLintにもあるらしいが、Prettierのほうが優秀とのこと。
ただし、Prettierには、ESLintのような構文チェックの機能はないので、両方を併用する。
ESLintの設定ファイルの作成
React環境構築①でcreate-react-appコマンドでReact環境を作成したときに、ESLint自体は自動でインストールされている。
まずは公式のGetting Startedに則って、package.jsonのESLintをdevDependenciesに追加。(--devを付けると、開発用のところに追加される)
yarn add eslint --dev
追加された。(でもこれ、バージョンが原因で、あとでエラーになる・・・悲)
次に、ESLintの設定用のファイルを作成し、ライブラリ等のインストールができるように下記のコマンドを実行。
npx eslint --init
ここから質問攻めw
めっちゃ聞いてくるやん。
How would you like to use ESLint?
⇒ To check syntax, find problems, and enforce code style
What type of modules does your project use?
⇒ JavaScript modules (import/export)
Which framework does your project use?
⇒ React
Does your project use TypeScript?
⇒ Yes (これ、Noにしておけばよかった。後でエラーになるw)
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/javascript
What format do you want your config file to be in?
⇒ JSON
Would you like to install them now with npm?
⇒ No (yarn使ってる場合、ここをYesにするとエラーになる)
これで完了。
プロジェクト直下に、.eslintrc.jsonというファイルができている。
2021/11/23 追記:
↑でTypeScriptをNoにすればよかった~!って書いたけど、ctrl + Cで init 処理の中断ができるらしい。(こういうところ、RaiseTechのメンターさんが色々教えてくださるので、とってもありがたい・・・😂)
あとは、ESLint を入れる前に、commit しておくと、設定系をやり直したい時なんかにとっても便利っていうアドバイスもいただき。
とっても納得。
まず、やってみよ、っていうのはちょっと反省かなww
試すにしても、元に戻しやすい状態にして試すのは、今後必要なスキルの1つかもしれない。
.eslintrc.jsonの編集
それでは、先ほど生成された、.eslintrc.jsonを変更していく。
package.jsonの内容をeslintrc.jsonに移植
create-react-app実行時にできた、package.jsonから、ESLintの部分を.eslintrc.jsonに移植する。
(ESLintは、package.jsonではなく、.eslintrc.jsonを参照するから)
package.jsonの赤枠部分を削除
.eslintrc.jsonに移植(赤枠部分を追加)
ESLintのエラーをなくしていく
ここからめっちゃ大変。(悲報)
yarn build して出てきたエラーを、順に対処していく。
There might be a problem with the project dependency tree.
It is likely not a bug in Create React App, but something you need to fix locally.
The react-scripts package provided by Create React App requires a dependency:
"eslint": "^7.11.0"
Don't try to install it manually: your package manager does it automatically.
However, a different version of eslint was detected higher up in the tree:
C:\Users\neco-project\node_modules\eslint (version: 8.2.0)
1個目のエラー。
eslintのメジャーバージョンが、7なのに、8が入ってるから依存関係の整合性が取れないよ、的なやつ。
ESLintmのBlogページにリリースノート的な記事があって、それを見ると7.32.0がメジャーバージョン7の最新版なので、package.jsonに記載されているバージョンを変更する。
package.json
"devDependencies": { "eslint": "^7.32.0", }
書き換えたら、nome_modulesフォルダを消して、yarn.lockファイルも削除。(2021/11/23 追記:この時にyarn.lockファイルは削除しなくても大丈夫らしい。package.jsonを編集した場合は、yarn installすれば、package.json通りに処理してくれるのだとか。)
そのあとに、yarn installコマンドで再インストール。
2個目のエラー
Failed to load config "airbnb" to extend from.
Referenced from: C:\Users\neco-project\.eslintrc.json
airbnbがない的なやつ。
ないならインストールしましょう。
yarn add --dev eslint-config-airbnb
3個目のエラー
Failed to load parser '@typescript-eslint/parser' declared in '.eslintrc.json': Cannot find module 'typescript'
Failed to load parser '@typescript-eslint/parser' declared in '.eslintrc.json': Cannot find module 'typescript'
Failed to load plugin '@typescript-eslint' declared in '.eslintrc.json': Cannot find module 'typescript'
TypeScripのモジュールないよ!的なやつ。
TypeScriptなしにすればよかったな。
.eslintrc.jsonファイルの該当のところ、コメントアウトしちゃいます。(.eslintrc.jsonはJSONだけどコメントが書ける!)
.eslintrc.json
{ "env": { "browser": true, "es2021": true }, "extends": [ "react-app", "react-app/jest", "plugin:react/recommended", "airbnb" ], // "parser": "@typescript-eslint/parser", "parserOptions": { // "ecmaFeatures": { // "jsx": true // }, "ecmaVersion": 13, "sourceType": "module" }, "plugins": [ "react" // ,"@typescript-eslint" ], "rules": { "react/react-in-jsx-scope": "off", "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx", ".tsx"] }] } }
4つ目のエラー
src\App.js
Line 4:1: Function component is not a function expression react/function-component-definition
Line 6:5: 'React' must be in scope when using JSX react/react-in-jsx-scope
Line 6:5: JSX not allowed in files with extension '.js' react/jsx-filename-extension
Line 7:7: 'React' must be in scope when using JSX react/react-in-jsx-scope
Line 8:9: 'React' must be in scope when using JSX react/react-in-jsx-scope
Line 9:9: 'React' must be in scope when using JSX react/react-in-jsx-scope
Line 10:16: `code` must be placed on a new line react/jsx-one-expression-per-line
Line 10:16: 'React' must be in scope when using JSX react/react-in-jsx-scope
Line 10:39: ` and save to reload. ` must be placed on a new line react/jsx-one-expression-per-line
Line 12:9: 'React' must be in scope when using JSX react/react-in-jsx-scopesrc\index.js
Line 8:3: JSX not allowed in files with extension '.js' react/jsx-filename-extension
Line 11:34: Missing trailing comma comma-danglesrc\reportWebVitals.js
Line 1:25: Expected parentheses around arrow function argument arrow-parens
Line 3:32: Expected a line break after this opening brace object-curly-newline
Line 3:74: Expected a line break before this closing brace object-curly-newline
めっちゃ出てるな・・・
1個ずつつぶしていくか。(遠い目)
react/react-in-jsx-scope
JSXでReact をインポートしてないとエラーになるらしい。
「import React from 'react'」がないよっていうエラー。(でも、React v17以降は書かなくてもいい仕様になったらしく、create-react-appで生成されたファイルにも記載がない。)
というわけで、.eslintrc.json にこのルールを無視する記述を追加する。
.eslintrc.json
"rules": { "react/react-in-jsx-scope": "off" }
react/jsx-filename-extension
上のサイトにある通り、デフォルトに合わせて、.eslintrc.json にこのルールを無視する記述を追加する。
.eslintrc.json
"rules": { "react/react-in-jsx-scope": "off", "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx", ".tsx"] }] }
残りは、文法的なエラーっぽいので、eslint --fixコマンドで自動修正してもらいましょう。
その前に、package.jsonに、eslintのコマンドを追加。(いちいちパスを指定するのがめんどくさいから)
package.json
"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "lint": "eslint ./src" },
これでlintというコマンドが使えるようになったので、lint --fix 該当ファイル名 で自動修正。
ようやくエラーが消えた。
ワーニングはあるけど、とりあえず動かせるものを作ることが今回の目標なので、ちょっと今はスルーww
Prettierのインストール
ようやくPrettierまでこぎつけました!
Prettierは関連するライブラリを追加でインストールする必要がある。
yarn add --dev prettier eslint-config-prettier
package.jsonのdevDependenciesにPrettierが追加された。
.eslintrc.jsonのextendsにも、prettierを追加。(extendsの最後に追加すると、ESLintで構文解析、Prettierで整形の設定になる。)
.eslintrc.json
"extends": [ "react-app", "react-app/jest", "plugin:react/recommended", "airbnb", "prettier" ],
Prettierのコマンドも、ESLintと同様に、package.jsonのscriptsに登録しておく。
package.json
"scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "lint": "eslint ./src", "fmt": "prettier --write ./{public,src}/**/*.{js,jsx,ts,tsx,html,gql,graphql,json}" },
これで、yarn fmt コマンドで一括整形できる。
VSCodeの設定
Prettierをインストールする。
画面左下の歯車マーク > 設定
ワークスペースを選択して、検索ボックスに「save」と入力。
Format On Save にチェックを入れる。
Format On Save Mode を file に設定。
検索ボックスに「default」と入力して、Default formatter に Prettier を設定。
この設定をすると、ワークスペースに、.vscodeフォルダができて、その中にsettings.jsonが生成される。
settings.json
{ "editor.defaultFormatter": "esbenp.prettier-vscode" "editor.formatOnSave": true }
これで、VSCodeでこのプロジェクトの中のファイルを更新して保存するときに、Prettierの整形が実行される。
せっかくなので、App.js をデフォルトからちょっと変更して保存してみる。
App.js
import React from "react"; const App = function () { return ( <div> <h1>Hello Neco World!!</h1> <p>(=^.^=)</p> </div> ); }; export default App;
yarn startコマンドを実行。
とりあえず、これで一通り環境は整った。