Next.jsへの導入を例にESLintとPrettierについて解説する

この記事ではESLint、Prettierとはなんぞや？　という方向けに、Next.jsでの設定を例に解説を行います。

ESLintとPrettierを導入するメリットは、**常に一定のクオリティを保ちながらJavaScript・TypeScriptを書けるようになること**です。

## 0. 前提条件

- Node.jsのバージョンは14.x.x
- Next.jsのバージョンは12.x.x
- Reactのバージョンは17.x.x以上
- ソースコードはTypeScriptで記述する
- エディタにはVisual Studio Codeを使用


## 1. 最終的な設定内容

記事が長くなるので、まず最初に全体像として最終的な設定内容をお見せします。

```text:ファイル構成
.
|-- .eslintrc.json
|-- .prettierignore
`-- .prettierrc.json
```

```json:package.json
{
  ...
  "scripts": {
    ...
    "lint": "next lint"
  },
  ...
  "devDependencies": {
    ...
    "@typescript-eslint/eslint-plugin": "^5.20.0",
    "@typescript-eslint/parser": "^5.20.0",
    "eslint": "8.13.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-airbnb-typescript": "^17.0.0",
    "eslint-config-next": "12.1.5",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-react": "^7.29.4",
    "prettier": "^2.6.2",
    ...
  }
}
```

```json:.eslintrc.json
{
  "env": {
    "browser": true,
    "node": true,
    "es2022": true
  },
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": "latest",
    "project": "./tsconfig.json",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "extends": [
    "eslint:recommended",
    "next/core-web-vitals",
    "plugin:@typescript-eslint/recommended",
    "plugin:react/recommended",
    "airbnb",
    "airbnb-typescript",
    "prettier"
  ],
  "plugins": ["@typescript-eslint", "react"],
  "rules": {
    "react/react-in-jsx-scope": "off",
    "react/function-component-definition": [
      2,
      {
        "namedComponents": "arrow-function",
        "unnamedComponents": "arrow-function"
      }
    ],
    "react/prop-types": "off"
  }
}
```

```.prettierrc.json
{
  "endOfLine": "lf",
  "semi": true,
  "singleQuote": true,
  "jsxSingleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 60
}
```

```rust:.prettierignore
# next.js build output
.next
out
# dotenv environment variables file (build for Zeit Now)
.env
.env.local
# Dependency directories
node_modules
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
```


## 2. ESLintとPrettierの概要


### 2-1. ESLintとはなんぞや？

ESLint公式ドキュメントから、ESLintの概要を引用します。

> ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs. In many ways, it is similar to JSLint and JSHint with a few exceptions:
>
> - ESLint uses Espree for JavaScript parsing.
> - ESLint uses an AST to evaluate patterns in code.
> - ESLint is completely pluggable, every single rule is a plugin and you can add more at runtime.

引用元：https://eslint.org/docs/user-guide/getting-started

要約すると、ESLintは**ECMAScript/JavaScriptのコードのパターンを分析してレポートを出力することでコードの一貫性を保ち、バグを防ぐためのツール**です。
各ルールに応じたプラグインを追加できるという特徴を持っています。

### 2-2. Prettierとはなんぞや？

Prettierとは**様々な言語をサポートするコードフォーマッター**[^1]であり、**いつ、誰が書いてもコードが一定の様式を保てるようにするため**[^2]のものです。

ESLintのようなリンターとの使い分けとしては、**コードの規則をチェックしてバグを拾うにはリンターを使用**し、**フォーマットを整えるのにはPrettierを使用する**ことが推奨されています[^3]。

[^1]:参考URL：https://prettier.io/docs/en/index.html
[^2]:参考URL：https://prettier.io/docs/en/why-prettier.html
[^3]:参考URL：https://prettier.io/docs/en/comparison.html


## 3. Next.jsへのESLintの導入


### 3-1. Next.js用のESLint初期設定

Next.js公式ドキュメントの記載を参考に、Next.js用のESLint初期設定をします。

参考：https://nextjs.org/docs/basic-features/eslint

package.jsonの`scripts`に`"next lint"`を追加。

```json:package.json
{
  ...
  "scripts": {
    ...
    "lint": "next lint"
  },
 ...
```

`yarn lint`もしくは`npm run lint`を実行すると、ESLintの設定をStrictかBaseから選ぶように聞かれるので、とりあえず今回はStrictを選択。

```shell
$ next lint
? How would you like to configure ESLint? https://nextjs.org/docs/basic-features/eslint
❯  Strict (recommended)
   Base
   Cancel
```

選択すると、devDependenciesにeslintとeslint-config-nextが自動でインストールされます。

```shell
Installing devDependencies:
- eslint
- eslint-config-next
```

公式サイトだと.eslintrc.jsonも自動で作成されることになっていますが、なぜか私の環境ではされないので、手動で追加します。
(原因は別途調査して分かったら追記します)
ルートフォルダに追加してください。

```json:.eslintrc.json
{
  "extends": ["eslint:recommended", "next/core-web-vitals"]
}
```

:::note info
.eslintrc.jsonのextendsでは、すでに構成済みの設定を読み込むことができます。

参考：https://eslint.org/docs/user-guide/configuring/configuration-files#extending-configuration-files
:::

`"eslint:recommended"`を指定するとESLint推奨のチェック項目を確認します。

[Next.js公式ドキュメント](https://nextjs.org/docs/basic-features/eslint)によると、`"next/core-web-vitals"`は、Next.jsの基本ESLint設定＋より厳密なルールセット(Core Web Vitals rule-set)を含んでいます。


### 3-2. envの記載追加

.eslintrc.jsonにenvの記載を追加します。

```diff_json:.eslintrc.json
{
+ "env": {
+   "browser" : true,
+   "node" : true,
+   "es2022" : true
+ },
  "extends": ["eslint:recommended", "next/core-web-vitals"]
}
```

:::note info
envを指定することで事前定義されたグローバル変数を設定することができます。
使用できるグローバル変数の一覧：https://eslint.org/docs/user-guide/configuring/language-options#specifying-environments

参考：[.eslintrcのenv設定ってなんぞや？](https://zenn.dev/kimromi/articles/546923b7281dcb)
:::


### 3-3. TypeScriptのparserを追加

ESLintでTypeScriptのチェックをできるようにするために、`@typescript-eslint/parser`をインストールします。

下記コマンドを実行。

**yarnの場合**

```shell
yarn add -D @typescript-eslint/parser
```

**npmの場合**

```shell
npm install --save-dev @typescript-eslint/parser
```

.eslintrc.jsonの記載を修正。

```diff_json:.eslintrc.json
{
  "env": {
    "browser": true,
    "node": true,
    "es2022": true
  },
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+   "ecmaVersion": "latest",
+   "project": "./tsconfig.json",
+   "ecmaFeatures": {
+     "jsx": true
+   }
+ },
  "extends": ["eslint:recommended", "next/core-web-vitals"]
}
```

parserに`"@typescript-eslint/parser"`を指定します。

parserOptionsの指定について補足します。

| オプション | 説明                                               |
|:----------|:---------------------------------------------------|
|ecmaVersion|使用するECMAScriptのバージョンを指定。今回は"latest"|
|project    |parserが読み込むtsconfig.jsonファイルを指定        |
|ecmaFeatures|jsxをtrueにすると、.js、.jsx、.tsxのファイルが解析される|

parserOptionsについて、より細かい説明は下記を参照。

参考：https://www.npmjs.com/package/@typescript-eslint/parser


### 3-4. その他おすすめ設定の適用

その他のおすすめ設定もインストールします。

追加で下記設定をインストールします。

- @typescript-eslint/eslint-plugin
- eslint-plugin-react
- eslint-config-airbnb
- eslint-config-airbnb-typescript

次のコマンドを実行。

**yarnの場合**

```shell
yarn add -D @typescript-eslint/eslint-plugin eslint-plugin-react eslint-config-airbnb eslint-config-airbnb-typescript
```

**npmの場合**

```shell
npm install --save-dev @typescript-eslint/eslint-plugin eslint-plugin-react eslint-config-airbnb eslint-config-airbnb-typescript
```

.eslintrc.jsonを再度修正します。

```diff_json:.eslintrc.json
{
  "env": {
    "browser": true,
    "node": true,
    "es2022": true
  },
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaVersion": "latest",
    "project": "./tsconfig.json",
    "ecmaFeatures": {
      "jsx": true
    }
  },
- "extends": ["eslint:recommended", "next/core-web-vitals"]
+ "extends": [
+   "eslint:recommended",
+   "next/core-web-vitals",
+   "plugin:@typescript-eslint/recommended",
+   "plugin:react/recommended",
+   "airbnb",
+   "airbnb-typescript"
+ ],
+ "plugins": ["@typescript-eslint", "react"],
+ "rules: {
+   "linebreak-style": ["error", "windows"],
+   "react/react-in-jsx-scope": "off",
+   "react/function-component-definition": [
+     2,
+     {
+       "namedComponents": "arrow-function",
+       "unnamedComponents": "arrow-function"
+     }
+   ],
+   "react/prop-types": "off"
+ }
}
```

修正箇所について補足します。

|記載内容 |説明|
|:--------------------------------------------------|:-------------------------------------------------------------------------------------------|
|"extends" : "plugin:@typescript-eslint/recommended"|TypeScript関連のおすすめ設定。`"plugins" : "@typescript-eslint"`とセットで指定する。          |
|"extends" : "plugin:react/recommended"             |React関連のおすすめ設定。"plugins" : "react"とセットで指定する。                              |
|"extends" : "airbnb", "airbnb-typescript"          |AirbnbのESLint設定。typeのネーミングルールなど、より細かいチェックができるので追加しています。  |
|"rules" : "react/react-in-jsx-scope"               |Reactが17.x.xからReactのimportがなくても動くようになった。offにしておかないと、Reactのimportをしないと注意されるので追加。|
|"rules" : "react/function-component-definition"    |airbnbデフォルト設定だと、arrow関数が許可されないため修正。                                    |
|"rules" : "react/prop-types"                       |[PropTypesを用いた型チェック](https://ja.reactjs.org/docs/typechecking-with-proptypes.html)に関するルール。TypeScriptで型定義するなら基本的には不要と思います。 |

参考１：https://chaika.hatenablog.com/entry/2020/12/04/083000
参考２：https://bufferings.hatenablog.com/entry/2021/11/16/225032

:::note info
rulesには個別のルール設定を指定します。
全体的に不要なルールのoffもここで行います。
:::


## 4. Next.jsへのPrettierの導入

ここからはPrettierのインストールと設定内容について記載します。


### 4-1. Prettierのインストールと設定ファイルの作成

まずは、下記コマンドを実行。

**yarnの場合**

```shell
yarn add -D prettier eslint-config-prettier
```
**npmの場合**

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

ルートフォルダに`.prettierrc.json`ファイルを追加します。
このファイルが実際のフォーマットの設定になります。

```json:.prettierrc.json
{
  "endOfLine": "lf",
  "semi": true,
  "singleQuote": true,
  "jsxSingleQuote": false,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 60
}
```

正直Prettierの設定内容については個人の好みや、ルールによると思います。
ここでは、上記設定内容で具体的に何を設定しているかの説明に留めます。

| Option    | 説明                                                 |
|:----------|:-----------------------------------------------------|
|endOfLine  |改行の文字コードを指定。今回は"LF"を指定。              |
|semi       |trueにすると文末に常にセミコロンを付ける                |
|singleQuote|trueにするとダブルクォートの代わりにシングルクォートを使用(JSX以外)  |
|jsxSingleQuote|falseにするとJSX内ではダブルクォートを使用する        |
|tabWidth   |インデントを行うときのSpaceの数を指定します              |
|trailingComma|末尾のカンマの扱い。ES5に準拠した設定でカンマを付ける   |
|printWidth  |折り返しの桁数を指定                                   |

全Optionの詳細は、Prettierの公式ドキュメントを参考にしてください。
参考：https://prettier.io/docs/en/options.html

合わせて、`.prettierignore`ファイルも作成します。
フォーマットをかけたくないファイルやフォルダを指定することができます。
記載の仕方は.gitignoreと同じです。
内容についても、特にこだわりがなければ.gitignoreと同じで良いのでは、と個人的には思います。

```rust:.prettierignore
# next.js build output
.next
out
# dotenv environment variables file (build for Zeit Now)
.env
.env.local
# Dependency directories
node_modules
# Logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*

```


### 4-2. Visual Studio Codeの設定

CLIでもPrettierでフォーマットをかけることができますが、Visual Studio Codeを使っているなら、拡張機能に追加しておくと便利です。

https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode

Prettierの拡張機能をVSCodeに追加した上で、設定を変更します。

```json
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.formatOnSave": true
```

- `Editor: Default Formatter`(デフォルトのフォーマッター)をPrettierに
- `Editor: Format On Save`(セーブするときにフォーマットするか)をtrueに

このように設定すると、ファイルを保存するときに自動的にPrettierでフォーマットをかけてくれます。


## 99. おわりに

この記事ではNext.jsにESLintとPrettierを導入する方法を解説しました。

なんとなくで開発を進めてきてしまっていた人こそ、ESLintやPrettierの力を借りることでさらなるレベルアップにつながるはずです。

---

:hatched_chick:[Twitter](https://twitter.com/sake_engineer)もやっています。

よかったらフォローお願いします。