# 通知設計書 35-babel not installed

## 概要

本ドキュメントは、CoffeeScriptコンパイラで`--transpile`オプション使用時にBabelがインストールされていない場合に発生するエラー通知「babel not installed」の設計仕様を記載する。

### 本通知の処理概要

CoffeeScriptのCLI（`coffee`コマンド）で`--transpile`オプションを使用してES2015+コードへのトランスパイルを要求した際、必要なBabelパッケージ（`@babel/core`または`babel-core`）がインストールされていない場合に、インストール方法を含むエラーメッセージを標準エラー出力に表示し、プロセスを終了コード1で終了する通知機能である。

**業務上の目的・背景**：CoffeeScriptはES2015+形式のJavaScriptを出力するが、古いブラウザやNode.jsバージョンとの互換性のためにBabelを使用したトランスパイルが必要になる場合がある。CoffeeScript自体はBabelに依存しないため、ユーザーが明示的にBabelをインストールする必要がある。このエラー通知により、ユーザーは必要なパッケージのインストール方法を理解できる。

**通知の送信タイミング**：`coffee --transpile`オプションが指定された際、`compileOptions`関数内で`require('@babel/core')`および`require('babel-core')`を試み、両方が失敗した時点で即座に通知される。

**通知の受信者**：コマンドラインでCoffeeScriptコンパイラを実行している開発者またはビルドシステム。標準エラー出力（stderr）に出力されるため、ターミナルまたはログ収集システムが受信者となる。

**通知内容の概要**：ローカルインストールとグローバルインストールの2つのケースに応じた異なるメッセージを出力する。いずれもBabelのインストールコマンドと設定ファイルの参照先URLを含む。

**期待されるアクション**：ユーザーはエラーメッセージに従って以下のいずれかの対応を行うことが期待される：
1. ローカルの場合: `npm install --save-dev @babel/core`を実行
2. グローバルの場合: `npm install --global @babel/core`を実行
3. Babel設定ファイル（`.babelrc`等）を作成

## 通知種別

コンソール出力（標準エラー出力）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高 |
| リトライ | 無し |

### 送信先決定ロジック

標準エラー出力（stderr）への直接出力のため、受信者決定ロジックは不要。コマンド実行元のターミナルまたはパイプ先に出力される。

## 通知テンプレート

### コンソール出力の場合

| 項目 | 内容 |
|-----|------|
| 出力先 | stderr（console.error） |
| 形式 | テキスト（複数行） |

### 本文テンプレート（ローカルインストールの場合）

```
To use --transpile, you must have @babel/core installed:
  npm install --save-dev @babel/core
And you must save options to configure Babel in one of the places it looks to find its options.
See https://coffeescript.org/#transpilation
```

### 本文テンプレート（グローバルインストールの場合）

```
To use --transpile with globally-installed CoffeeScript, you must have @babel/core installed globally:
  npm install --global @babel/core
And you must save options to configure Babel in one of the places it looks to find its options, relative to the file being compiled or to the current folder.
See https://coffeescript.org/#transpilation
```

### 添付ファイル

なし

## テンプレート変数

なし（インストール方法に応じた固定メッセージ）

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| CLI実行 | compileOptions関数内のrequire | @babel/coreとbabel-coreの両方が見つからない | Babel未インストール |

### インストール判定ロジック

| 条件 | 判定方法 | 出力メッセージ |
|-----|---------|--------------|
| ローカルインストール | `require.resolve('.').indexOf(process.cwd()) === 0` | ローカル用メッセージ |
| グローバルインストール | 上記がfalseの場合 | グローバル用メッセージ |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| @babel/coreが見つかる | 正常にBabelが読み込める場合 |
| babel-coreが見つかる | 旧バージョンのBabelが読み込める場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[coffee --transpile 実行] --> B[compileOptions関数呼び出し]
    B --> C{opts.transpile?}
    C -->|No| D[transpile = false]
    C -->|Yes| E[require @babel/core]
    E --> F{成功?}
    F -->|Yes| G[正常処理継続]
    F -->|No| H[require babel-core]
    H --> I{成功?}
    I -->|Yes| G
    I -->|No| J{ローカルインストール?}
    J -->|Yes| K[ローカル用エラーメッセージ]
    J -->|No| L[グローバル用エラーメッセージ]
    K --> M[process.exit 1]
    L --> M
```

## データベース参照・更新仕様

### 参照テーブル一覧

なし

### 更新テーブル一覧

なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| Babel未インストール | @babel/coreとbabel-coreの両方がrequireできない | インストール方法を表示して終了 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

なし（コマンド実行ごとに発生）

### 配信時間帯

制限なし

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

- 固定メッセージのため、機密情報の漏洩リスクはない
- プロセス終了コード1により、シェルスクリプトやCI/CDパイプラインでエラー検知が可能
- 参照URLはhttps://coffeescript.org/への公式ドキュメントリンク

## 備考

- `babel-core`は@babel/coreの旧パッケージ名で、Babel 6系との互換性のために試行される
- CoffeeScriptはBabelをオプショナル依存として扱い、package.jsonには含めていない
- `--transpile`オプションにオブジェクトを渡すことで、Babelオプションを直接指定することも可能

---

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

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

### 推奨読解順序

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

transpileオプションの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | command.coffee | `src/command.coffee` | SWITCHES配列（52行目: -t, --transpile）を確認 |

**読解のコツ**: transpileオプションはbooleanまたはオブジェクトとして扱われることを理解しておく。

#### Step 2: エントリーポイントを理解する

処理の起点となる関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | command.coffee | `src/command.coffee` | compileOptions関数（452-527行目）でtranspileオプション処理を確認 |

**主要処理フロー**:
1. **453行目**: `if opts.transpile`でtranspileオプションチェック
2. **460-464行目**: `require '@babel/core'`を試行
3. **463-464行目**: 失敗時に`require 'babel-core'`を試行
4. **466-482行目**: 両方失敗時にエラーメッセージを出力

#### Step 3: インストール判定処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | command.coffee | `src/command.coffee` | 468行目でインストール位置判定を確認 |

**主要処理フロー**:
- **468行目**: `require.resolve('.').indexOf(process.cwd()) is 0`でローカル判定
- **469-474行目**: ローカル用エラーメッセージ
- **476-481行目**: グローバル用エラーメッセージ
- **482行目**: `process.exit 1`

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

```
compileScript (command.coffee:202)
    │
    └─ compileOptions (command.coffee:452)
           │
           └─ [opts.transpile === true]
                  │
                  ├─ require('@babel/core') [try]
                  │      └─ [失敗]
                  │
                  ├─ require('babel-core') [try]
                  │      └─ [失敗]
                  │
                  └─ [両方失敗]
                         │
                         ├─ [ローカル] → console.error(ローカル用メッセージ)
                         │
                         └─ [グローバル] → console.error(グローバル用メッセージ)
                                │
                                └─ process.exit(1)
```

### データフロー図

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

opts.transpile ───▶ compileOptions()
                          │
                          ▼
               require('@babel/core')
                          │
              ┌───────────┴───────────┐
              │ 成功                  │ 失敗
              ▼                       ▼
         正常処理              require('babel-core')
                                      │
                          ┌───────────┴───────────┐
                          │ 成功                  │ 失敗
                          ▼                       ▼
                     正常処理              インストール位置判定
                                                  │
                                      ┌───────────┴───────────┐
                                      │ ローカル             │ グローバル
                                      ▼                       ▼
                                console.error()        console.error()
                                      │                       │
                                      └───────────┬───────────┘
                                                  ▼
                                            process.exit(1)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| command.coffee | `src/command.coffee` | ソース | CLIエントリーポイント、Babelインストールチェック |
| coffeescript.coffee | `src/coffeescript.coffee` | ソース | transpile関数の定義 |
