Skip to content

في Bun، YAML هو مواطن من الدرجة الأولى جنبًا إلى جنب مع JSON و TOML. يمكنك:

  • تحليل سلاسل YAML مع Bun.YAML.parse
  • import و require ملفات YAML كوحدات في وقت التشغيل (بما في ذلك دعم إعادة التحميل الساخن ووضع المراقبة)
  • import و require ملفات YAML في تطبيقات الواجهة الأمامية عبر مجمع bun

المطابقة ​

محلل YAML في Bun يمرر حاليًا أكثر من 90% من مجموعة اختبارات YAML الرسمية. بينما نعمل بنشاط للوصول إلى 100% من المطابقة، يغطي التنفيذ الحالي الغالبية العظمى من حالات الاستخدام الواقعية. تم كتابة المحلل في Zig للحصول على أداء مثالي ويتم تحسينه باستمرار.


واجهة برمجة التطبيقات في وقت التشغيل ​

Bun.YAML.parse() ​

تحليل سلسلة YAML إلى كائن 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 متعدد المستندات ​

عند تحليل YAML مع مستندات متعددة (مفصولة بـ ---)، ترجع Bun.YAML.parse() مصفوفة:

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

ميزات YAML المدعومة ​

محلل YAML في Bun يدعم مواصفات YAML 1.2 الكاملة، بما في ذلك:

  • القياسات: السلاسل، الأرقام، القيم المنطقية، قيم null
  • المجموعات: المتتابعات (مصفوفات) والتعيينات (كائنات)
  • المراسي والمراجع: عقد قابلة لإعادة الاستخدام مع & و *
  • العلامات: تلميحات النوع مثل !!str، !!int، !!float، !!bool، !!null
  • سلاسل متعددة الأسطر: حرفية (|) ومطوية (>)
  • التعليقات: باستخدام #
  • التوجيهات: %YAML و %TAG
ts
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 غير صالح:

ts
try {
  Bun.YAML.parse("invalid: yaml: content:");
} catch (error) {
  console.error("فشل تحليل YAML:", error.message);
}

استيراد الوحدة النمطية ​

وحدات ES ​

يمكنك استيراد ملفات YAML مباشرة كوحدات ES. يتم تحليل محتوى YAML وجعله متاحًا كصادرات افتراضية ومسماة:

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

redis:
  host: localhost
  port: 6379

features:
  auth: true
  rateLimit: true
  analytics: false

الاستيراد الافتراضي ​

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

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

الاستيراد المسمى ​

يمكنك إزالة خصائص YAML على المستوى العلوي كواردات مسماة:

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

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

أو الجمع بين الاثنين:

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

// استخدام كائن config الكامل
console.log(config);

// أو استخدام أجزاء محددة
if (features.rateLimit) {
  setupRateLimiting(database);
}

CommonJS ​

يمكن أيضًا طلب ملفات YAML في CommonJS:

ts
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 تلقائيًا وإعادة تحميلها بدون إغلاق الاتصالات

إعادة تحميل التكوين الساخن ​

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");
}

// كود الخادم الخاص بك هنا
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
bun --hot server.ts

الآن عند تعديل config.yaml، يتم عكس التغييرات على الفور في تطبيقك قيد التشغيل. هذا مثالي لـ:

  • ضبط التكوين أثناء التطوير
  • اختبار إعدادات مختلفة بدون إعادة تشغيل
  • تصحيح الأخطاء المباشر مع تغييرات التكوين
  • تبديل علم الميزة

إدارة التكوين ​

التكوين القائم على البيئة ​

يتفوق 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: false
ts
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:
  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;
  }

  // التحقق من نسبة النشر
  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
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";

// تحليل متغيرات البيئة مع القيم الافتراضية
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
bun build app.ts --outdir=dist

هذا يعني:

  • لا نفقات عامة لتحليل YAML في وقت التشغيل في الإنتاج
  • أحجام حزم أصغر
  • دعم اهتزاز الشجرة للتكوين غير المستخدم (الواردات المسماة)

الواردات الديناميكية ​

يمكن استيراد ملفات YAML بشكل ديناميكي، مفيدة لتحميل التكوين عند الطلب:

ts
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");
  }
}

Bun بواسطة www.bunjs.com.cn تحرير