دليل الترحيل

الترحيل من المترجم القديم (lingo.dev/compiler) إلى @lingo.dev/compiler الجديد.

لماذا الترحيل؟

يوفر المترجم الجديد:

  • تجربة تطوير أفضل — تلقائي افتراضيًا (لا حاجة لـ 'use i18n')
  • أداء أفضل — بناء أسرع، HMR محسّن
  • أوضاع البناء — فصل اهتمامات التطوير/CI/الإنتاج
  • تجاوزات يدوية — خاصية data-lingo-override
  • محللات لغة مخصصة — كشف مرن للغة
  • أدوات التطوير — مترجم زائف، أداة التطوير (قريبًا)
  • بنية أنظف — فصل أفضل للاهتمامات

التغييرات الجذرية

1. اسم الحزمة

القديم:

npm install lingo.dev

الجديد:

npm install @lingo.dev/compiler

2. مسارات الاستيراد

القديم:

import lingoCompiler from "lingo.dev/compiler";
import { LingoProvider } from "lingo.dev/react/rsc";

الجديد:

import { withLingo } from "@lingo.dev/compiler/next";
import { LingoProvider } from "@lingo.dev/compiler/react";

3. واجهة برمجة الإعدادات

Next.js

القديم:

// next.config.js
import lingoCompiler from "lingo.dev/compiler";

export default lingoCompiler.next({
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  models: "lingo.dev",
})(nextConfig);

الجديد:

// next.config.ts
import { withLingo } from "@lingo.dev/compiler/next";

export default async function (): Promise<NextConfig> {
  return await withLingo(nextConfig, {
    sourceRoot: "./app", // New: specify source directory
    sourceLocale: "en",
    targetLocales: ["es", "de"],
    models: "lingo.dev",
  });
}

التغييرات:

  • يجب أن يكون الإعداد دالة غير متزامنة
  • خيار sourceRoot جديد
  • غلاف withLingo بدلاً من lingoCompiler.next

Vite

القديم:

import lingoCompiler from "lingo.dev/compiler";

export default defineConfig(() =>
  lingoCompiler.vite({
    sourceRoot: "src",
    targetLocales: ["es", "de"],
    models: "lingo.dev",
  })(viteConfig)
);

الجديد:

import { lingoCompilerPlugin } from "@lingo.dev/compiler/vite";

export default defineConfig({
  plugins: [
    lingoCompilerPlugin({
      sourceRoot: "src",
      sourceLocale: "en", // New: required
      targetLocales: ["es", "de"],
      models: "lingo.dev",
    }),
    react(),
  ],
});

التغييرات:

  • يعتمد على الإضافات بدلاً من غلاف الإعدادات
  • sourceLocale مطلوب الآن
  • ضعه قبل إضافة react()

4. إعداد المزود

القديم:

import { LingoProvider, loadDictionary } from "lingo.dev/react/rsc";

export default function Layout({ children }) {
  return (
    <LingoProvider loadDictionary={(locale) => loadDictionary(locale)}>
      {children}
    </LingoProvider>
  );
}

الجديد:

import { LingoProvider } from "@lingo.dev/compiler/react";

export default function Layout({ children }) {
  return (
    <LingoProvider>
      {children}
    </LingoProvider>
  );
}

التغييرات:

  • لا توجد خاصية loadDictionary—تتم معالجتها داخلياً
  • واجهة برمجية أبسط

5. هيكل الملفات

القديم:

lingo/
├── dictionary.js
├── meta.json
└── [locale]/
    └── *.json

الجديد:

.lingo/
└── metadata.json

التغييرات:

  • تمت إعادة تسمية الدليل (.lingo مقابل lingo)
  • ملف بيانات وصفية واحد بدلاً من ملفات متعددة
  • بنية JSON مختلفة

6. توجيه "use i18n"

القديم: مطلوب افتراضياً. أضفه إلى كل ملف تريد ترجمته:

'use i18n';

export function Component() { ... }

الجديد: اختياري. افتراضياً، تتم ترجمة جميع الملفات تلقائياً. للاشتراك:

{
  useDirective: true, // Enable opt-in behavior
}

ثم أضف التوجيه:

'use i18n';

export function Component() { ... }

خطوات الترحيل

الخطوة 1: تحديث الحزمة

# Uninstall old package
npm uninstall lingo.dev

# Install new package
npm install @lingo.dev/compiler

الخطوة 2: تحديث الإعدادات

Next.js

قبل:

// next.config.js
import lingoCompiler from "lingo.dev/compiler";

export default lingoCompiler.next({
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  models: "lingo.dev",
})(nextConfig);

بعد:

// next.config.ts
import type { NextConfig } from "next";
import { withLingo } from "@lingo.dev/compiler/next";

const nextConfig: NextConfig = {};

export default async function (): Promise<NextConfig> {
  return await withLingo(nextConfig, {
    sourceRoot: "./app",
    sourceLocale: "en",
    targetLocales: ["es", "de"],
    models: "lingo.dev",
    dev: {
      usePseudotranslator: true, // Recommended for development
    },
  });
}

Vite

قبل:

import lingoCompiler from "lingo.dev/compiler";

export default defineConfig(() =>
  lingoCompiler.vite({
    sourceRoot: "src",
    targetLocales: ["es", "de"],
    models: "lingo.dev",
  })(viteConfig)
);

بعد:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { lingoCompilerPlugin } from "@lingo.dev/compiler/vite";

export default defineConfig({
  plugins: [
    lingoCompilerPlugin({
      sourceRoot: "src",
      sourceLocale: "en",
      targetLocales: ["es", "de"],
      models: "lingo.dev",
      dev: {
        usePseudotranslator: true,
      },
    }),
    react(),
  ],
});

الخطوة 3: تحديث المزود

قبل:

import { LingoProvider, loadDictionary } from "lingo.dev/react/rsc";

export default function Layout({ children }) {
  return (
    <LingoProvider loadDictionary={(locale) => loadDictionary(locale)}>
      {children}
    </LingoProvider>
  );
}

بعد:

import { LingoProvider } from "@lingo.dev/compiler/react";

export default function Layout({ children }) {
  return (
    <LingoProvider>
      {children}
    </LingoProvider>
  );
}

الخطوة 4: حذف الملفات القديمة

# Backup old translations (optional)
mv lingo lingo.backup

# Remove old directory
rm -rf lingo

# New directory will be created automatically
# on first build

الخطوة 5: الاختبار باستخدام المترجم الوهمي

npm run dev

باستخدام usePseudotranslator: true، ستشاهد ترجمات وهمية فورية. تحقق من:

  • ترجمة جميع النصوص المتوقعة
  • عدم وجود أخطاء في الترجمة
  • قدرة التخطيط على التعامل مع أطوال النصوص المختلفة

الخطوة 6: إنشاء الترجمات الفعلية

حدّث الإعدادات لتعطيل المترجم الوهمي:

{
  dev: {
    usePseudotranslator: false,
  }
}

أعد تشغيل خادم التطوير. سيقوم المترجم بإنشاء ترجمات فعلية لأي نص جديد أو معدّل.

الخطوة 7: تثبيت الترجمات الجديدة

git add .lingo/
git commit -m "chore: migrate to @lingo.dev/compiler"
git push

تعيين الميزات

الميزات القديمة ← المعادلات الجديدة

الميزة القديمةالمكافئ الجديدملاحظات
dictionary.js.lingo/metadata.jsonتنسيق مختلف
meta.json.lingo/metadata.jsonتم الدمج في ملف واحد
"use i18n" (مطلوب)"use i18n" (اختياري)الآن اختياري، وليس مطلوباً
مطالبات مخصصةخيار تكوين promptنفس الوظيفة
تحرير الترجماتdata-lingo-overrideتجاوزات قائمة على السمات
تخطي الترجماتdata-lingo-override + فارغأو استخدم useDirective
تجاوز الترجماتdata-lingo-overrideقائم على السمات
تبديل اللغاتuseLingoContext()يُرجع { locale, setLocale }
موفرو LLMتكوين modelsنفس الموفرين المدعومين

ميزات جديدة (غير موجودة في المترجم القديم)

  • أوضاع البناءtranslate مقابل cache-only
  • مترجم زائف — ترجمات وهمية فورية
  • أداة التطوير — التحرير داخل المتصفح (قريباً)
  • محللات لغة مخصصة — كشف مرن للغة
  • جمع تلقائي — دعم ICU MessageFormat
  • خادم الترجمة — ترجمات عند الطلب في بيئة التطوير

ترجمة الترجمات الموجودة

يستخدم المترجم الجديد تنسيق ملف مختلف. لا يتم ترحيل الترجمات الموجودة تلقائياً.

الخيارات:

الخيار 1: إعادة إنشاء جميع الترجمات

اسمح للمترجم بإنشاء ترجمات جديدة:

  1. احذف دليل lingo/ القديم
  2. شغّل المترجم الجديد
  3. أنشئ الترجمات باستخدام الذكاء الاصطناعي

المزايا: بداية نظيفة، أحدث نماذج الذكاء الاصطناعي العيوب: تكاليف واجهة برمجة التطبيقات، قد تفقد الفروق الدقيقة

الخيار 2: سكريبت الترحيل اليدوي

أنشئ سكريبت لتحويل التنسيق القديم إلى الجديد:

// migrate-translations.ts
import * as fs from "fs";

const oldDir = "./lingo";
const newFile = "./.lingo/metadata.json";

// Read old translations
const oldTranslations = {}; // Parse old files

// Convert to new format
const newMetadata = {
  version: "1",
  sourceLocale: "en",
  targetLocales: ["es", "de"],
  translations: {}, // Convert old translations
};

// Write new metadata
fs.writeFileSync(newFile, JSON.stringify(newMetadata, null, 2));

هذا عمل يدوي ويعتمد على التنسيق.

الخيار 3: النهج المختلط

  1. إنشاء ترجمات جديدة لمعظم النصوص
  2. استخدام data-lingo-override للترجمات الحرجة التي تحتاج إلى صياغة دقيقة

المشاكل الشائعة

"Cannot find module '@lingo.dev/compiler'" قم بتشغيل npm install @lingo.dev/compiler

"Config must be async function" (Next.js) قم بتغليف الإعدادات الخاصة بك في async function:

export default async function () {
  return await withLingo(...);
}

"sourceLocale is required" أضف sourceLocale: "en" إلى إعداداتك.

الترجمات لا تظهر تحقق من:

  1. LingoProvider موجود في التخطيط الجذري
  2. .lingo/metadata.json موجود
  3. لا توجد أخطاء في وحدة التحكم

الأسئلة الشائعة

هل يمكنني تشغيل كلا المترجمين في وقت واحد؟ لا. قم بإلغاء تثبيت المترجم القديم قبل تثبيت الجديد.

هل سأفقد ترجماتي؟ ليس إذا قمت بترحيلها يدويًا. وإلا، قم بإعادة إنشائها باستخدام الذكاء الاصطناعي (يكلف أرصدة API).

ماذا لو لم يكن إطار العمل الخاص بي مدعومًا بعد؟ يدعم المترجم الجديد حاليًا Next.js وVite. أطر العمل الأخرى قادمة قريبًا. استمر في استخدام المترجم القديم أو ساهم في دعم إطار العمل الخاص بك.

كم من الوقت يستغرق الترحيل؟

  • مشروع بسيط: 15-30 دقيقة
  • مشروع معقد: 1-2 ساعة
  • معظم الوقت يُقضى في الاختبار والتحقق من الترجمات

هل يجب أن أقوم بالترحيل الآن أم أنتظر؟ قم بالترحيل عندما:

  • تحتاج إلى ميزات جديدة (أوضاع البناء، التجاوزات، محللات مخصصة)
  • تبدأ مشروعًا جديدًا
  • تريد تجربة مطور أفضل

انتظر إذا:

  • مشروعك يعمل بشكل جيد مع المترجم القديم
  • تحتاج إلى أطر عمل غير مدعومة بعد من قبل المترجم الجديد

الخطوات التالية