工作原理
@lingo.dev/compiler 通过智能代码分析和 AI 驱动的翻译,在构建时将您的 React 应用转化为多语言应用。
构建时转换
传统的运行时 i18n 库(如 i18next、react-intl)在应用运行时加载翻译、插值变量并格式化消息。这会增加包体积、运行时开销和实现复杂度。
@lingo.dev/compiler 的工作方式不同:它在构建过程中转换您的代码。您的 React 组件保持简洁,翻译内容会被预编译为优化后的包。
结果: 零运行时开销、更小的包体积,无需手动管理翻译键。
流程说明
1. AST 分析
编译器使用 Babel 将您的 React 代码解析为抽象语法树(AST)。它遍历 JSX,识别可翻译内容:
- 文本节点(
<p>Hello</p>) - 字符串属性(
<img alt="Logo" />) - 模板表达式中的文本(
<p>Hello {name}</p>)
编译器理解 React 组件边界,并维护上下文信息以确保翻译准确。技术标识符、代码片段和不可翻译元素会被自动过滤。
2. 内容提取
对于每个可翻译字符串,编译器会:
- 生成稳定的哈希标识符
- 保留组件上下文(文件、位置、周边元素)
- 提取富文本结构(可处理嵌套元素,如
<strong>和<em>) - 保持插值占位符
这些元数据会存储在 .lingo/metadata.json —— 一个用于追踪应用中所有可翻译内容的版本化文件中。
3. 翻译生成
在开发过程中,翻译服务器会按需处理翻译:
- 伪翻译模式(默认):即时生成假翻译,便于查看哪些内容会被翻译且无需 API 成本
- 真实翻译模式:调用您配置的 LLM 提供商(Lingo.dev Engine 或直接 LLM)
该翻译服务是无状态的,并能优雅地处理部分失败——即使部分翻译失败,仍会使用已缓存的翻译。
4. 代码注入
编译器会将翻译查找自动注入到你的 JSX 中:
// Your source code
<p>Hello {name}</p>
// Transformed code (simplified)
<p>{t('abc123', { name })}</p>
t() 函数经过优化并会自动注入。它会在预加载的翻译字典中基于哈希进行查找。
5. 包优化
构建时:
- 会为每个语言环境生成独立的包
- 只包含实际用到的翻译
- 未使用的翻译会被消除(dead code elimination)
- 字典会按组件进行 tree-shaking
开发工作流
开发模式
{
dev: {
usePseudotranslator: true,
}
}
当你运行 npm run dev 时:
- 编译器会启动一个翻译服务器(自动查找 60000-60099 端口)
- 你的应用会向服务器请求翻译
- 伪翻译器会即时生成假翻译
- 翻译会缓存在
.lingo/metadata.json中 - HMR 正常工作——状态会被保留
开发小部件(如启用)允许你在浏览器中编辑翻译并实时查看更改。
生产模式
{
buildMode: "cache-only",
}
当你运行 npm run build 时:
- 不会启动翻译服务器
- 只会使用
.lingo/metadata.json中的缓存翻译 - 如果有翻译缺失,构建会失败并给出明确错误
- 不会发起 API 调用——无需 API key
为什么只用缓存? 在生产环境下,你需要确定性的构建。翻译应在 CI 阶段(有 API key)生成,而不是在生产构建时生成。
推荐工作流
本地开发:
- 使用伪翻译器
- 快速反馈
- 无 API 成本
CI/CD:
{
buildMode: "translate",
dev: {
usePseudotranslator: false,
}
}
- 生成真实翻译
- 每次部署时运行一次
- 提交
.lingo/变更
生产构建:
{
buildMode: "cache-only",
}
- 使用预生成的翻译
- 无需 API 密钥
- 构建速度快且结果可预测
架构
编译器围绕关注点分离进行组织:
元数据管理器
- 针对
.lingo/metadata.json进行 CRUD 操作 - 文件锁保证线程安全
- 基于哈希的翻译标识符
翻译服务
- 协调翻译工作流
- 处理缓存策略
- 管理部分失败情况
- 返回成功和失败的翻译结果
翻译器(无状态)
- 伪翻译器:即时生成假翻译
- LCP Translator:集成 Lingo.dev 引擎
- LLM Translator:直接集成第三方服务商
- 不自带缓存——由服务层统一处理
翻译服务器
- 用于开发的 HTTP 服务器
- 支持 WebSocket 实时小部件更新
- 自动端口管理
- 批量请求处理
实现细节请参见 源代码架构文档。
框架集成
Next.js
编译器通过 withLingo() 封装集成:
- 支持 Webpack 和 Turbopack
- 兼容 React Server Components
- 异步配置,支持插件懒加载
- 自动基于 locale 的路由(如已配置)
Vite
编译器通过 lingoCompilerPlugin 集成:
- 基于 unplugin(兼容 Vite、Webpack、Rollup)
- 完全支持 HMR
- 高效的开发服务器集成
- 自动生成虚拟模块
常见问题
支持 Server Components 吗? 支持。在 Next.js 中,编译器会转换 Server 和 Client Components。翻译查找可同构运行。
如何处理代码分割? 翻译会随组件自动分割。每个 chunk 只包含所需的翻译内容。
翻译如何缓存?
所有翻译都存储在 .lingo/metadata.json 文件中。该文件受版本控制,作为翻译缓存。编译器采用内容哈希,只有新增或变更的文本才会触发重新翻译。
如果翻译失败怎么办? 服务会返回部分结果。成功的翻译会被缓存并直接使用,错误会带有上下文记录到日志以便调试。您的应用不会崩溃——它会回退到已缓存的翻译或源文本。
我可以查看转换后的代码吗?
可以。在构建输出中,查找已转换的文件。转换非常轻量——仅包含 t() 函数调用和基于哈希的查找。