迁移指南

从旧版编译器(lingo.dev/compiler)迁移到新版 @lingo.dev/compiler。

为什么要迁移?

新版编译器带来:

  • 更优的 DX — 默认自动化(无需 'use i18n'
  • 更高性能 — 构建更快,HMR 更优
  • 构建模式 — 区分 dev/CI/prod 场景
  • 手动覆盖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. 配置 API

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

变更点:

  • 配置必须为 async function
  • 新增 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. Provider 设置

旧:

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 属性——已在内部处理
  • API 更加简洁

5. 文件结构

旧:

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

新:

.lingo/
└── metadata.json

变更:

  • 目录已重命名(.lingolingo
  • 采用单一元数据文件,替代多个文件
  • 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:更新 Provider

更新前:

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"(可选)现在为可选,非必需
自定义 promptsprompt 配置选项功能相同
编辑翻译data-lingo-override基于属性的覆盖
跳过翻译data-lingo-override + 空或使用 useDirective
覆盖翻译data-lingo-override基于属性
切换语言环境useLingoContext()返回 { locale, setLocale }
LLM providersmodels 配置支持相同的 providers

新功能(旧编译器中未包含)

  • 构建模式translatecache-only
  • 伪翻译器 — 即时生成假翻译
  • 开发小部件 — 浏览器内编辑(即将推出)
  • 自定义区域解析器 — 灵活的区域检测
  • 自动复数处理 — 支持 ICU MessageFormat
  • 翻译服务器 — 开发环境下按需翻译

翻译现有翻译内容

新编译器采用了不同的文件格式。现有翻译不会自动迁移。

选项:

选项 1:重新生成所有翻译

让编译器生成全新的翻译:

  1. 删除旧的 lingo/ 目录
  2. 运行新编译器
  3. 使用 AI 生成翻译

优点: 全新开始,采用最新 AI 模型 缺点: 有 API 成本,可能丢失细节

选项 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

常见问题

“找不到模块 '@lingo.dev/compiler'” 运行 npm install @lingo.dev/compiler

“Config 必须是异步函数”(Next.js) 将你的 config 包裹在 async function

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

“sourceLocale 是必需的” 在你的 config 中添加 sourceLocale: "en"

翻译未显示 请检查:

  1. LingoProvider 是否在根布局中
  2. .lingo/metadata.json 是否存在
  3. 控制台无报错

常见问题解答

可以同时运行两个编译器吗? 不可以。请先卸载旧编译器,再安装新编译器。

我的翻译会丢失吗? 如果手动迁移则不会丢失。否则可用 AI 重新生成(会消耗 API 积分)。

如果我的框架还不支持怎么办? 新编译器目前支持 Next.js 和 Vite。其他框架即将支持。请继续使用旧编译器,或为你的框架贡献支持。

迁移需要多长时间?

  • 简单项目:15-30 分钟
  • 复杂项目:1-2 小时
  • 大部分时间用于测试和验证翻译

我现在应该迁移还是等待? 建议在以下情况下迁移:

  • 你需要新功能(构建模式、覆盖、自定义解析器)
  • 你正在启动新项目
  • 你想要更好的开发体验

如果你的项目在旧编译器下运行良好,或你需要新编译器尚未支持的框架,则建议暂缓迁移。

后续步骤