Alpha
Lingo.dev Compiler 目前仍处于 alpha 阶段。它尚不稳定,不建议用于生产环境,且 API 可能会在不同版本之间发生变化。
以下实践基于在使用 Lingo.dev Compiler 时能够产出稳定且具成本效益结果的模式,总结了构建流程、代码组织、翻译质量和测试方面的建议。
构建流程#
采用三种模式策略#
开发 - pseudotranslator
启用 dev.usePseudotranslator: true,即可获得即时反馈。无需 API 调用、无需成本、立刻见效。伪翻译能帮助你发现未翻译的字符串并测试布局。
{
buildMode: "translate",
dev: { usePseudotranslator: true },
}CI - translate 模式
使用 buildMode: "translate" 并接入真实 provider 运行。每次 CI 运行后,都要提交更新后的 .lingo/metadata.json,这样生产环境才能使用这些翻译。
LINGO_BUILD_MODE=translate npm run build生产环境 - cache-only 模式
使用 buildMode: "cache-only" 部署。生产环境无需 API 密钥,构建过程可预测且速度更快。
LINGO_BUILD_MODE=cache-only npm run build版本控制#
将 .lingo/ 提交到仓库#
.lingo/metadata.json 文件是所有缓存翻译的唯一事实来源。生产环境在 cache-only 模式下的构建依赖于它。
# .gitignore - do NOT ignore .lingo/
node_modules/
dist/
.env如果没有提交 .lingo/metadata.json,生产构建会失败,因为 cache-only 模式下没有可读取的翻译。
审查翻译变更#
当 CI 提交更新后的翻译时,请在 pull request 中审查 .lingo/metadata.json 的 diff。这样可以像审查代码变更一样,在翻译进入生产环境前及时发现问题。
代码组织#
将可翻译文本直接写在 JSX 中#
Compiler 会扫描 JSX 中可翻译的内容。存放在 JavaScript 变量、常量或外部文件中的文本不会被识别:
// Good - compiler detects this text
export function Header() {
return <h1>Welcome to our app</h1>;
}
// Bad - compiler cannot detect text in a variable
const title = "Welcome to our app";
export function Header() {
return <h1>{title}</h1>;
}大型代码库使用 useDirective#
在大型项目中,扫描每个文件都会增加构建时间。启用 useDirective: true,并仅在包含面向用户文本的文件中添加 'use i18n':
{
useDirective: true,
}'use i18n';
// Only this file is scanned for translations
export function PublicPage() {
return <h1>Welcome</h1>;
}尽量缩小 sourceRoot 范围#
将 sourceRoot 设置为恰好包含可翻译组件的最小目录。范围过大的 sourceRoot 会扫描许多不必要的文件:
| 项目类型 | 推荐 sourceRoot |
|---|---|
| Next.js App Router | "./app" |
| Vite + React | "src" |
| Monorepo(配合 useDirective) | "." |
翻译质量#
品牌术语使用手动覆盖#
品牌名、产品名和法务文本应使用 manual overrides,而不是依赖 AI 翻译:
<h1 data-lingo-override={{ es: "Motor de Localizacion", de: "Lokalisierungs-Engine" }}>
Localization Engine
</h1>使用 locale-pair mapping 优化成本#
不同模型各有优势,价格也不同。把昂贵的模型分配给真正需要它们的语言,其余场景则使用更具性价比的模型:
{
models: {
"*:*": "groq:llama-3.3-70b-versatile", // Fast, cost-effective default
"*:ja": "anthropic:claude-3-5-sonnet", // Higher quality for Japanese
"*:zh-Hans": "anthropic:claude-3-5-sonnet", // Higher quality for Chinese
},
}使用 Lingo.dev engine 统一术语表和品牌语气#
如果你需要在整个应用中保持术语一致,可在 Lingo.dev 上配置一个包含 glossary 和 brand voice 的 localization engine。这些设置会自动应用到每一次翻译请求中。
复数处理#
不需要时关闭复数处理#
如果你的应用不会在文本旁显示数字计数,可关闭复数处理,以降低构建复杂度:
{
pluralization: { enabled: false },
}自然书写与计数相关的文本#
启用复数处理后,直接以自然方式编写包含数字变量的文本即可。Compiler 会处理到 ICU MessageFormat 的转换:
// Good - the compiler detects and pluralizes this
<p>You have {count} items in your cart</p>
// Also good - works with any numeric expression
<p>{unreadCount} unread messages</p>测试#
先用 pseudotranslator 测试#
在生成真实翻译之前,先使用 pseudotranslator 运行一遍,以验证是否已完整覆盖:
- 启用
dev.usePseudotranslator: true - 遍历每一个页面和组件
- 任何没有
[!!! ... !!!]标记的文本,都还没有被翻译 - 修复文本放置问题(将文本移入 JSX、调整
sourceRoot、添加'use i18n'指令)
用 pseudotranslator 发现未翻译字符串,比等到生成真实翻译后再发现,速度更快、成本也更低。
发布前用真实翻译测试#
发布前,请关闭 pseudotranslator,并至少为一个目标 locale 生成真实翻译:
{
dev: { usePseudotranslator: false },
}检查布局溢出、文本截断,以及伪翻译无法暴露的双向文本问题。
