【React Native】簡単なAPI連携のアプリケーションを作成する　③ESLint+Prettierの導入(寄り道)

# はじめに
本記事は下記の記事の続編になります。
[【React Native】簡単なAPI連携のアプリケーションを作成する　①準備編](https://qiita.com/kazuki_yoshida/items/d5f47e4d39a9e54f091d)
[【React Native】簡単なAPI連携のアプリケーションを作成する　②住所検索の実装](https://qiita.com/kazuki_yoshida/items/cb7df8d51dc0e0c2f8de)
実践的なアプリを作成するというよりは、ハンズオン的にReact Nativeを触ってみるといった趣旨になっています。
なお思いついた順で記事にしているため、本来は実装を開始する②の前に
本記事の内容であるLintやフォーマッターを実施する方が好ましいのと、
今回の内容は必須ではないため、スキップしていただいても問題ないと思います。
(毎回アレ？ってなるので備忘で残したかったんです。。)


## 本記事で実現すること
VSCode上でコードを編集後、Ctrl+sなどで保存するとシュバッと綺麗にしてくれる。
フォーマッターでは判断できない場合はエラーになり綺麗にならない。
(たまにはLintを無視したいので抑制する)

## 本記事で説明すること
* ESLintの適用手順
* Prettierの適用手順

## 本記事で解説できているか怪しいこと
* 最新のESLint+Prettierのベストプラクティスかどうか<br>

→[Prettier と ESLint の組み合わせの公式推奨が変わり plugin が不要になった](https://blog.ojisan.io/prettier-eslint-cli)
などの記事で触れられているように、去年くらいから公式の推奨方法などが変わっているそうです。
参考にした情報によっては現在のベストプラクティスとは異なる可能性があります。
今回紹介するのは手順の一例程度に捉えていただければ幸いです:pray:

## 環境
* eslint：7.20.0
* eslint-config-prettier：7.2.0
* prettier：2.2.1
<br>※eslint-plugin-prettierは入れないらしい。
* VSCodeの拡張機能で[ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)と[Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)を入れておく。

## githubリポジトリ（追記：削除済み）
https://github.com/pbyoshida/postal-app

# 導入編
それではローカル環境でのLint、フォーマッターの構築を進めていきます。

## 各モジュールの導入
とりあえずはnpmでインストールしていきましょう。
※Lintやフォーマッターは開発者が使うので--save-devを付けます。

```powershell
$ npm install --save-dev eslint eslint-config-prettier prettier
```
package.json見てみましょう。

```json:package.json(導入時点)
{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject"
  },
  "dependencies": {
    "axios": "^0.21.1",
    "expo": "~40.0.0",
    "expo-status-bar": "~1.0.3",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
    "react-native-web": "~0.13.12"
  },
  "devDependencies": {
    "@babel/core": "~7.9.0",
    "eslint": "^7.20.0",
    "eslint-config-prettier": "^7.2.0",
    "prettier": "^2.2.1"
  },
  "private": true
}

```
devDependenciesに導入できていそうですね。

## ESLintのセットアップ
以下のコマンドでセットアップを開始します。

```powershell
$ npx 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
```
一番上のJavaScriptを選択します。
次はフレームワークの選択です。

```
? Which framework does your project use? ...
> React
  Vue.js
  None of these
```
今回はReactなので一番上を選択します。
次は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
```
こちらは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)
```
今回はUdemyの講座で使用していたAirbnbのスタイルを適用しようと思います。
そのため上記の選択肢では一番上を選びます。
この後にどのスタイルにするか聞かれます。

```
? Which style guide do you want to follow? ...
> Airbnb: https://github.com/airbnb/javascript
  Standard: https://github.com/standard/standard
  Google: https://github.com/google/eslint-config-google
```
Airbnbを選択します。
次はconfigファイルの形式です。

```
? What format do you want your config file to be in? ...
  JavaScript
  YAML
> JSON
```
ここではjsonを選びましょう。(多分一般的かなと)
最後は依存するライブラリを自動的にインストールしてくれます。yesを選択してインストールしましょう。
(ついでにここまでの選択も載せておきます。)

```
√ 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? · node
√ 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.21.5 eslint-config-airbnb@latest eslint@^5.16.0 || ^6.8.0 || ^7.2.0 eslint-plugin-import@^2.22.1 eslint-plugin-jsx-a11y@^6.4.1 eslint-plugin-react-hooks@^4 || ^3 || ^2.3.0 || ^1.7.0
? Would you like to install them now with npm? » No / Yes
```
さて、セットアップ後のpackage.jsonは以下になりました。

```json:package.json(セットアップ後)
{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject"
  },
  "dependencies": {
    "axios": "^0.21.1",
    "expo": "~40.0.0",
    "expo-status-bar": "~1.0.3",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
    "react-native-web": "~0.13.12"
  },
  "devDependencies": {
    "@babel/core": "~7.9.0",
    "eslint": "^7.20.0",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-config-prettier": "^7.2.0",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "eslint-plugin-react": "^7.22.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "prettier": "^2.2.1"
  },
  "private": true
}
```
セットアップ後は.eslintrc.jsonというファイルが作成されています。

```json:.eslintrc.json
{
  "env": {
    "es2021": true,
    "node": true
  },
  "extends": [
    "plugin:react/recommended",
    "airbnb",
    "eslint-config-prettier", // 追加
    "prettier" // 追加
  ],
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  "plugins": ["react"],
  "rules": {
    "import/prefer-default-export": 0, // 追加
    "no-use-before-define": 0 // 追加
  }
}

```
もしも無視したいESLintのルールなどがある場合には上記のファイルに追記していきます。
上では追加とコメントしている4行を追記しています。

## VSCodeの設定
続いてVSCodeの設定をしていきます。
.vscodeというフォルダを作成し、その中にsettings.jsonというファイルを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289995/2372a20d-9d97-8565-d416-f7e889885e4d.png)
中身はとりあえずこんな感じにします。

```json:settings.json
{
  /* Linter and Formatter */
  // linter
  "eslint.packageManager": "npm", // ESLintライブラリ解決時に使うパッケージマネージャ
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true, // eslint
    "source.fixAll.stylelint": true // Stylelint
  },
  // formatter
  "editor.defaultFormatter": "esbenp.prettier-vscode", // デフォルトフォーマッターをPrettier
  "editor.formatOnSave": true,
  "editor.formatOnPaste": true,
  "editor.formatOnType": true,
  // Prettier対象外言語
  "prettier.disableLanguages": ["markdown"]
}
```
このあたりは好みがあると思うので、色々と試してみてください。

## Prettierの設定
最後にPrettierの設定です。.prettierrcというファイルを作成し、その中に適用したいルールを記述します。

```:.prettierrc
{
  "trailingComma": "es5",
  "tabWidth": 2,
  "semi": true,
  "singleQuote": true
}
```
一部デフォルトでそうなっているようなものもありますが、とりあえずは上記のような形で記載します。
各オプションは[ドキュメント](https://prettier.io/docs/en/options.html)を参考にしてください。

# 動作確認
動作をさせようとしていたらESLINTの箇所に下記のようなマークが出ていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289995/72eaecef-ac0e-ce90-d0a7-3446e0da1638.png)
そこをクリックして、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289995/d553d125-fab6-2fd1-9f71-367adbeed50b.png)
「Allow Everywhere」を押して承認します。

## ESLintの確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289995/29f8e7c6-e4f7-8550-7d02-3458bff97c8b.png)
前回のソースコードを見てみると2か所怒られていたようです。。
1個目はswitch文にdefaultのケースが無い
2個目はaddressが重複して定義されている
とのことで修正します。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289995/a80af428-9b60-0b78-419d-3950d178f9f8.png)

APIのステータスが200でも400でも500でもない場合って何なんだ、、と思いつつとりあえず予期しない動作としました。
2個目は変数名を変えています。

ただし、どうしてもESLintのルールを無視したい時などがあれば以下のようにコメントしてください。

```:グローバルに無視する場合
/* eslint-disable */
```

```:次の1行だけ無視したい場合
/* eslint-disable-next-line */
```

## Prettierの確認
こちらは適当にスペースを入れまくってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289995/7cfced7e-0ab7-6837-f10c-57fceb69fa2b.png)
こんな感じにガタガタでも、Ctrl+sで保存すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289995/a08e34bb-e963-c8c5-b236-7ac6a7d3e379.png)
シュバッと綺麗に。気持ちいい。。

# 最後に
前回の記事は「まぁこんな感じじゃないの」と思いながら実装していたので、改めてLintやフォーマッターを入れてみると全然整っていなかったことが分かります。
チームで開発する上ではこういった議論や指摘で時間をロスしないために、あらかじめルールを決めておくことが大切だと実感できますね。
今回は寄り道しましたが、次回もう一つのAPIを実行するコードを実装してシリーズを終わりたいと思います。

2021/2/21 最終回を書きました。
→[【React Native】簡単なAPI連携のアプリケーションを作成する　④天気情報表示の実装](https://qiita.com/kazuki_yoshida/items/f6f576ec1782b8878e6f)