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&requiredes fichiers YAML comme modules au runtime (y compris le support du rechargement à chaud et du mode watch)import&requiredes 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.
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 :
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 :
%YAMLet%TAG
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 :
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 :
database:
host: localhost
port: 5432
name: myapp
redis:
host: localhost
port: 6379
features:
auth: true
rateLimit: true
analytics: falseImport par défaut
import config from "./config.yaml";
console.log(config.database.host); // "localhost"
console.log(config.redis.port); // 6379Imports nommés
Vous pouvez déstructurer les propriétés YAML de premier niveau comme imports nommés :
import { database, redis, features } from "./config.yaml";
console.log(database.host); // "localhost"
console.log(redis.port); // 6379
console.log(features.auth); // trueOu combiner les deux :
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 :
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); // 5432Rechargement à 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
server:
port: 3000
host: localhost
features:
debug: true
verbose: falseimport { 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 :
bun --hot server.tsMaintenant, 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 :
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: falseimport 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é
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, darkimport { 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
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: ./seedsimport { 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 :
bun build app.ts --outdir=distCela 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 :
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");
}
}