В Bun YAML является первоклассным гражданином наряду с JSON и TOML. Вы можете:
- Парсить YAML строки с помощью
Bun.YAML.parse - Импортировать и требовать YAML файлы как модули во время выполнения (включая поддержку горячей перезагрузки и режима наблюдения)
- Импортировать и требовать YAML файлы в фронтенд-приложениях через сборщик Bun
Соответствие
Парсер YAML от Bun в настоящее время проходит более 90% официального набора тестов YAML. Мы активно работаем над достижением 100% соответствия, но текущая реализация охватывает подавляющее большинство реальных случаев использования. Парсер написан на Zig для оптимальной производительности и постоянно улучшается.
API среды выполнения
Bun.YAML.parse()
Парсит YAML строку в 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
При парсинге YAML с несколькими документами (разделенными ---), Bun.YAML.parse() возвращает массив:
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
Парсер YAML от Bun поддерживает полную спецификацию YAML 1.2, включая:
- Скаляры: строки, числа, булевы значения, null значения
- Коллекции: последовательности (массивы) и отображения (объекты)
- Якоря и псевдонимы: повторно используемые узлы с
&и* - Теги: подсказки типов, такие как
!!str,!!int,!!float,!!bool,!!null - Многострочные строки: литеральные (
|) и сложенные (>) скаляры - Комментарии: использование
# - Директивы:
%YAMLи%TAG
const yaml = `
# Запись сотрудника
employee: &emp
name: Jane Smith
department: Engineering
skills:
- JavaScript
- TypeScript
- React
manager: *emp # Ссылка на employee
config: !!str 123 # Явный тип строки
description: |
Это многострочная
литеральная строка, которая сохраняет
разрывы строк и отступы.
summary: >
Это сложенная строка,
которая соединяет строки пробелами,
если нет пустых строк.
`;
const data = Bun.YAML.parse(yaml);Обработка ошибок
Bun.YAML.parse() выбрасывает SyntaxError, если YAML недействителен:
try {
Bun.YAML.parse("invalid: yaml: content:");
} catch (error) {
console.error("Не удалось парсить YAML:", error.message);
}Импорт модуля
ES модули
Вы можете импортировать YAML файлы напрямую как ES модули. Содержимое YAML парсится и предоставляется как как экспорты по умолчанию, так и именованные экспорты:
database:
host: localhost
port: 5432
name: myapp
redis:
host: localhost
port: 6379
features:
auth: true
rateLimit: true
analytics: falseИмпорт по умолчанию
import config from "./config.yaml";
console.log(config.database.host); // "localhost"
console.log(config.redis.port); // 6379Именованные импорты
Вы можете деструктурировать свойства YAML верхнего уровня как именованные импорты:
import { database, redis, features } from "./config.yaml";
console.log(database.host); // "localhost"
console.log(redis.port); // 6379
console.log(features.auth); // trueИли комбинировать оба:
import config, { database, features } from "./config.yaml";
// Используйте полный объект config
console.log(config);
// Или используйте конкретные части
if (features.rateLimit) {
setupRateLimiting(database);
}CommonJS
YAML файлы также могут быть затребованы в CommonJS:
const config = require("./config.yaml");
console.log(config.database.name); // "myapp"
// Деструктуризация также работает
const { database, redis } = require("./config.yaml");
console.log(database.port); // 5432Горячая перезагрузка с YAML
Одной из самых мощных функций поддержки YAML от Bun является горячая перезагрузка. Когда вы запускаете приложение с bun --hot, изменения в YAML файлах автоматически обнаруживаются и перезагружаются без закрытия соединений
Горячая перезагрузка конфигурации
server:
port: 3000
host: localhost
features:
debug: true
verbose: falseimport { server, features } from "./config.yaml";
console.log(`Запуск сервера на ${server.host}:${server.port}`);
if (features.debug) {
console.log("Режим отладки включен");
}
// Ваш код сервера здесь
Bun.serve({
port: server.port,
hostname: server.host,
fetch(req) {
if (features.verbose) {
console.log(`${req.method} ${req.url}`);
}
return new Response("Hello World");
},
});Запуск с горячей перезагрузкой:
bun --hot server.tsТеперь, когда вы изменяете config.yaml, изменения немедленно отражаются в вашем работающем приложении. Это идеально подходит для:
- Настройки конфигурации во время разработки
- Тестирования различных настроек без перезапусков
- Отладки в реальном времени с изменениями конфигурации
- Переключения флагов функций
Управление конфигурацией
Конфигурация на основе окружения
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: falseimport 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);Конфигурация флагов функций
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;
}
// Проверка процента развертывания
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();
}Конфигурация базы данных
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";
// Парсинг переменных окружения со значениями по умолчанию
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 модуль:
bun build app.ts --outdir=distЭто означает:
- Нулевые накладные расходы на парсинг YAML во время выполнения в продакшене
- Меньшие размеры пакета
- Поддержка tree-shaking для неиспользуемой конфигурации (именованные импорты)
Динамические импорты
YAML файлы могут быть динамически импортированы, что полезно для загрузки конфигурации по требованию:
const env = process.env.NODE_ENV || "development";
const config = await import(`./configs/${env}.yaml`);
// Загрузка пользовательских настроек
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");
}
}