# 機能設計書 97-ESLintプラグイン

## 概要

本ドキュメントは、Next.js固有のESLintプラグイン（`@next/eslint-plugin-next`）の設計について記述する。本プラグインは、Next.jsのベストプラクティスに基づいたLintルール群を提供し、一般的なミスやパフォーマンス問題をコーディング段階で検出する。

### 本機能の処理概要

**業務上の目的・背景**：Next.jsには独自の規約（next/image使用推奨、next/link使用推奨、_document.tsxでの制約等）が多く存在し、これらを手動で確認するのは困難である。ESLintプラグインはこれらの規約をルールとして自動チェックし、コード品質を向上させる。

**機能の利用シーン**：
- `next lint` コマンド実行時の自動チェック
- エディタのESLint統合によるリアルタイムフィードバック
- CI/CDパイプラインでのコード品質ゲート

**主要な処理内容**：
1. 21個のESLintルールの提供（warning 15個、error 6個）
2. `recommended` プリセット設定の提供
3. `core-web-vitals` プリセット設定の提供
4. レガシー設定形式（`recommended-legacy`, `core-web-vitals-legacy`）のサポート
5. フラット設定形式（ESLint 9+）のサポート

**関連システム・外部連携**：ESLint、`next lint` コマンド。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | ESLintプラグインは画面を持たないコード品質チェック機能 |

## 機能種別

バリデーション / 静的解析

## 入力仕様

### 入力パラメータ

各ルールはESLintのAST（抽象構文木）を入力として受け取る。

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| AST Node | ESTree Node | Yes | ESLintがパースしたJavaScript/TypeScript AST | - |
| context | Rule.RuleContext | Yes | ESLintルールコンテキスト | - |

### 入力データソース

プロジェクト内のJavaScript/TypeScriptソースファイル。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ESLint報告 | Lint Report | warning/errorレベルの違反レポート |

### 出力先

ESLint出力（ターミナル、エディタ統合）。

## 処理フロー

### 処理シーケンス

```
1. ESLintによるソースファイルのパース
   └─ AST（抽象構文木）の生成
2. 各ルールの適用
   └─ ASTノードの走査と違反チェック
3. レポートの生成
   └─ warning/errorの報告
```

### フローチャート

```mermaid
flowchart TD
    A[ソースファイル] --> B[ESLint パース]
    B --> C[AST生成]
    C --> D[ルール適用]
    D --> E{違反検出?}
    E -->|Yes| F[report: warning/error]
    E -->|No| G[パス]
```

## ビジネスルール

### 業務ルール

#### Warningルール（15個）

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | google-font-display | Google Fontsの`font-display`プロパティ設定チェック | link要素でのGoogle Fonts使用時 |
| BR-02 | google-font-preconnect | Google Fontsのpreconnect設定チェック | link要素でのGoogle Fonts使用時 |
| BR-03 | next-script-for-ga | Google Analytics用にnext/script推奨 | script要素でのGA使用時 |
| BR-04 | no-async-client-component | Client Componentでのasync禁止 | `use client`ファイル内 |
| BR-05 | no-before-interactive-script-outside-document | beforeInteractiveスクリプトは_documentでのみ使用 | Script component使用時 |
| BR-06 | no-css-tags | 手動CSSリンクタグの使用禁止 | link要素でのCSS読込時 |
| BR-07 | no-head-element | HTML head要素の直接使用禁止（next/head推奨） | head要素使用時 |
| BR-08 | no-html-link-for-pages | HTML a要素の使用禁止（next/link推奨） | a要素使用時 |
| BR-09 | no-img-element | HTML img要素の使用禁止（next/image推奨） | img要素使用時 |
| BR-10 | no-page-custom-font | ページ固有のカスタムフォント使用禁止 | pages内でのフォント読込時 |
| BR-11 | no-styled-jsx-in-document | _document内でのstyled-jsx使用禁止 | _document.tsx内 |
| BR-12 | no-sync-scripts | 同期スクリプトの使用禁止 | script要素使用時 |
| BR-13 | no-title-in-document-head | next/document Headでのtitle使用禁止 | Head component内 |
| BR-14 | no-typos | Next.js APIのタイプミス検出 | export定義時 |
| BR-15 | no-unwanted-polyfillio | 不要なpolyfill.ioの使用検出 | polyfill.io読込時 |

#### Errorルール（6個）

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-16 | inline-script-id | インラインnext/scriptにid属性必須 | Script component使用時 |
| BR-17 | no-assign-module-variable | module変数への代入禁止 | pages内 |
| BR-18 | no-document-import-in-page | ページ内でのnext/document import禁止 | pages内 |
| BR-19 | no-duplicate-head | 重複Headコンポーネント禁止 | Head component使用時 |
| BR-20 | no-head-import-in-document | _document内でのnext/head import禁止 | _document.tsx内 |
| BR-21 | no-script-component-in-head | HeadコンポーネントからのScript使用禁止 | Head component内 |

### 計算ロジック

特になし。

## データベース操作仕様

該当なし。

## エラー処理

### エラーケース一覧

ESLintルールのレポートとしてwarning/errorを出力する。プラグイン自体の実行時エラーはESLintフレームワークで処理される。

### リトライ仕様

該当なし。

## トランザクション仕様

該当なし。

## パフォーマンス要件

各ルールはAST走査ベースで動作するため、ファイルサイズに比例した処理時間となる。通常のプロジェクトでは性能上の問題は発生しない。

## セキュリティ考慮事項

ESLintルールはソースコードの静的解析のみを行い、実行や外部通信は行わない。

## 備考

- `core-web-vitals` プリセットは `recommended` を拡張し、`no-html-link-for-pages` と `no-sync-scripts` をerrorレベルに昇格
- ESLint 9のフラット設定形式（`recommended`, `core-web-vitals`）とレガシー形式（`recommended-legacy`, `core-web-vitals-legacy`）の両方をサポート

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/eslint-plugin-next/src/index.ts` | プラグインオブジェクトの構造（rules, configs）を理解する |

**読解のコツ**: ESLintプラグインはrules（ルール定義マップ）とconfigs（プリセット設定マップ）で構成される。`satisfies`型アサーションでTypeScript型安全性を確保している。

#### Step 2: プラグイン構成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/eslint-plugin-next/src/index.ts` | recommendedRules（25-49行目）とcoreWebVitalsRules（51-54行目）の定義 |

**主要処理フロー**:
1. **1-23行目**: 全21ルールモジュールのインポート
2. **25-49行目**: recommendedRulesオブジェクト - 15個のwarnと6個のerror
3. **51-54行目**: coreWebVitalsRulesオブジェクト - 2個のerror
4. **56-85行目**: pluginオブジェクトの構成
5. **94-121行目**: 4つの設定プリセット（recommended-legacy, core-web-vitals-legacy, recommended, core-web-vitals）

#### Step 3: 個別ルールの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | no-html-link-for-pages.ts | `packages/eslint-plugin-next/src/rules/no-html-link-for-pages.ts` | 代表的なルールの実装パターン |
| 3-2 | no-img-element.ts | `packages/eslint-plugin-next/src/rules/no-img-element.ts` | シンプルなルールの実装パターン |

### プログラム呼び出し階層図

```
ESLint CLI / next lint
    │
    └─ @next/eslint-plugin-next (index.ts)
           │
           ├─ configs.recommended
           │      └─ 21 rules (15 warn + 6 error)
           │
           ├─ configs.core-web-vitals
           │      └─ recommended + 2 upgraded to error
           │
           └─ rules
                  ├─ google-font-display
                  ├─ google-font-preconnect
                  ├─ inline-script-id
                  ├─ ... (18 more rules)
                  └─ no-unwanted-polyfillio
```

### データフロー図

```
[入力]                   [処理]                       [出力]

.js/.ts/.tsx ────▶ ESLint パーサー ──▶ AST ──▶ ルール適用 ──▶ Lint レポート
ソースファイル                                    │
                                                  └─ 各ルールが
                                                     ノードを検査
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/eslint-plugin-next/src/index.ts` | ソース | プラグインエントリ・設定プリセット定義 |
| define-rule.ts | `packages/eslint-plugin-next/src/utils/define-rule.ts` | ソース | ルール定義ヘルパー |
| node-attributes.ts | `packages/eslint-plugin-next/src/utils/node-attributes.ts` | ソース | ASTノード属性アクセスユーティリティ |
| url.ts | `packages/eslint-plugin-next/src/utils/url.ts` | ソース | URLユーティリティ |
| get-root-dirs.ts | `packages/eslint-plugin-next/src/utils/get-root-dirs.ts` | ソース | ルートディレクトリ取得 |
| no-html-link-for-pages.ts | `packages/eslint-plugin-next/src/rules/no-html-link-for-pages.ts` | ソース | HTMLリンク禁止ルール |
| no-img-element.ts | `packages/eslint-plugin-next/src/rules/no-img-element.ts` | ソース | img要素禁止ルール |
