> ## Documentation Index
> Fetch the complete documentation index at: https://bun.ll1025.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# YAML

> 通过运行时 API 和打包器集成使用 Bun 内置的 YAML 文件支持

在 Bun 中，YAML 与 JSON 和 TOML 一样是一等公民。您可以：

* 使用 `Bun.YAML.parse` 解析 YAML 字符串
* 在运行时 `import` 和 `require` YAML 文件作为模块（包括热重载和监视模式支持）
* 在前端应用中使用 Bun 的打包器 `import` 和 `require` YAML 文件

***

## 一致性

Bun 的 YAML 解析器使用 Rust 编写，通过了超过 90% 的官方 YAML 测试套件，覆盖了绝大多数实际使用场景。我们正在努力实现 100% 的一致性。

***

## 运行时 API

### `Bun.YAML.parse()`

将 YAML 字符串解析为 JavaScript 对象。

```ts theme={null}
import { YAML } from "bun";
const text = `
name: John Doe
age: 30
email: john@example.com
hobbies:
  - reading
  - coding
  - hiking
`;

const data = YAML.parse(text);
console.log(data);
// {
//   name: "John Doe",
//   age: 30,
//   email: "john@example.com",
//   hobbies: ["reading", "coding", "hiking"]
// }
```

#### 多文档 YAML

当解析包含多个文档（用 `---` 分隔）的 YAML 时，`Bun.YAML.parse()` 返回一个数组：

```ts theme={null}
const multiDoc = `
---
name: Document 1
---
name: Document 2
---
name: Document 3
`;

const docs = Bun.YAML.parse(multiDoc);
console.log(docs);
// [
//   { name: "Document 1" },
//   { name: "Document 2" },
//   { name: "Document 3" }
// ]
```

#### 支持的 YAML 特性

Bun 的 YAML 解析器支持完整的 YAML 1.2 规范，包括：

* **标量**：字符串、数字、布尔值、null 值
* **集合**：序列（数组）和映射（对象）
* **锚点和别名**：使用 `&` 和 `*` 的可复用节点
* **标签**：类型提示，如 `!!str`、`!!int`、`!!float`、`!!bool`、`!!null`
* **多行字符串**：字面量（`|`）和折叠（`>`）标量
* **注释**：使用 `#`
* **指令**：`%YAML` 和 `%TAG`

```ts theme={null}
const yaml = `
# Employee record
employee: &emp
  name: Jane Smith
  department: Engineering
  skills:
    - JavaScript
    - TypeScript
    - React

manager: *emp  # Reference to employee

config: !!str 123  # Explicit string type

description: |
  This is a multi-line
  literal string that preserves
  line breaks and spacing.

summary: >
  This is a folded string
  that joins lines with spaces
  unless there are blank lines.
`;

const data = Bun.YAML.parse(yaml);
```

#### 错误处理

`Bun.YAML.parse()` 在 YAML 无效时抛出 `SyntaxError`：

```ts theme={null}
try {
  Bun.YAML.parse("invalid: yaml: content:");
} catch (error) {
  console.error("Failed to parse YAML:", error.message);
}
```

***

## 模块导入

### ES 模块

直接作为 ES 模块导入 YAML 文件。Bun 解析内容并将其作为默认导出和命名导出暴露：

```yaml config.yaml theme={null}
database:
  host: localhost
  port: 5432
  name: myapp

redis:
  host: localhost
  port: 6379

features:
  auth: true
  rateLimit: true
  analytics: false
```

#### 默认导入

```ts app.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
import config from "./config.yaml";

console.log(config.database.host); // "localhost"
console.log(config.redis.port); // 6379
```

#### 命名导入

顶层的 YAML 属性可作为命名导入使用：

```ts app.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
import { database, redis, features } from "./config.yaml";

console.log(database.host); // "localhost"
console.log(redis.port); // 6379
console.log(features.auth); // true
```

或者组合两者：

```ts app.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
import config, { database, features } from "./config.yaml";

// 使用完整的配置对象
console.log(config);

// 或使用特定部分
if (features.rateLimit) {
  setupRateLimiting(database);
}
```

### CommonJS

您也可以在 CommonJS 中 `require` YAML 文件：

```ts app.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
const config = require("./config.yaml");
console.log(config.database.name); // "myapp"

// 解构也能工作
const { database, redis } = require("./config.yaml");
console.log(database.port); // 5432
```

***

## YAML 热重载

当您使用 `bun --hot` 运行应用程序时，Bun 会检测 YAML 文件的更改并重新加载它们，无需关闭连接。

### 配置热重载

```yaml config.yaml theme={null}
server:
  port: 3000
  host: localhost

features:
  debug: true
  verbose: false
```

```ts server.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
import { server, features } from "./config.yaml";

console.log(`Starting server on ${server.host}:${server.port}`);

if (features.debug) {
  console.log("Debug mode enabled");
}

// 您的服务器代码
Bun.serve({
  port: server.port,
  hostname: server.host,
  fetch(req) {
    if (features.verbose) {
      console.log(`${req.method} ${req.url}`);
    }
    return new Response("Hello World");
  },
});
```

使用热重载运行：

```bash terminal icon="terminal" theme={null}
bun --hot server.ts
```

现在，当您修改 `config.yaml` 时，正在运行的应用程序会捕获更改：您可以在开发期间调整设置或切换功能标志，而无需重启。

***

## 配置管理

### 基于环境的配置

一个 YAML 文件可以包含多个环境的配置，使用锚点共享默认值：

```yaml config.yaml theme={null}
defaults: &defaults
  timeout: 5000
  retries: 3
  cache:
    enabled: true
    ttl: 3600

development:
  <<: *defaults
  api:
    url: http://localhost:4000
    key: dev_key_12345
  logging:
    level: debug
    pretty: true

staging:
  <<: *defaults
  api:
    url: https://staging-api.example.com
    key: ${STAGING_API_KEY}
  logging:
    level: info
    pretty: false

production:
  <<: *defaults
  api:
    url: https://api.example.com
    key: ${PROD_API_KEY}
  cache:
    enabled: true
    ttl: 86400
  logging:
    level: error
    pretty: false
```

```ts app.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
import configs from "./config.yaml";

const env = process.env.NODE_ENV || "development";
const config = configs[env];

// YAML 值中的环境变量可以进行插值
function interpolateEnvVars(obj: any): any {
  if (typeof obj === "string") {
    return obj.replace(/\${(\w+)}/g, (_, key) => process.env[key] || "");
  }
  if (typeof obj === "object") {
    for (const key in obj) {
      obj[key] = interpolateEnvVars(obj[key]);
    }
  }
  return obj;
}

export default interpolateEnvVars(config);
```

### 功能标志配置

```yaml features.yaml theme={null}
features:
  newDashboard:
    enabled: true
    rolloutPercentage: 50
    allowedUsers:
      - admin@example.com
      - beta@example.com

  experimentalAPI:
    enabled: false
    endpoints:
      - /api/v2/experimental
      - /api/v2/beta

  darkMode:
    enabled: true
    default: auto # auto, light, dark
```

```ts feature-flags.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
import { features } from "./features.yaml";

export function isFeatureEnabled(featureName: string, userEmail?: string): boolean {
  const feature = features[featureName];

  if (!feature?.enabled) {
    return false;
  }

  // 检查发布百分比
  if (feature.rolloutPercentage < 100) {
    const hash = hashCode(userEmail || "anonymous");
    if (hash % 100 >= feature.rolloutPercentage) {
      return false;
    }
  }

  // 检查允许的用户
  if (feature.allowedUsers && userEmail) {
    return feature.allowedUsers.includes(userEmail);
  }

  return true;
}

// 配合热重载使用，实时切换功能
if (isFeatureEnabled("newDashboard", user.email)) {
  renderNewDashboard();
} else {
  renderLegacyDashboard();
}
```

### 数据库配置

```yaml database.yaml icon="yaml" theme={null}
connections:
  primary:
    type: postgres
    host: ${DB_HOST:-localhost}
    port: ${DB_PORT:-5432}
    database: ${DB_NAME:-myapp}
    username: ${DB_USER:-postgres}
    password: ${DB_PASS}
    pool:
      min: 2
      max: 10
      idleTimeout: 30000

  cache:
    type: redis
    host: ${REDIS_HOST:-localhost}
    port: ${REDIS_PORT:-6379}
    password: ${REDIS_PASS}
    db: 0

  analytics:
    type: clickhouse
    host: ${ANALYTICS_HOST:-localhost}
    port: 8123
    database: analytics

migrations:
  autoRun: ${AUTO_MIGRATE:-false}
  directory: ./migrations

seeds:
  enabled: ${SEED_DB:-false}
  directory: ./seeds
```

```ts db.ts icon="https://mintcdn.com/span-inc/82N53aP7NFbaCVSl/icons/typescript.svg?fit=max&auto=format&n=82N53aP7NFbaCVSl&q=85&s=787d39d6a7d96d7f9540dc74344eba23" theme={null}
import { connections, migrations } from "./database.yaml";
import { createConnection } from "./database-driver";

// 解析带默认值的环境变量
function parseConfig(config: any) {
  return JSON.parse(
    JSON.stringify(config).replace(
      /\${([^:-]+)(?::([^}]+))?}/g,
      (_, key, defaultValue) => process.env[key] || defaultValue || "",
    ),
  );
}

const dbConfig = parseConfig(connections);

export const db = await createConnection(dbConfig.primary);
export const cache = await createConnection(dbConfig.cache);
export const analytics = await createConnection(dbConfig.analytics);

// 如果已配置，自动运行迁移
if (parseConfig(migrations).autoRun === "true") {
  await runMigrations(db, migrations.directory);
}
```

### 打包器集成

当您打包导入 YAML 文件的应用程序时，Bun 会在构建时解析 YAML 并将其作为 JavaScript 模块包含：

```bash terminal icon="terminal" theme={null}
bun build app.ts --outdir=dist
```

在构建时解析意味着：

* 生产环境中零运行时 YAML 解析开销
* 更小的打包体积
* 未使用配置的摇树优化（命名导入）

### 动态导入

动态导入 YAML 文件以按需加载配置：

```ts 根据环境加载配置 theme={null}
const env = process.env.NODE_ENV || "development";
const { default: config } = await import(`./configs/${env}.yaml`);

// 加载用户特定设置
async function loadUserSettings(userId: string) {
  try {
    const settings = await import(`./users/${userId}/settings.yaml`);
    return settings.default;
  } catch {
    const { default: defaults } = await import("./users/default-settings.yaml");
    return defaults;
  }
}
```
