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

## はじめに

このガイドラインは、Babelのコードベースを効率的に理解するための手引きです。
TypeScript/JavaScriptに精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

**Babelとは:**
BabelはJavaScriptコンパイラです。最新のJavaScript構文で書かれたコードを、古いブラウザやNode.js環境でも動作する形式に変換します。

---

## 1. 言語基礎

> このセクションでは、TypeScript/JavaScriptの基本構文と概念を解説します。

### 1.1 プログラム構造

Babelプロジェクトは主にTypeScriptで書かれています。各ファイルはESモジュール形式で構成されています。

**実例: `packages/babel-core/src/index.ts:1-27`**
```typescript
export const version = process.env.BABEL_9_BREAKING
  ? PACKAGE_JSON.version + "999999999"
  : PACKAGE_JSON.version;

export { default as File } from "./transformation/file/file.ts";
export type { default as PluginPass } from "./transformation/plugin-pass.ts";
export { default as buildExternalHelpers } from "./tools/build-external-helpers.ts";

// eslint-disable-next-line import/no-unresolved, import/extensions
import * as resolvers from "#config/files";
// For backwards-compatibility, we expose the resolvers
// with the old API.
export const resolvePlugin = (name: string, dirname: string) =>
  resolvers.resolvePlugin(name, dirname, false).filepath;
export const resolvePreset = (name: string, dirname: string) =>
  resolvers.resolvePreset(name, dirname, false).filepath;

export { getEnv } from "./config/helpers/environment.ts";

// NOTE: Lazy re-exports aren't detected by the Node.js CJS-ESM interop.
export * as types from "@babel/types";
export { tokTypes } from "@babel/parser";
export { default as traverse } from "@babel/traverse";
export { default as template } from "@babel/template";
```

### 1.2 データ型と変数

BabelではTypeScriptの型システムを活用しています。主要な型定義パターンを以下に示します。

**実例: `packages/babel-generator/src/index.ts:124-215`**
```typescript
export interface GeneratorOptions {
  /**
   * Optional string to add as a block comment at the start of the output file.
   */
  auxiliaryCommentBefore?: string;

  /**
   * Optional string to add as a block comment at the end of the output file.
   */
  auxiliaryCommentAfter?: string;

  /**
   * Attempt to use the same line numbers in the output code as in the source code.
   * Defaults to `false`.
   */
  retainLines?: boolean;

  /**
   * Should comments be included in output? Defaults to `true`.
   */
  comments?: boolean;

  /**
   * Set to true to avoid adding whitespace for formatting.
   * Defaults to the value of `opts.minified`.
   */
  compact?: boolean | "auto";

  /**
   * Should the output be minified. Defaults to `false`.
   */
  minified?: boolean;
}

export interface GeneratorResult {
  code: string;
  map: EncodedSourceMap | null;
  decodedMap: DecodedSourceMap | undefined;
  rawMappings: Mapping[] | undefined;
}
```

### 1.3 制御構造

標準的なJavaScriptの制御構造に加え、ジェネレータ関数とイテレータパターンが多用されています。

**実例: `packages/babel-core/src/transformation/index.ts:36-81`**
```typescript
export function* run(
  config: ResolvedConfig,
  code: string,
  ast?: t.File | t.Program | null,
): Handler<FileResult> {
  const file = yield* normalizeFile(
    config.passes,
    normalizeOptions(config),
    code,
    ast,
  );

  const opts = file.opts;
  try {
    yield* transformFile(file, config.passes);
  } catch (e) {
    e.message = `${opts.filename ?? "unknown file"}: ${e.message}`;
    if (!e.code) {
      e.code = "BABEL_TRANSFORM_ERROR";
    }
    throw e;
  }

  let outputCode, outputMap;
  try {
    if (opts.code !== false) {
      ({ outputCode, outputMap } = generateCode(config.passes, file));
    }
  } catch (e) {
    e.message = `${opts.filename ?? "unknown file"}: ${e.message}`;
    if (!e.code) {
      e.code = "BABEL_GENERATE_ERROR";
    }
    throw e;
  }

  return {
    metadata: file.metadata,
    options: opts,
    ast: opts.ast === true ? file.ast : null,
    code: outputCode === undefined ? null : outputCode,
    map: outputMap === undefined ? null : outputMap,
    sourceType: file.ast.program.sourceType,
    externalDependencies: flattenToSet(config.externalDependencies),
  };
}
```

### 1.4 関数/メソッド定義

Babelでは関数型とオブジェクト指向の両方のパターンが使用されています。

**実例: `packages/babel-parser/src/index.ts:41-86`**
```typescript
/**
 * Parse the provided code as an entire ECMAScript program.
 */
export function parse(
  input: string,
  options?: ParserOptions,
): ParseResult<File> {
  if (options?.sourceType === "unambiguous") {
    options = {
      ...options,
    };
    try {
      options.sourceType = "module";
      const parser = getParser(options, input);
      const ast = parser.parse();

      if (parser.sawUnambiguousESM) {
        return ast;
      }

      if (parser.ambiguousScriptDifferentAst) {
        try {
          options.sourceType = "script";
          return getParser(options, input).parse();
        } catch {}
      } else {
        ast.program.sourceType = "script";
      }

      return ast;
    } catch (moduleError) {
      try {
        options.sourceType = "script";
        return getParser(options, input).parse();
      } catch {}

      throw moduleError;
    }
  } else {
    return getParser(options, input).parse();
  }
}
```

### 1.5 モジュール/インポート

ESモジュール形式を採用し、名前付きエクスポートとデフォルトエクスポートを使い分けています。

**実例: `packages/babel-traverse/src/index.ts:1-25`**
```typescript
import "./path/context.ts"; // We have some cycles, this ensures correct order
import * as visitors from "./visitors.ts";
import {
  VISITOR_KEYS,
  removeProperties,
  type RemovePropertiesOptions,
  traverseFast,
} from "@babel/types";
import type * as t from "@babel/types";
import * as cache from "./cache.ts";
import type NodePath from "./path/index.ts";
import type { default as Scope, Binding } from "./scope/index.ts";
import type { ExplodedVisitor, Visitor, VisitorBase } from "./types.ts";
import { traverseNode } from "./traverse-node.ts";

export type { ExplodedVisitor, Visitor, VisitorBase, Binding };
export { default as NodePath } from "./path/index.ts";
export { default as Scope, type BindingKind } from "./scope/index.ts";
export { default as Hub } from "./hub.ts";
export type { HubInterface } from "./hub.ts";
export type { VisitWrapper } from "./visitors.ts";

export { visitors };
```

---

## 2. プロジェクト固有の概念

> このセクションでは、当プロジェクト特有の概念を解説します。

### 2.1 コンパイラパイプライン

Babelのコンパイル処理は3つの主要フェーズで構成されています:

```
ソースコード → @babel/parser → AST → トランスフォーマー → AST → @babel/generator → 出力コード
```

1. **パース**: ソースコードをAST（抽象構文木）に変換
2. **トランスフォーム**: プラグインによるAST変換
3. **ジェネレート**: ASTからコードを生成

### 2.2 AST（抽象構文木）

BabelのASTはESTreeベースですが、いくつかの拡張があります。

**実例: ASTノードの構造**
```javascript
// 入力コード: const x = 1;
// AST構造:
{
  type: "VariableDeclaration",
  kind: "const",
  declarations: [{
    type: "VariableDeclarator",
    id: { type: "Identifier", name: "x" },
    init: { type: "NumericLiteral", value: 1 }
  }]
}
```

### 2.3 Visitorパターン

プラグインはVisitorパターンを使用してASTを走査・変換します。

**実例: `packages/babel-plugin-transform-arrow-functions/src/index.ts:1-30`**
```typescript
import { declare } from "@babel/helper-plugin-utils";

export interface Options {
  spec?: boolean;
}

export default declare((api, options: Options) => {
  api.assertVersion(REQUIRED_VERSION(7));

  const noNewArrows = api.assumption("noNewArrows") ?? !options.spec;

  return {
    name: "transform-arrow-functions",

    visitor: {
      ArrowFunctionExpression(path) {
        // In some conversion cases, it may have already been converted
        if (!path.isArrowFunctionExpression()) return;

        path.arrowFunctionToExpression({
          allowInsertArrow: false,
          noNewArrows,
        });
      },
    },
  };
});
```

### 2.4 NodePathとScope

NodePathはASTノードのラッパーで、ノードの操作やトラバーサルを容易にします。

**主要なNodePathメソッド:**

| メソッド | 説明 |
|---------|------|
| `replaceWith(node)` | ノードを別のノードに置換 |
| `remove()` | ノードを削除 |
| `insertBefore(nodes)` | ノードの前に挿入 |
| `insertAfter(nodes)` | ノードの後に挿入 |
| `traverse(visitor)` | サブツリーを走査 |
| `get(key)` | 子ノードのパスを取得 |
| `isXxx()` | 型チェック |

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| `babel-*` | パッケージディレクトリ | `babel-core`, `babel-parser` |
| `babel-plugin-*` | 変換プラグイン | `babel-plugin-transform-arrow-functions` |
| `babel-preset-*` | プリセット（プラグイン集） | `babel-preset-env` |
| `babel-helper-*` | ヘルパーユーティリティ | `babel-helper-plugin-utils` |
| `babel-plugin-syntax-*` | 構文プラグイン（パース有効化のみ） | `babel-plugin-syntax-jsx` |
| `babel-plugin-proposal-*` | 提案段階の機能プラグイン | `babel-plugin-proposal-decorators` |
| `babel-plugin-transform-*` | 標準変換プラグイン | `babel-plugin-transform-classes` |
| `babel-plugin-bugfix-*` | バグ修正プラグイン | `babel-plugin-bugfix-v8-spread-parameters` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| `is*` | 真偽値を返す関数 | `isIdentifier()`, `isExpression()` |
| `assert*` | アサーション関数 | `assertIdentifier()` |
| `get*` | ゲッター関数 | `getTypeAnnotation()` |
| `build*` | ビルダー関数 | `buildExternalHelpers()` |
| `*Visitor` | Visitorオブジェクト | `ClassVisitor` |
| `*Pass` | 変換パス | `PluginPass` |
| `*Options` | オプション型 | `GeneratorOptions` |
| `*Result` | 結果型 | `FileResult`, `GeneratorResult` |

### 3.3 プログラム分類一覧

| 分類 | プレフィックス | 役割 |
|-----|--------------|------|
| コアパッケージ | `@babel/core`, `@babel/parser`, `@babel/traverse`, `@babel/generator` | コンパイラの中核機能 |
| ユーティリティ | `@babel/types`, `@babel/template`, `@babel/code-frame` | AST操作・ユーティリティ |
| プラグイン | `@babel/plugin-*` | 個別の変換ロジック |
| プリセット | `@babel/preset-*` | プラグインのバンドル |
| ランタイム | `@babel/runtime` | 実行時ヘルパー |
| CLI | `@babel/cli`, `@babel/node` | コマンドラインツール |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
babel/
├── packages/                    # すべてのnpmパッケージ
│   ├── babel-core/             # コンパイラコア
│   │   ├── src/
│   │   │   ├── config/         # 設定ローダー
│   │   │   ├── transformation/ # 変換処理
│   │   │   └── index.ts        # エントリーポイント
│   │   └── test/
│   ├── babel-parser/           # JavaScriptパーサー
│   │   ├── src/
│   │   │   ├── parser/         # パーサー実装
│   │   │   ├── tokenizer/      # トークナイザー
│   │   │   └── plugins/        # パーサープラグイン
│   │   └── test/
│   ├── babel-traverse/         # AST走査
│   │   ├── src/
│   │   │   ├── path/           # NodePath実装
│   │   │   └── scope/          # スコープ分析
│   │   └── test/
│   ├── babel-generator/        # コード生成
│   ├── babel-types/            # AST型定義・ビルダー
│   ├── babel-plugin-*/         # 変換プラグイン
│   ├── babel-preset-*/         # プリセット
│   └── babel-helper-*/         # ヘルパーパッケージ
├── scripts/                    # ビルド・開発スクリプト
├── test/                       # 統合テスト
├── doc/                        # 設計ドキュメント
├── benchmark/                  # パフォーマンステスト
├── eslint/                     # ESLint設定・プラグイン
├── codemods/                   # コード変換ツール
├── Makefile                    # ビルドコマンド
├── babel.config.ts             # Babel自体の設定
└── package.json                # ルートパッケージ設定
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `packages/babel-core` | コンパイラの中核、transform API | `src/index.ts`, `src/transform.ts` |
| `packages/babel-parser` | ソースコードをASTに変換 | `src/index.ts`, `src/parser/` |
| `packages/babel-traverse` | ASTの走査と操作 | `src/index.ts`, `src/path/` |
| `packages/babel-generator` | ASTからコードを生成 | `src/index.ts`, `src/printer.ts` |
| `packages/babel-types` | AST型定義とユーティリティ | `src/index.ts`, `src/definitions/` |
| `packages/babel-plugin-*` | 個別の変換ロジック | `src/index.ts` |
| `packages/babel-preset-*` | プラグインのコレクション | `src/index.ts` |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

Babelはパイプラインアーキテクチャを採用し、各フェーズが独立したパッケージとして実装されています。

```mermaid
flowchart LR
    A[ソースコード] --> B[@babel/parser]
    B --> C[AST]
    C --> D[プラグイン群]
    D --> E[変換後AST]
    E --> F[@babel/generator]
    F --> G[出力コード]

    subgraph "@babel/core"
        B
        D
        F
    end
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| 設定レイヤー | babel.config.js解析、プラグイン解決 | `babel-core/src/config/` |
| パースレイヤー | ソースコードのトークン化とAST生成 | `babel-parser/src/` |
| 変換レイヤー | プラグインによるAST操作 | `babel-traverse/src/`, プラグイン |
| 生成レイヤー | ASTからコードへの変換 | `babel-generator/src/` |
| ユーティリティレイヤー | AST操作ヘルパー | `babel-types/src/` |

### 5.3 データフロー

1. **入力**: ソースコード + 設定オプション
2. **設定解決**: `@babel/core`が設定ファイルを読み込み、プラグイン・プリセットを解決
3. **パース**: `@babel/parser`がソースコードをASTに変換
4. **変換**: 各プラグインが順番にASTを変換（`@babel/traverse`を使用）
5. **生成**: `@babel/generator`が変換後ASTをコードに変換
6. **出力**: 変換されたコード + ソースマップ

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

**`@babel/core`の主要API (`packages/babel-core/src/index.ts`)**

```typescript
// 同期変換
export function transformSync(code: string, opts?: InputOptions): FileResult | null;

// 非同期変換
export function transformAsync(code: string, opts?: InputOptions): Promise<FileResult | null>;

// ファイル変換
export function transformFileSync(filename: string, opts?: InputOptions): FileResult | null;

// AST変換
export function transformFromAstSync(ast: t.File, code: string, opts?: InputOptions): FileResult | null;

// パース
export function parseSync(code: string, opts?: InputOptions): t.File | null;
```

### 6.2 ビジネスロジック

**変換処理 (`packages/babel-core/src/transformation/index.ts:83-133`)**

```typescript
function* transformFile(file: File, pluginPasses: PluginPasses): Handler<void> {
  const async = yield* isAsync();

  for (const pluginPairs of pluginPasses) {
    const passPairs: [Plugin, PluginPass][] = [];
    const passes = [];
    const visitors = [];

    for (const plugin of pluginPairs.concat([loadBlockHoistPlugin()])) {
      const pass = new PluginPass(file, plugin.key, plugin.options, async);

      passPairs.push([plugin, pass]);
      passes.push(pass);
      visitors.push(plugin.visitor!);
    }

    for (const [plugin, pass] of passPairs) {
      if (plugin.pre) {
        const fn = maybeAsync(plugin.pre, `...`);
        yield* fn.call(pass, file);
      }
    }

    // merge all plugin visitors into a single visitor
    const visitor = traverse.visitors.merge(
      visitors,
      passes,
      file.opts.wrapPluginVisitorMethod,
    );

    traverse(file.ast.program, visitor, file.scope, null, file.path, true);

    for (const [plugin, pass] of passPairs) {
      if (plugin.post) {
        const fn = maybeAsync(plugin.post, `...`);
        yield* fn.call(pass, file);
      }
    }
  }
}
```

### 6.3 データアクセス

**NodePath操作 (`packages/babel-traverse/src/path/index.ts`)**

NodePathは以下のモジュールで構成されています:

| モジュール | 機能 |
|-----------|------|
| `path/ancestry.ts` | 親ノード検索 (`findParent`, `getAncestry`) |
| `path/inference/` | 型推論 (`getTypeAnnotation`) |
| `path/replacement.ts` | ノード置換 (`replaceWith`, `replaceWithMultiple`) |
| `path/evaluation.ts` | 式評価 (`evaluate`, `evaluateTruthy`) |
| `path/conversion.ts` | 構造変換 (`arrowFunctionToExpression`) |
| `path/introspection.ts` | 検査 (`matchesPattern`, `isStatic`) |
| `path/removal.ts` | ノード削除 (`remove`) |
| `path/modification.ts` | ノード挿入 (`insertBefore`, `insertAfter`) |
| `path/family.ts` | 兄弟・子ノード取得 (`get`, `getSibling`) |

### 6.4 ユーティリティ/共通機能

**@babel/types (`packages/babel-types/src/index.ts`)**

```typescript
// ノードビルダー
t.identifier("name");
t.stringLiteral("value");
t.numericLiteral(42);
t.callExpression(callee, args);
t.memberExpression(object, property);

// 型チェック
t.isIdentifier(node);
t.isExpression(node);
t.isFunctionDeclaration(node);

// アサーション
t.assertIdentifier(node);

// ユーティリティ
t.cloneNode(node);
t.traverseFast(node, callback);
```

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| Visitorパターン | AST走査・変換 | 高 | すべてのプラグイン |
| Declarerパターン | プラグイン定義 | 高 | `babel-helper-plugin-utils` |
| ジェネレータパターン | 非同期処理の統一 | 中 | `babel-core/src/transformation/` |
| Mixinパターン | 機能の合成 | 中 | `babel-parser/src/` |
| Cacheパターン | パフォーマンス最適化 | 中 | `babel-traverse/src/cache.ts` |

### 各パターンの詳細

#### パターン1: Visitorパターン

**目的:** ASTノードを型別に処理する

**実装例:**
```typescript
// ファイル: packages/babel-plugin-transform-arrow-functions/src/index.ts
export default declare((api, options) => {
  return {
    name: "transform-arrow-functions",
    visitor: {
      ArrowFunctionExpression(path) {
        path.arrowFunctionToExpression({
          allowInsertArrow: false,
          noNewArrows,
        });
      },
    },
  };
});
```

**解説:** Visitorオブジェクトのキーはノードタイプ名で、値はそのノードを処理するコールバック関数です。`@babel/traverse`が自動的に該当するノードを探してコールバックを呼び出します。

#### パターン2: Declarerパターン

**目的:** プラグイン/プリセットのAPI互換性を保証する

**実装例:**
```typescript
// ファイル: packages/babel-helper-plugin-utils/src/index.ts
export function declare<Options = {}, Return = PluginObject<Options>>(
  builder: (api: BabelAPI, options: Options, dirname: string) => Return,
): (api: object, options: Options, dirname: string) => Return {
  return (api, options, dirname) => {
    let clonedApi: BabelAPI;

    for (const name of Object.keys(apiPolyfills) as (keyof typeof apiPolyfills)[]) {
      if (api[name]) continue;
      // ...polyfill logic
    }

    return builder(clonedApi || api, options, dirname);
  };
}
```

**解説:** `declare`関数はプラグインビルダーをラップし、APIバージョン間の互換性を提供します。

#### パターン3: ジェネレータパターン

**目的:** 同期/非同期処理を統一的に扱う

**実装例:**
```typescript
// ファイル: packages/babel-core/src/transform.ts
const transformRunner = gensync(function* transform(
  code: string,
  opts?: InputOptions | null,
): Handler<FileResult | null> {
  const config: ResolvedConfig | null = yield* loadConfig(opts);
  if (config === null) return null;
  return yield* run(config, code);
});

export const transformSync = transformRunner.sync;
export const transformAsync = transformRunner.async;
```

**解説:** `gensync`ライブラリを使用して、同一のジェネレータ関数から同期版と非同期版の両方のAPIを生成しています。

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定
2. 処理の流れを追跡（呼び出し関係を追う）
3. データの変換を確認
4. 最終的な出力を確認

### 8.2 フロー追跡の実例

#### 例1: transformSync処理フロー

**概要:** ソースコードを変換する基本的なフロー

**処理フロー:**
```
transformSync() → loadConfig() → run() → normalizeFile() → transformFile() → generateCode()
```

**詳細な追跡:**

1. **エントリーポイント** (`packages/babel-core/src/transform.ts:56-60`)
   ```typescript
   export function transformSync(
     ...args: Parameters<typeof transformRunner.sync>
   ) {
     return beginHiddenCallStack(transformRunner.sync)(...args);
   }
   ```

2. **設定読み込み** (`packages/babel-core/src/transform.ts:21-29`)
   ```typescript
   const transformRunner = gensync(function* transform(
     code: string,
     opts?: InputOptions | null,
   ): Handler<FileResult | null> {
     const config: ResolvedConfig | null = yield* loadConfig(opts);
     if (config === null) return null;
     return yield* run(config, code);
   });
   ```

3. **変換実行** (`packages/babel-core/src/transformation/index.ts:36-46`)
   ```typescript
   export function* run(
     config: ResolvedConfig,
     code: string,
     ast?: t.File | t.Program | null,
   ): Handler<FileResult> {
     const file = yield* normalizeFile(
       config.passes,
       normalizeOptions(config),
       code,
       ast,
     );
     // ...
   }
   ```

4. **プラグイン適用** (`packages/babel-core/src/transformation/index.ts:119`)
   ```typescript
   traverse(file.ast.program, visitor, file.scope, null, file.path, true);
   ```

5. **コード生成** (`packages/babel-core/src/transformation/index.ts:61-63`)
   ```typescript
   if (opts.code !== false) {
     ({ outputCode, outputMap } = generateCode(config.passes, file));
   }
   ```

#### 例2: プラグイン適用フロー

**概要:** アロー関数を通常の関数に変換するプラグインの動作

**処理フロー:**
```
ArrowFunctionExpression訪問 → isArrowFunctionExpression()チェック → arrowFunctionToExpression()
```

**詳細な追跡:**

1. **Visitor登録** (`packages/babel-plugin-transform-arrow-functions/src/index.ts:15-27`)
   ```typescript
   visitor: {
     ArrowFunctionExpression(path) {
       if (!path.isArrowFunctionExpression()) return;
       path.arrowFunctionToExpression({
         allowInsertArrow: false,
         noNewArrows,
       });
     },
   },
   ```

2. **ノード変換** (`packages/babel-traverse/src/path/conversion.ts`)
   ```typescript
   arrowFunctionToExpression(options): NodePath<t.FunctionExpression | t.CallExpression> {
     // アロー関数を通常の関数式に変換
     // this/argumentsのバインディングを処理
   }
   ```

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイントを特定したか
- [ ] 呼び出し関係を把握したか
- [ ] データの変換ポイントを確認したか
- [ ] エラーハンドリングを確認したか
- [ ] 最終的な出力を確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. `README.md` - プロジェクト概要
2. `packages/README.md` - パッケージ構成とコンパイラフロー
3. `doc/design/monorepo.md` - モノレポ設計の理由
4. `CONTRIBUTING.md` - 開発環境とアーキテクチャ概要

#### 特定機能を理解したい場合
1. 対象パッケージの`README.md`
2. 対象パッケージの`src/index.ts`
3. テストフィクスチャ（`test/fixtures/`）
4. 関連ヘルパーパッケージ

#### プラグイン開発を行う場合
1. [Babel Plugin Handbook](https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md)
2. 既存プラグインの`src/index.ts`（例: `babel-plugin-transform-arrow-functions`）
3. `@babel/types`のビルダー・バリデーター
4. AST Explorer（http://astexplorer.net/）

#### 改修作業を行う場合
1. 対象パッケージの設計書
2. 関連テストケース
3. `CHANGELOG.md`で過去の変更履歴を確認
4. GitHub Issues/PRで議論を確認

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| `README.md` | プロジェクト概要 | 最初に読む |
| `packages/README.md` | パッケージ構成 | アーキテクチャ理解時 |
| `CONTRIBUTING.md` | 開発ガイド | 開発環境構築時 |
| `doc/design/monorepo.md` | モノレポ設計 | 構造理解時 |
| `doc/design/versioning.md` | バージョニング方針 | リリース作業時 |
| `packages/babel-parser/ast/spec.md` | AST仕様 | パーサー/プラグイン開発時 |
| `CHANGELOG.md` | 変更履歴 | 変更影響調査時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: `yield*`は何をしているのですか？
A: `gensync`ライブラリのパターンで、ジェネレータ関数間で制御を委譲しています。これにより同期/非同期の両方のAPIを単一の実装から生成できます。参照: `packages/babel-core/src/gensync-utils/`

#### Q: `REQUIRED_VERSION(7)`とは？
A: コンパイル時に置換されるマクロで、Babelのメジャーバージョンに応じたチェックを行います。Babel 7/8の互換性維持に使用されています。

#### Q: なぜ`#config/files`のようなインポートがあるのですか？
A: Node.jsのsubpath importsパターンです。`package.json`の`imports`フィールドで定義され、環境（ブラウザ/Node.js）に応じて異なるファイルを読み込みます。

#### Q: Visitorの`enter`と`exit`の違いは？
A: `enter`はノードに入る時、`exit`はノードから出る時に呼ばれます。省略時は`enter`として扱われます。
```typescript
visitor: {
  FunctionDeclaration: {
    enter(path) { /* 子ノード処理前 */ },
    exit(path) { /* 子ノード処理後 */ }
  }
}
```

#### Q: `path.skip()`と`path.stop()`の違いは？
A: `skip()`は現在のノードの子ノードをスキップし、`stop()`は走査全体を停止します。

### デバッグのヒント

1. **AST確認**: https://astexplorer.net/ でASTを可視化
2. **ブレークポイント**: `debugger;`を挿入し、`TEST_DEBUG=true`でテスト実行
3. **ログ出力**: `path.toString()`でノードのコード表現を確認
4. **型確認**: `console.log(path.node.type)`でノードタイプを確認

```bash
# デバッグモードでテスト実行
$ TEST_DEBUG=true yarn jest babel-plugin-transform-classes -t "specific test"
```

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| AST | Abstract Syntax Tree（抽象構文木）。ソースコードの構造を木構造で表現したもの |
| Visitor | ASTを走査する際のノードタイプ別処理を定義するオブジェクト |
| NodePath | ASTノードのラッパー。コンテキスト情報とノード操作メソッドを提供 |
| Scope | 変数のスコープ情報を管理するオブジェクト |
| Binding | 変数束縛。変数の宣言とその参照を追跡 |
| Plugin | 特定の変換ロジックを実装するモジュール |
| Preset | プラグインの集合。設定を簡略化 |
| Polyfill | 新しいAPIを古い環境で動作させるためのコード |
| Transform | ソースコードを別の形式に変換する処理 |
| Parse | ソースコードをASTに変換する処理 |
| Generate | ASTをソースコードに変換する処理 |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `packages/babel-core/src/index.ts` | @babel/coreエントリーポイント | 公開API定義 |
| `packages/babel-parser/src/index.ts` | パーサーエントリーポイント | parse(), parseExpression() |
| `packages/babel-traverse/src/index.ts` | トラバーサルエントリーポイント | traverse()関数 |
| `packages/babel-generator/src/index.ts` | ジェネレータエントリーポイント | generate()関数 |
| `packages/babel-types/src/index.ts` | 型ユーティリティ | ビルダー、バリデーター |
| `packages/babel-core/src/transformation/` | 変換処理 | プラグイン適用ロジック |
| `packages/babel-traverse/src/path/` | NodePath実装 | ノード操作メソッド |
| `packages/babel-parser/src/parser/` | パーサー実装 | 構文解析ロジック |

### C. 参考資料

- [Babel公式ドキュメント](https://babeljs.io/)
- [Babel Plugin Handbook](https://github.com/thejameskyle/babel-handbook/blob/master/translations/en/plugin-handbook.md)
- [AST Explorer](https://astexplorer.net/)
- [ESTree仕様](https://github.com/estree/estree)
- [Babel AST仕様](https://github.com/babel/babel/blob/main/packages/babel-parser/ast/spec.md)
- [TypeScript公式ドキュメント](https://www.typescriptlang.org/docs/)
