本文目录导读:

- 核心理念:将翻译视为代码
- 策略一:手动同步(适合小型项目或个人项目)
- 策略二:自动化提取 + 注释/标签(适合中型项目)
- 策略三:代码与翻译文件紧耦合(适合小规模、静态内容)
- 针对不同代码库的常见方案
- 最短路径:从零开始
这是一个非常核心且棘手的问题,开源项目的翻译(国际化/i18n)与代码同步,本质上是一个持续集成和工作流管理的问题。
没有一种“银弹”能解决所有情况,最佳方案取决于项目的规模、技术栈和翻译贡献者的习惯,以下是几种主流策略,从简单到复杂排列,你可以根据项目情况选择或组合使用。
核心理念:将翻译视为代码
翻译文件(.json, .po, .properties 等)应该和源代码一样:
- 存储在同一个仓库(通常是同一个代码库,或紧耦合的子模块)。
- 接受版本控制(Git)。
- 经过代码审查(Code Review)。
- 通过CI/CD流程自动检查。
手动同步(适合小型项目或个人项目)
流程:
- 开发者修改代码,添加新的可翻译字符串(如
t('new_feature.title'))。 - 开发者运行一个脚本(如
i18n extract),更新翻译模板文件(如en.json或messages.pot),这个模板文件包含了所有需要翻译的源字符串。 - 翻译者手动编辑对应语言的翻译文件(如
zh_CN.json),为新增的字符串添加翻译。 - 当UI中引用这些新字符串的代码被提交并部署后,翻译文件也一并提交。
优点:简单、直接,不需要额外工具。 缺点:
- 容易脱节,开发者可能忘记更新模板文件,或者翻译者没跟上节奏。
- 对新贡献者不友好,需要人工关注变更历史。
- 容易产生“翻译滞后”或“未翻译字符串”。
自动化提取 + 注释/标签(适合中型项目)
这是最推荐的标准做法,核心是“从代码中自动提取字符串”,然后通过代码注释或文件标签来标记翻译。
流程:
-
开发阶段:
- 开发者在代码中直接使用国际化函数或组件,并紧挨着写注释说明上下文或用途。
- 例(React +
react-i18next):// 翻译上下文:首页的欢迎标语 <Trans i18nKey="home.welcome">Welcome!</Trans>
- 例(Python + Flask-Babel):
# 翻译提示: 这是确认删除按钮的文字 _('Confirm Delete')
-
自动化提取(Pre-commit Hook 或 CI 步骤):
- 使用工具(如
i18next-parser,Babel Extract,gettext)扫描源代码,自动生成新的翻译模板(如en.json或messages.pot)。 - 这个工具会直接读取代码中的
t()或<Trans>调用,以及旁边的注释。 - 自动提交:将更新后的模板文件自动提交到仓库。
- 使用工具(如
-
翻译流程:
- 翻译者可手动编辑翻译文件,或使用翻译管理平台(如 Crowdin, Transifex, Weblate, POEditor)。
- 这些平台可以订阅 GitHub/GitLab 仓库的变更,自动拉取最新的模板文件,并显示哪些字符串是新的、已过期的或未翻译的。
- 翻译完成后,平台自动生成更新后的翻译文件,并推回仓库的对应分支,创建 Pull Request。
-
代码审查:
- 开发者在 Review 代码时,也需要 Review 翻译文件的变动。
- 检查:
- 新增的字符串是否正确提取?
- 翻译是否准确(尤其是术语、占位符)?
- 有没有遗漏的翻译?
-
部署:
当含翻译文件的 PR 被合并到主分支后,CI/CD 自动构建并部署,翻译与代码同步生效。
关键工具:
- 提取工具:
i18next-parser(JS),Babel(Python),gettext(通用),GNU xgettext。 - 翻译管理平台:Weblate(开源,可自托管)、Crowdin(商业,易用)、Transifex(商业)、POEditor。
- CI/CD 工具:GitHub Actions, GitLab CI, Jenkins。
优点:自动化程度高,减少了人为错误;翻译者能看到上下文;平台提供协作和审校功能。 缺点:需要一定的工具链设置和维护成本;依赖第三方平台有潜在风险(数据安全、成本)。
代码与翻译文件紧耦合(适合小规模、静态内容)
流程:
-
翻译文件直接内嵌在组件或模块文件夹中,而不是放在全局
locales目录。 -
例 (React +
react-i18next):components/Header文件夹下有:index.jsxen.json(只包含Header组件的翻译)zh_CN.json
-
同步:当开发者修改
index.jsx并新增了需要翻译的字符串时,他必须手动或通过脚本更新本地的en.json,CI 检查其他语言文件是否也同步更新了(比如通过i18next-parser扫描所有此类文件)。
优点:非常局部化,容易理解;适合独立组件库;避免了大的全局翻译文件冲突。 缺点:文件数量爆炸;不利于集中搜索和审查所有翻译;翻译者需要逐个打开文件修改。
针对不同代码库的常见方案
| 技术栈 | 推荐方案 | 具体工具 | 备注 |
|---|---|---|---|
| JavaScript/React/Vue | 策略二(自动化+平台) | i18next-parser + react-i18next + Crowdin/Welate |
最成熟的生态 |
| Python (Django/Flask) | 策略二(自动化+平台) | Django 的 makemessages, Babel + Transifex |
经典做法 |
| Java/Spring Boot | 策略一/二 | Properties 文件 + i18n-mybatis + 手动提取 |
通常手动或脚本提取 |
| Go | 策略二 | gotext + i18n (go-i18n v2) + 手动提交 |
|
| .NET | 策略二 | Resx 文件 + .xlf 格式 + ResX Resource Manager |
- 将翻译文件视为一等公民:它们和代码一样,需要被版本控制、代码审查、自动化处理。
- 自动化提取是基石:永远不要让开发者手动维护翻译列表,使用
i18next-parser或类似工具自动从代码中提取。 - 用平台解决协作:对于有多个翻译者的项目,使用 Crowdin/Weblate 等平台,它们能自动追踪字符串变化,提供上下文和评论,并自动同步回仓库。
- CI 检查:在 CI 中运行检查,确保:
- 所有语言文件的键与模板一致。
- 没有未翻译的字符串(根据需要设置)。
- 占位符(如
%s,{name})在不同语言中正确匹配。
- 为翻译者提供上下文:在代码中写注释(
// 翻译上下文: xxx),或利用翻译平台的“上下文”字段,这是解决“翻译质量”的关键。 - 不要破坏代码结构:翻译文件的结构应该合理(按模块、页面或组件划分),便于查找和维护。
最短路径:从零开始
- 选择一个支持自动提取的国际化库(如
react-i18next+i18next-parser)。 - 配置
i18next-parser,让它扫描你的src目录,生成locales/en/translation.json。 - 将
en.json和zh_CN.json等文件提交到 Git。 - 在
package.json中添加脚本:"extract": "i18next-parser"
- 每次修改代码后,运行
npm run extract,然后提交en.json的更改。 - 人工或通过平台维护
zh_CN.json。
通过这种方式,你至少能保证 en.json(源语言)永远与代码同步,其他语言的同步则取决于你的工作流是否跟得上。