Skip to content

Dans Bun, YAML est un citoyen de première classe aux côtés de JSON et TOML. Vous pouvez :

  • Analyser des chaînes YAML avec Bun.YAML.parse
  • import & require des fichiers YAML comme modules au runtime (y compris le support du rechargement à chaud et du mode watch)
  • import & require des fichiers YAML dans les applications frontend via le bundler de bun

Conformité

L'analyseur YAML de Bun réussit actuellement plus de 90 % de la suite de tests YAML officielle. Bien que nous travaillions activement à atteindre 100 % de conformité, l'implémentation actuelle couvre la grande majorité des cas d'utilisation réels. L'analyseur est écrit en Zig pour des performances optimales et est continuellement amélioré.


API Runtime

Bun.YAML.parse()

Analyse une chaîne YAML en un objet JavaScript.

ts
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 multi-documents

Lors de l'analyse de YAML avec plusieurs documents (séparés par ---), Bun.YAML.parse() renvoie un tableau :

ts
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" }
// ]

Fonctionnalités YAML prises en charge

L'analyseur YAML de Bun prend en charge la spécification YAML 1.2 complète, y compris :

  • Scalaires : chaînes, nombres, booléens, valeurs null
  • Collections : séquences (tableaux) et mappages (objets)
  • Ancres et alias : nœuds réutilisables avec & et *
  • Tags : indices de type comme !!str, !!int, !!float, !!bool, !!null
  • Chaînes multi-lignes : scalaires littéraux (|) et pliés (>)
  • Commentaires : utilisant #
  • Directives : %YAML et %TAG
ts
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);

Gestion des erreurs

Bun.YAML.parse() génère une SyntaxError si le YAML est invalide :

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

Import de module

ES Modules

Vous pouvez importer des fichiers YAML directement comme modules ES. Le contenu YAML est analysé et rendu disponible à la fois comme export par défaut et exports nommés :

yaml
database:
  host: localhost
  port: 5432
  name: myapp

redis:
  host: localhost
  port: 6379

features:
  auth: true
  rateLimit: true
  analytics: false

Import par défaut

ts
import config from "./config.yaml";

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

Imports nommés

Vous pouvez déstructurer les propriétés YAML de premier niveau comme imports nommés :

ts
import { database, redis, features } from "./config.yaml";

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

Ou combiner les deux :

ts
import config, { database, features } from "./config.yaml";

// Utiliser l'objet config complet
console.log(config);

// Ou utiliser des parties spécifiques
if (features.rateLimit) {
  setupRateLimiting(database);
}

CommonJS

Les fichiers YAML peuvent également être requis en CommonJS :

ts
const config = require("./config.yaml");
console.log(config.database.name); // "myapp"

// La déstructuration fonctionne aussi
const { database, redis } = require("./config.yaml");
console.log(database.port); // 5432

Rechargement à chaud avec YAML

L'une des fonctionnalités les plus puissantes du support YAML de Bun est le rechargement à chaud. Lorsque vous exécutez votre application avec bun --hot, les modifications des fichiers YAML sont automatiquement détectées et rechargées sans fermer les connexions

Rechargement à chaud de la configuration

yaml
server:
  port: 3000
  host: localhost

features:
  debug: true
  verbose: false
ts
import { server, features } from "./config.yaml";

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

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

// Votre code serveur ici
Bun.serve({
  port: server.port,
  hostname: server.host,
  fetch(req) {
    if (features.verbose) {
      console.log(`${req.method} ${req.url}`);
    }
    return new Response("Hello World");
  },
});

Exécuter avec rechargement à chaud :

bash
bun --hot server.ts

Maintenant, lorsque vous modifiez config.yaml, les modifications sont immédiatement reflétées dans votre application en cours d'exécution. C'est parfait pour :

  • Ajuster la configuration pendant le développement
  • Tester différents paramètres sans redémarrages
  • Débogage en direct avec modifications de configuration
  • Basculement de drapeaux de fonctionnalité

Gestion de la configuration

Configuration basée sur l'environnement

YAML excelle dans la gestion de la configuration across différents environnements :

yaml
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
import configs from "./config.yaml";

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

// Les variables d'environnement dans les valeurs YAML peuvent être interpolées
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);

Configuration des drapeaux de fonctionnalité

yaml
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
import { features } from "./features.yaml";

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

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

  // Vérifier le pourcentage de déploiement
  if (feature.rolloutPercentage < 100) {
    const hash = hashCode(userEmail || "anonymous");
    if (hash % 100 >= feature.rolloutPercentage) {
      return false;
    }
  }

  // Vérifier les utilisateurs autorisés
  if (feature.allowedUsers && userEmail) {
    return feature.allowedUsers.includes(userEmail);
  }

  return true;
}

// Utiliser avec le rechargement à chaud pour basculer les fonctionnalités en temps réel
if (isFeatureEnabled("newDashboard", user.email)) {
  renderNewDashboard();
} else {
  renderLegacyDashboard();
}

Configuration de la base de données

yaml
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
import { connections, migrations } from "./database.yaml";
import { createConnection } from "./database-driver";

// Analyser les variables d'environnement avec valeurs par défaut
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);

// Exécuter automatiquement les migrations si configuré
if (parseConfig(migrations).autoRun === "true") {
  await runMigrations(db, migrations.directory);
}

Intégration avec le bundler

Lorsque vous importez des fichiers YAML dans votre application et que vous la bundlez avec Bun, le YAML est analysé au moment du build et inclus comme module JavaScript :

bash
bun build app.ts --outdir=dist

Cela signifie :

  • Zéro frais d'analyse YAML au runtime en production
  • Tailles de bundle plus petites
  • Support du tree-shaking pour la configuration inutilisée (imports nommés)

Imports dynamiques

Les fichiers YAML peuvent être importés dynamiquement, utile pour charger la configuration à la demande :

ts
const env = process.env.NODE_ENV || "development";
const config = await import(`./configs/${env}.yaml`);

// Charger les paramètres spécifiques à l'utilisateur
async function loadUserSettings(userId: string) {
  try {
    const settings = await import(`./users/${userId}/settings.yaml`);
    return settings.default;
  } catch {
    return await import("./users/default-settings.yaml");
  }
}

Bun édité par www.bunjs.com.cn