Lingo.dev CLI 通过已配置的 .stringslocalization engine 翻译原生移动端资源文件——包括 Xcode 、Android XML、Flutter ARB 和 React Native JSON。CLI 会根据文件扩展名自动识别格式,保留原有结构,并原生支持复数处理。
平台概览#
| 平台 | 原生格式 | 典型的源文件路径 |
|---|---|---|
| iOS (Xcode) | .strings | en.lproj/Localizable.strings |
| iOS (Xcode) | .stringsdict | en.lproj/Localizable.stringsdict |
| iOS (Xcode) | .xcstrings | Localizable.xcstrings |
| Android | strings.xml | app/src/main/res/values/strings.xml |
| Flutter | .arb | lib/l10n/app_en.arb |
| React Native | .json | src/locales/en.json |
准备工作#
每次运行 CLI 时,内容都会经过一个本地化引擎——它决定采用哪个 LLM 模型,以及应用哪套术语表、品牌语气和规则。你可以在 Lingo.dev 控制面板中创建。
安装 CLI(Node.js 22+)并完成认证:
npm install -g @lingo.dev/cli
lingo loginlingo login 会通过一次性验证码让你登录。在 CI 中,请跳过交互式登录,直接传入 --api-key(或设置 LINGO_API_KEY)。
配置你的平台#
运行 lingo init 创建 .lingo/config.json(源/目标语言区域以及文件模式),再运行 lingo link 关联你的 orgId 和 engineId。然后将 .lingo/config.json 提交到代码仓库。下面的示例展示了各个平台最终生成的配置。
该模式始终指向你的源文件,CLI 会据此推导出每个目标路径。通常,这意味着替换路径中的语言区域(en.lproj → de.lproj,app_en.arb → app_de.arb)。不过有两个平台例外,好在 CLI 都会自动处理:String Catalog 会将所有语言区域放在同一个文件里,因此目标路径与源路径相同;而 Android 会把默认字符串放在不带任何语言区域的无限定 values/ 中,因此 CLI 会为它追加目标限定符(values/ → values-de/)。
Xcode 支持三种本地化格式。请选择与你的项目配置相匹配的那一种。
字符串目录(.xcstrings)——这是 Xcode 15 引入的现代 Xcode 格式。单个 JSON 文件包含所有语言环境,新增字符串时,Xcode 也会自动更新它。CLI 会直接原地修改这个文件,因此文件模式只需指向这一个目录文件,无需包含语言环境片段。
{
"orgId": "org_...",
"engineId": "eng_...",
"sourceLocale": "en",
"targetLocales": ["es", "fr", "de", "ja"],
"files": [{ "pattern": "MyApp/Localizable.xcstrings" }]
}传统 .strings 文件——每个语言环境在 [code].lproj/ 目录中对应一个文件。源语言环境位于路径中(en.lproj),CLI 会将每个目标语言环境写入各自的 .lproj 目录。如果你的项目还使用 .stringsdict 处理复数形式,请再添加一条 files 配置。
{
"orgId": "org_...",
"engineId": "eng_...",
"sourceLocale": "en",
"targetLocales": ["es", "fr", "de", "ja"],
"files": [
{ "pattern": "MyApp/en.lproj/Localizable.strings" },
{ "pattern": "MyApp/en.lproj/Localizable.stringsdict" }
]
}如果项目的开发语言 bundle 是 Base.lproj 而不是 en.lproj,也同样适用——CLI 会将 Base.lproj 识别为源语言区域。
如需搭建 Xcode 的国际化基础设施,请参阅 Apple 的 本地化文档。
运行翻译#
只需一条命令,即可翻译所有资源文件:
lingo pushCLI 会读取你的源语言环境文件,借助你已提交的 lockfile(.lingo/lock.json)计算自上次运行以来的变更,只翻译增量内容,并将结果写入目标语言环境文件。
首次运行时——或每次新增目标语言环境时——请从头开始翻译全部内容:
lingo push --backfill-missing如果项目里包含多种资源类型,可通过传入 glob 来指定某个平台(没有 --bucket 或 --target-locale 标志)。模式是按源路径匹配的,因此应按源文件而不是目标文件来限定范围:
lingo push "app/src/main/res/values/strings.xml"
lingo push "MyApp/Localizable.xcstrings"如果你想在别处获取最新翻译(例如在另一台机器上),请运行 lingo pull。如果你想在不写入变更的情况下验证翻译是否为最新状态——这很适合作为部署门禁——请运行 lingo check。
复数形式与平台约定#
不同移动平台处理复数形式的方式各不相同——iOS 使用 .stringsdict 或 String Catalog 规则,Android 使用 <plurals> XML 元素,而 Flutter 则在 ARB 文件中使用 ICU MessageFormat。CLI 会在翻译过程中保留各平台原生的复数结构,并为每个目标语言区域生成正确的复数类别。
在 CI 中实现自动化#
保持翻译始终最新的推荐方式是使用 Lingo.dev GitHub App。它在服务端运行,读取你已提交的 .lingo/config.json 和 engineId,并自动发起翻译更新——你无需自己管理 runner、secret 或 lockfile。如果你更希望在自有流水线中运行翻译,请在 CI runner 中执行 lingo push 并提交结果。
