# API設計書

## 概要

本ドキュメントは、Babel (JavaScriptコンパイラ/トランスパイラ) のプログラムAPI設計書です。Babelは、最新のJavaScript構文を古いブラウザや環境で動作するコードに変換するためのツールチェインです。

BabelはREST APIではなく、Node.js環境で使用するプログラムAPI（関数ベースのAPI）を提供しています。主要なパッケージとして以下があります:

- **@babel/core**: コアトランスフォーメーションAPI
- **@babel/parser**: JavaScriptパーサー
- **@babel/generator**: AST (抽象構文木) からコードを生成
- **@babel/traverse**: AST走査
- **@babel/types**: AST型定義とユーティリティ
- **@babel/template**: テンプレートリテラルからASTを生成

## 共通仕様

### インストール

```bash
npm install @babel/core
```

### 基本的な使用方法

```javascript
import * as babel from "@babel/core";

// 同期的な変換
const result = babel.transformSync("const fn = () => {};", {
  presets: ["@babel/preset-env"]
});
console.log(result.code);
```

### 共通の型定義

#### InputOptions

Babelのすべての変換関数で使用されるオプションオブジェクトです。

| オプション名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| filename | string | - | 処理対象ファイルのパス |
| cwd | string | - | 作業ディレクトリ（デフォルト: process.cwd()） |
| root | string | - | プロジェクトルートディレクトリ |
| rootMode | "root" \| "upward" \| "upward-optional" | - | ルート検索モード |
| envName | string | - | 環境名（デフォルト: process.env.BABEL_ENV または NODE_ENV） |
| configFile | string \| boolean | - | 設定ファイルのパス |
| babelrc | boolean | - | .babelrcファイルを読み込むかどうか |
| presets | PresetItem[] | - | 使用するプリセット |
| plugins | PluginItem[] | - | 使用するプラグイン |
| sourceType | "module" \| "commonjs" \| "script" \| "unambiguous" | - | ソースタイプ |
| sourceMaps | boolean \| "inline" \| "both" | - | ソースマップ生成 |
| code | boolean | - | コードを出力するか（デフォルト: true） |
| ast | boolean | - | ASTを出力するか（デフォルト: false） |
| comments | boolean | - | コメントを保持するか |
| compact | boolean \| "auto" | - | 出力を圧縮するか |
| minified | boolean | - | 最小化出力 |
| retainLines | boolean | - | 行番号を維持 |
| targets | string \| object | - | ターゲット環境 |
| assumptions | object | - | コード変換の仮定 |

#### FileResult

変換結果を表すオブジェクトです。

| プロパティ名 | 型 | 説明 |
| --- | --- | --- |
| code | string \| null | 変換後のコード |
| map | object \| null | ソースマップ |
| ast | t.File \| null | 変換後のAST（options.ast = trueの場合） |
| metadata | object | プラグインから追加されたメタデータ |
| options | object | 使用されたオプション |
| sourceType | "module" \| "commonjs" \| "script" | 検出されたソースタイプ |
| externalDependencies | Set<string> | 外部依存ファイル |

### 共通エラー

| エラーコード | 説明 |
| --- | --- |
| BABEL_UNKNOWN_OPTION | 不明なオプションが指定された |
| BABEL_TRANSFORM_ERROR | 変換中にエラーが発生 |
| BABEL_GENERATE_ERROR | コード生成中にエラーが発生 |

## API一覧

| カテゴリ | API名 | 説明 |
| --- | --- | --- |
| Transform | transformSync | コードを同期的に変換 |
| Transform | transformAsync | コードを非同期に変換 |
| Transform | transform | コードを変換（コールバック形式） |
| Transform | transformFileSync | ファイルを同期的に変換 |
| Transform | transformFileAsync | ファイルを非同期に変換 |
| Transform | transformFile | ファイルを変換（コールバック形式） |
| Transform | transformFromAstSync | ASTから同期的に変換 |
| Transform | transformFromAstAsync | ASTから非同期に変換 |
| Transform | transformFromAst | ASTから変換（コールバック形式） |
| Parse | parseSync | コードを同期的にパース |
| Parse | parseAsync | コードを非同期にパース |
| Parse | parse | コードをパース（コールバック形式） |
| Config | loadOptionsSync | オプションを同期的に読み込み |
| Config | loadOptionsAsync | オプションを非同期に読み込み |
| Config | loadPartialConfigSync | 部分設定を同期的に読み込み |
| Config | loadPartialConfigAsync | 部分設定を非同期に読み込み |
| Config | createConfigItemSync | 設定アイテムを同期的に作成 |
| Config | createConfigItemAsync | 設定アイテムを非同期に作成 |
| Utility | buildExternalHelpers | 外部ヘルパーコードを生成 |
| Utility | resolvePlugin | プラグインを解決 |
| Utility | resolvePreset | プリセットを解決 |
| Parser | parse（@babel/parser） | コードをASTにパース |
| Parser | parseExpression（@babel/parser） | 式をASTにパース |
| Generator | generate（@babel/generator） | ASTからコードを生成 |
| Traverse | traverse（@babel/traverse） | ASTを走査 |

## 各APIエンドポイント定義

### Transform API

#### 1 transformSync

コード文字列を同期的にトランスフォームします。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { transformSync } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| code | string | ○ | 変換対象のソースコード |
| options | InputOptions | - | 変換オプション |

**戻り値**

```typescript
FileResult | null
```

**使用例**

```javascript
import { transformSync } from "@babel/core";

const result = transformSync("const fn = () => {};", {
  presets: ["@babel/preset-env"],
  filename: "example.js"
});

console.log(result.code);
// 出力: "var fn = function () {};"
```

**エラー**

| 条件 | エラー |
| --- | --- |
| 構文エラー | SyntaxError |
| 設定エラー | ConfigError |
| 変換エラー | Error (code: BABEL_TRANSFORM_ERROR) |

---

#### 2 transformAsync

コード文字列を非同期にトランスフォームします。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { transformAsync } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| code | string | ○ | 変換対象のソースコード |
| options | InputOptions | - | 変換オプション |

**戻り値**

```typescript
Promise<FileResult | null>
```

**使用例**

```javascript
import { transformAsync } from "@babel/core";

const result = await transformAsync("const fn = () => {};", {
  presets: ["@babel/preset-env"]
});

console.log(result.code);
```

---

#### 3 transform

コード文字列をコールバック形式でトランスフォームします。Babel 8.0.0以降ではコールバックが必須です。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { transform } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| code | string | ○ | 変換対象のソースコード |
| options | InputOptions | - | 変換オプション |
| callback | FileResultCallback | ○ | 結果を受け取るコールバック |

**使用例**

```javascript
import { transform } from "@babel/core";

transform("const fn = () => {};", { presets: ["@babel/preset-env"] }, (err, result) => {
  if (err) {
    console.error(err);
    return;
  }
  console.log(result.code);
});
```

---

#### 4 transformFileSync

ファイルを同期的に読み込んでトランスフォームします。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { transformFileSync } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| filename | string | ○ | 変換対象ファイルのパス |
| options | InputOptions | - | 変換オプション |

**戻り値**

```typescript
FileResult | null
```

**使用例**

```javascript
import { transformFileSync } from "@babel/core";

const result = transformFileSync("./src/app.js", {
  presets: ["@babel/preset-env"]
});

console.log(result.code);
```

---

#### 5 transformFileAsync

ファイルを非同期に読み込んでトランスフォームします。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { transformFileAsync } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| filename | string | ○ | 変換対象ファイルのパス |
| options | InputOptions | - | 変換オプション |

**戻り値**

```typescript
Promise<FileResult | null>
```

---

#### 6 transformFromAstSync

既存のASTからコードを同期的にトランスフォームします。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { transformFromAstSync } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| ast | t.File \| t.Program | ○ | 変換対象のAST |
| code | string | ○ | 元のソースコード（ソースマップ用） |
| options | InputOptions | - | 変換オプション |

**戻り値**

```typescript
FileResult | null
```

**使用例**

```javascript
import { parseSync, transformFromAstSync } from "@babel/core";

const ast = parseSync("const fn = () => {};");
const result = transformFromAstSync(ast, "const fn = () => {};", {
  presets: ["@babel/preset-env"]
});

console.log(result.code);
```

---

### Parse API

#### 7 parseSync

コード文字列を同期的にパースしてASTを取得します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { parseSync } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| code | string | ○ | パース対象のソースコード |
| options | InputOptions | - | パースオプション |

**戻り値**

```typescript
ParseResult | null
```

ParseResultはt.Fileにcomments、errors、tokensプロパティを追加したものです。

**使用例**

```javascript
import { parseSync } from "@babel/core";

const ast = parseSync("const x = 1;", {
  sourceType: "module"
});

console.log(ast.program.body[0].type); // "VariableDeclaration"
```

---

#### 8 parseAsync

コード文字列を非同期にパースしてASTを取得します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { parseAsync } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| code | string | ○ | パース対象のソースコード |
| options | InputOptions | - | パースオプション |

**戻り値**

```typescript
Promise<ParseResult | null>
```

---

### Config API

#### 9 loadOptionsSync

設定ファイルとプログラムオプションをマージして、最終的な設定を同期的に読み込みます。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { loadOptionsSync } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| options | InputOptions | - | 入力オプション |

**戻り値**

```typescript
ResolvedOptions | null
```

---

#### 10 loadPartialConfigSync

部分的な設定情報を同期的に読み込みます。プラグインやプリセットの解決前の状態を取得できます。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { loadPartialConfigSync } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| options | InputOptions | - | 入力オプション |

**戻り値**

```typescript
PartialConfig | null
```

PartialConfigには以下のプロパティが含まれます:
- `options`: マージされたオプション
- `babelrc`: 検出された.babelrcのパス
- `babelignore`: 検出された.babelignoreのパス
- `config`: 検出されたbabel.config.jsのパス

---

#### 11 createConfigItemSync

設定アイテム（プラグインまたはプリセット）を同期的に作成します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { createConfigItemSync } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| value | PluginItem \| PresetItem | ○ | プラグイン/プリセットの指定 |
| options | object | - | オプション |
| options.dirname | string | - | 相対パスの基準ディレクトリ |
| options.type | "preset" \| "plugin" | - | アイテムの種類 |

**戻り値**

```typescript
ConfigItem
```

ConfigItemには以下のプロパティが含まれます:
- `value`: プラグイン/プリセット関数
- `options`: 渡されたオプション
- `dirname`: オプションの基準ディレクトリ
- `name`: アイテム名
- `file`: ファイル情報（request, resolved）

**使用例**

```javascript
import { createConfigItemSync, transformSync } from "@babel/core";

const preset = createConfigItemSync(
  ["@babel/preset-env", { targets: "> 0.25%" }],
  { type: "preset" }
);

const result = transformSync("const x = 1;", {
  presets: [preset]
});
```

---

### Utility API

#### 12 buildExternalHelpers

Babelヘルパー関数のコードを生成します。複数のファイルで共有するヘルパーを事前生成する場合に使用します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { buildExternalHelpers } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| allowlist | string[] | - | 生成するヘルパーのリスト（省略時は全ヘルパー） |
| outputType | "global" \| "module" \| "umd" \| "var" | - | 出力形式（デフォルト: "global"） |

**戻り値**

```typescript
string
```

**使用例**

```javascript
import { buildExternalHelpers } from "@babel/core";

// UMD形式で特定のヘルパーのみ生成
const code = buildExternalHelpers(
  ["classCallCheck", "createClass"],
  "umd"
);

console.log(code);
```

---

#### 13 resolvePlugin

プラグイン名をファイルパスに解決します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { resolvePlugin } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| name | string | ○ | プラグイン名 |
| dirname | string | ○ | 基準ディレクトリ |

**戻り値**

```typescript
string
```

---

#### 14 resolvePreset

プリセット名をファイルパスに解決します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/core |
| モジュール | `import { resolvePreset } from "@babel/core"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| name | string | ○ | プリセット名 |
| dirname | string | ○ | 基準ディレクトリ |

**戻り値**

```typescript
string
```

---

### @babel/parser API

#### 15 parse

ソースコードをパースしてASTを生成します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/parser |
| モジュール | `import { parse } from "@babel/parser"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| input | string | ○ | パース対象のソースコード |
| options | ParserOptions | - | パースオプション |

**ParserOptions**

| オプション名 | 型 | 説明 |
| --- | --- | --- |
| sourceType | "script" \| "module" \| "unambiguous" \| "commonjs" | ソースタイプ |
| sourceFilename | string | ソースファイル名 |
| startLine | number | 開始行番号（デフォルト: 1） |
| startColumn | number | 開始列番号（デフォルト: 0） |
| startIndex | number | 開始インデックス（デフォルト: 0） |
| allowImportExportEverywhere | boolean | import/exportを任意の場所で許可 |
| allowAwaitOutsideFunction | boolean | async関数外でのawaitを許可 |
| allowReturnOutsideFunction | boolean | 関数外でのreturnを許可 |
| allowSuperOutsideMethod | boolean | メソッド外でのsuperを許可 |
| allowUndeclaredExports | boolean | 未宣言のexportを許可 |
| attachComment | boolean | コメントをノードに付加（デフォルト: true） |
| errorRecovery | boolean | エラー回復モード |
| plugins | ParserPlugin[] | 使用するパーサープラグイン |
| strictMode | boolean | strictモードでパース |
| ranges | boolean | rangesプロパティを追加 |
| tokens | boolean | トークンを出力 |

**戻り値**

```typescript
ParseResult<File>
```

**使用例**

```javascript
import { parse } from "@babel/parser";

const ast = parse("const x = 1;", {
  sourceType: "module",
  plugins: ["typescript", "jsx"]
});

console.log(ast.program.body[0]);
```

---

#### 16 parseExpression

単一の式をパースしてASTを生成します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/parser |
| モジュール | `import { parseExpression } from "@babel/parser"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| input | string | ○ | パース対象の式 |
| options | ParserOptions | - | パースオプション |

**戻り値**

```typescript
ParseResult<Expression>
```

**使用例**

```javascript
import { parseExpression } from "@babel/parser";

const expr = parseExpression("x + y * z");
console.log(expr.type); // "BinaryExpression"
```

---

### @babel/generator API

#### 17 generate

ASTからソースコードを生成します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/generator |
| モジュール | `import generate from "@babel/generator"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| ast | t.Node | ○ | 変換対象のAST |
| options | GeneratorOptions | - | 生成オプション |
| code | string | - | 元のソースコード（ソースマップ用） |

**GeneratorOptions**

| オプション名 | 型 | 説明 |
| --- | --- | --- |
| auxiliaryCommentBefore | string | 先頭に追加するコメント |
| auxiliaryCommentAfter | string | 末尾に追加するコメント |
| shouldPrintComment | function | コメントを出力するか判定 |
| retainLines | boolean | 行番号を維持 |
| retainFunctionParens | boolean | 関数式の括弧を維持 |
| comments | boolean | コメントを出力（デフォルト: true） |
| compact | boolean \| "auto" | 出力を圧縮 |
| minified | boolean | 最小化出力 |
| concise | boolean | 簡潔な出力 |
| filename | string | 警告メッセージ用のファイル名 |
| sourceMaps | boolean | ソースマップを生成 |
| sourceRoot | string | ソースマップのルート |
| sourceFileName | string | ソースマップのファイル名 |

**戻り値**

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

**使用例**

```javascript
import { parse } from "@babel/parser";
import generate from "@babel/generator";

const ast = parse("const x = 1;");
const output = generate(ast, { minified: true });

console.log(output.code); // "const x=1;"
```

---

### @babel/traverse API

#### 18 traverse

ASTを走査し、各ノードに対してビジターを実行します。

**基本情報**

| 項目 | 内容 |
| --- | --- |
| パッケージ | @babel/traverse |
| モジュール | `import traverse from "@babel/traverse"` |

**パラメータ**

| パラメータ名 | 型 | 必須 | 説明 |
| --- | --- | --- | --- |
| parent | t.Node | ○ | 走査対象のASTノード |
| opts | TraverseOptions | ○ | ビジターオブジェクト |
| scope | Scope | - | スコープオブジェクト |
| state | any | - | ビジターに渡す状態 |
| parentPath | NodePath | - | 親ノードのパス |
| visitSelf | boolean | - | 自身のノードもビジット |

**TraverseOptions**

```typescript
{
  scope?: Scope;
  noScope?: boolean;
  denylist?: string[];
  shouldSkip?: (node: NodePath) => boolean;
  // ノードタイプごとのビジター
  [nodeType: string]: {
    enter?: (path: NodePath, state: any) => void;
    exit?: (path: NodePath, state: any) => void;
  } | ((path: NodePath, state: any) => void);
}
```

**戻り値**

```typescript
void
```

**使用例**

```javascript
import { parse } from "@babel/parser";
import traverse from "@babel/traverse";

const ast = parse("const x = 1; const y = 2;");

traverse(ast, {
  VariableDeclaration(path) {
    console.log(path.node.declarations[0].id.name);
  }
});
// 出力: "x", "y"
```

---

### 追加ユーティリティ

#### traverse.cheap

高速なAST走査を行います。NodePathを作成しないため高速ですが、機能は限定的です。

```javascript
traverse.cheap(ast, (node) => {
  console.log(node.type);
});
```

#### traverse.hasType

ASTに特定の型のノードが含まれるかを確認します。

```javascript
const hasArrowFunction = traverse.hasType(ast, "ArrowFunctionExpression");
```

---

### 定数・エクスポート

#### DEFAULT_EXTENSIONS

Babelが処理対象とする推奨ファイル拡張子の配列です。

```javascript
import { DEFAULT_EXTENSIONS } from "@babel/core";

console.log(DEFAULT_EXTENSIONS);
// [".js", ".jsx", ".es6", ".es", ".mjs", ".cjs"]
```

#### 再エクスポート

@babel/coreは以下のモジュールを再エクスポートしています:

- `types`: @babel/types
- `tokTypes`: @babel/parserのトークンタイプ
- `traverse`: @babel/traverse
- `template`: @babel/template

```javascript
import { types as t, traverse, template } from "@babel/core";
```

## 備考

### バージョン情報

本ドキュメントはBabel 8.0.0-rc.2に基づいています。Babel 8からは以下の変更があります:

1. `transform`、`parse`、`transformFromAst`などの関数はコールバックが必須になりました。同期処理には`*Sync`関数を使用してください。
2. 非同期処理には`*Async`関数を使用することを推奨します。

### プラグイン開発

Babelプラグインを開発する場合は、以下のAPIを使用します:

```javascript
export default function myPlugin(api, options) {
  return {
    name: "my-plugin",
    visitor: {
      Identifier(path) {
        // プラグインロジック
      }
    }
  };
}
```

### 参考リンク

- 公式ドキュメント: https://babeljs.io/docs/
- GitHub: https://github.com/babel/babel
