ここでは、とにかく混乱しがちな ESLint + Prettier の設定方法をまとめておきます。 まず、基本的な構成として、TypeScript (with React) の Lint をかけられるようにして、必要に応じて Airbnb スタイル を追加で設定する、という流れにしたいと思います。
TypeScript プロジェクトの準備
前提条件として、TypeScript (+ React) のプロジェクト自体は作成済みとします。
何も準備できていなければ、Next.js の create-next-app コマンドを使うと簡単に作成できます(typescript および @types/node、@types/react、@types/react-dom などの型情報が導入された状態のプロジェクトが作成されます)。
# テンプレートを使う方法
$ create-next-app myapp --example with-typescript
# typescript オプションを使う方法
$ create-next-app myapp --typescriptPrettier + ESLint の基本設定 (for TypeScript with React)
# Prettier 本体
$ yarn add --dev --exact prettier
# ESLint 本体
$ yarn add --dev eslint
# ESLint 用のプラグインおよび共有設定
$ yarn add --dev @typescript-eslint/eslint-plugin
$ yarn add --dev @typescript-eslint/parser
$ yarn add --dev eslint-plugin-react
$ yarn add --dev eslint-plugin-react-hooks
$ yarn add --dev eslint-config-prettier
# npm スクリプトの並列実行用
$ yarn add --dev npm-run-all# Prettier 本体
$ npm install prettier --save-dev --save-exact
# ESLint 本体
$ npm install eslint --save-dev
# ESLint 用のプラグインおよび共有設定
$ npm install @typescript-eslint/eslint-plugin --save-dev
$ npm install @typescript-eslint/parser --save-dev
$ npm install eslint-plugin-react --save-dev
$ npm install eslint-plugin-react-hooks --save-dev
$ npm install eslint-config-prettier --save-dev
# npm スクリプトの並列実行用
$ npm install npm-run-all --save-devsemi: false # 行末のセミコロンは省略する
singleQuote: true # 引用符にはシングルクォートを使う.next/
build/
*.htmlroot: true
env:
  browser: true
  es2021: true
extends:
  - eslint:recommended
  - plugin:react/recommended
  - plugin:react-hooks/recommended
  - plugin:@typescript-eslint/recommended
  - plugin:@typescript-eslint/recommended-requiring-type-checking
  - prettier
parser: "@typescript-eslint/parser"
parserOptions:
  ecmaVersion: 12
  ecmaFeatures:
    jsx: true
  project: ./tsconfig.json
plugins:
  - react
  - react-hooks
  - "@typescript-eslint"
rules:
  react/react-in-jsx-scope: off// ...
  scripts: {
    "lint": "run-p -c -l lint:**",
    "lint:prettier": "prettier --check .",
    "lint:eslint": "eslint . --ext .ts,.tsx",
    "lint:tsc": "tsc",
    "fix": "run-s -l fix:**",
    "fix:prettier": "prettier --write .",
    "fix:eslint": "eslint . --ext .ts,.tsx --fix",これで、次のようにして Prettier + ESLint による Lint チェックと自動修正をかけられるようになります。
# yarn の場合
$ yarn lint  # Lint チェック
$ yarn fix   # 自動修正
# npm の場合
$ npm run lint  # Lint チェック
$ npm run fix   # 自動修正fix を実行すると多数のファイルが自動修正されることになるので、lint が実行できた段階で、一度 Git へ設定をコミットしておくことをオススメします。
ts/tsx ファイルを src ディレクトリにまとめる
Next.js 9.1 からは、pages ディレクトリを src/pages というパスで作成できるようになりました。
next コマンドは、プロジェクトのルートに pages が見つからないとき、src/pages を参照してくれます。
この仕組みを利用すると、.ts、.tsx ファイルは全て src ディレクトリ以下にまとめられるので、プロジェクトのルートディレクトリがスッキリします。
ただし、tsconfig.json や public ディレクトリは、これまで通りルートディレクトリに配置する必要があります。
$ mkdir src
$ git mv components src
$ git mv interfaces src
$ git mv pages src
$ git mv utils srcあとは、各種コマンドの対象パスなどを変更すれば OK です。
   "scripts": {
     "lint": "run-p -c -l lint:**",
-    "lint:prettier": "prettier --check .",
-    "lint:eslint": "eslint . --ext .ts,.tsx",
+    "lint:prettier": "prettier --check src",
+    "lint:eslint": "eslint src --ext .ts,.tsx",
     "lint:tsc": "tsc",
     "fix": "run-s -l fix:**",
-    "fix:prettier": "prettier --write .",
-    "fix:eslint": "eslint . --ext .ts,.tsx --fix",
+    "fix:prettier": "prettier --write src",
+    "fix:eslint": "eslint src --ext .ts,.tsx --fix",
     "target": "esnext"
   },
   "exclude": ["node_modules"],
-  "include": ["**/*.ts", "**/*.tsx"]
+  "include": ["src/**/*.ts", "src/**/*.tsx"]
 }
ここまでの結果をテンプレートにする
ここで作成したプロジェクトを GitHub にプッシュしておけば、create-next-app コマンドのテンプレートとして使用できるようになります。
次のように、--example オプションで GitHub リポジトリの URL を指定するだけで OK です。
$ create-next-app myapp --example \
  https://github.com/maku77/template-nextjs-ts-eslint-prettierAirbnb スタイルを追加導入する
JavaScript のコーディングスタイルとしては、Airbnb のスタイルが有名です。 ここでは、前述の基本的な ESLint + Prettier 設定が終わっている想定で、追加で Airbnb スタイルを導入してみます。
Airbnb は ESLint 用の eslint-config-airbnb 共有設定を用意しているのですが、これをそのまま使うと TypeScript 用のカスタマイズが厄介なので、最初から TypeScript 用の対応が入った eslint-config-airbnb-typescript を使うことにします。
公式サイトを見ると、eslint-config-airbnb-typescript の依存パッケージとして下記が必要ということが分かるので、まだインストールしていないものを追加でインストールします。
- eslint-plugin-import
- eslint-plugin-jsx-a11y
- eslint-plugin-react (インストール済み)
- eslint-plugin-react-hooks (インストール済み)
- @typescript-eslint/eslint-plugin (インストール済み)
$ yarn add --dev eslint-config-airbnb-typescript
$ yarn add --dev eslint-plugin-import
$ yarn add --dev eslint-plugin-jsx-a11y$ npm install eslint-config-airbnb-typescript --save-dev
$ npm install eslint-plugin-import --save-dev
$ npm install eslint-plugin-jsx-a11y --save-devroot: true
env:
  browser: true
  es2021: true
extends:
  - airbnb-typescript
  - prettier
parser: "@typescript-eslint/parser"
parserOptions:
  ecmaFeatures:
    jsx: true
  ecmaVersion: 12
  project: ./tsconfig.json
plugins:
  - react
  - "@typescript-eslint"
rules:
  react/react-in-jsx-scope: off  # JSX 用の React インポートエラー抑制実行方法はこれまで通りで変化なしです(npm run lint と npm run fix)。
ESLint と Prettier の設定で気を付けること
ESLint および Prettier の設定のポイントや、ハマりがちなことをまとめておきます。
TypeScript 型情報のチェックを ESLint で行う
@typescript-eslint/eslint-plugin プラグインが提供する recommended-requiring-type-checking という共有設定を有効にすると、TypeScript の型情報を利用した Lint チェックを行うことができます。
このとき、内部では TypeScript コンパイラが使用されるため、parserOptions.project で tsconfig.json ファイルの位置を知らせてやる必要があります(指定しないとエラーになります)。
root: true
parser: '@typescript-eslint/parser'
parserOptions:
  ecmaVersion: 2021
  project: ./tsconfig.json  # ★型チェックに必要
plugins:
  - '@typescript-eslint'
extends:
  - eslint:recommended
  - plugin:@typescript-eslint/recommended
  - plugin:@typescript-eslint/recommended-requiring-type-checking  # ★型チェックTypeScript の型チェックを行うよう設定すると、追加で TypeScript コンパイラが動作するようになるため、ESLint の実行に時間がかかるようになります。
tsconfig.json の情報をそのまま使うのではなく、ESLint 用に tsconfig.eslint.json を作成してパフォーマンス向上させる方法が提案されています。
いずれにしても、型チェックの仕組みはあまり洗練されているとは言えないので、型チェックに関しては TypeScript コードの tsc ビルド時にだけ行うと割り切ってもいいかもしれません(VS Code デフォルトの検出機能もあります)。
TypeScript / Prettier の設定は後ろへ
plugin:
  - react
  - @typescript-eslint
extends:
  - eslint:recommended
  - plugin:react/recommended
  - plugin:@typescript-eslint/recommended
  - plugin:@typescript-eslint/recommended-requiring-type-checkingTypeScript 用の共有設定 plugin:@typescript-eslint/recommended は、eslint:recommended などにより定義されるルールのうち、TypeScript と競合するものを解決してくれます。
なので、TypeScript に関する設定は extends の中で最後の方に指定して設定を上書きする必要があります。
具体的には、plugin:@typescript-eslint/eslint-recommended がこの競合を解決するものであり、plugin:@typescript-eslint/recommended から利用されています。
同様に、コードフォーマッターの Prettier を使用する場合は、Prettier が自動修正してくれる部分を ESLint が指摘しないように、一番最後に eslint-config-prettier 関連の共有設定を指定する必要があります。
extends:
  - eslint:recommended
  - plugin:react/recommended
  - plugin:@typescript-eslint/recommended
  - plugin:@typescript-eslint/recommended-requiring-type-checking
  - prettierAirbnb スタイルは React 込み
  extends:
-   - eslint:recommended
-   - plugin:react/recommended
+   - airbnb
+   - airbnb/hooks
extends プロパティで airbnb (eslint-config-airbnb) を指定する場合、eslint:recommended や plugin:react/recommeded の設定は airbnb 側でほぼカバーされるので、指定する必要はありません。
逆に、React を使わない場合は、eslint-config-airbnb ではなく eslint-config-airbnb-base の方を使います。
eslint-config-airbnb が依存するパッケージを調べる
.eslintrc.* ファイルの extends プロパティで airbnb を指定するには、あらかじめ eslint-config-airbnb パッケージをインストールするだけでなく、その依存パッケージ (peerDependencies) もインストールしておく必要があります。
依存パッケージは次のように確認することができます。
$ npm info "eslint-config-airbnb@latest" peerDependencies
{
  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': '^7.21.5',
  'eslint-plugin-react-hooks': '^4 || ^3 || ^2.3.0 || ^1.7.0'
}