开源项目的翻译版本如何与代码同步

wen 开源项目 1

本文目录导读:

开源项目的翻译版本如何与代码同步

  1. 核心理念:将翻译视为代码
  2. 策略一:手动同步(适合小型项目或个人项目)
  3. 策略二:自动化提取 + 注释/标签(适合中型项目)
  4. 策略三:代码与翻译文件紧耦合(适合小规模、静态内容)
  5. 针对不同代码库的常见方案
  6. 最短路径:从零开始

这是一个非常核心且棘手的问题,开源项目的翻译(国际化/i18n)与代码同步,本质上是一个持续集成工作流管理的问题。

没有一种“银弹”能解决所有情况,最佳方案取决于项目的规模、技术栈和翻译贡献者的习惯,以下是几种主流策略,从简单到复杂排列,你可以根据项目情况选择或组合使用。

核心理念:将翻译视为代码

翻译文件(.json, .po, .properties 等)应该和源代码一样:

  • 存储在同一个仓库(通常是同一个代码库,或紧耦合的子模块)。
  • 接受版本控制(Git)。
  • 经过代码审查(Code Review)。
  • 通过CI/CD流程自动检查。

手动同步(适合小型项目或个人项目)

流程:

  1. 开发者修改代码,添加新的可翻译字符串(如 t('new_feature.title'))。
  2. 开发者运行一个脚本(如 i18n extract),更新翻译模板文件(如 en.jsonmessages.pot),这个模板文件包含了所有需要翻译的源字符串。
  3. 翻译者手动编辑对应语言的翻译文件(如 zh_CN.json),为新增的字符串添加翻译。
  4. 当UI中引用这些新字符串的代码被提交并部署后,翻译文件也一并提交。

优点:简单、直接,不需要额外工具。 缺点

  • 容易脱节,开发者可能忘记更新模板文件,或者翻译者没跟上节奏。
  • 对新贡献者不友好,需要人工关注变更历史。
  • 容易产生“翻译滞后”或“未翻译字符串”。

自动化提取 + 注释/标签(适合中型项目)

这是最推荐的标准做法,核心是“从代码中自动提取字符串”,然后通过代码注释文件标签来标记翻译。

流程:

  1. 开发阶段

    • 开发者在代码中直接使用国际化函数或组件,并紧挨着写注释说明上下文或用途。
    • 例(React + react-i18next):
      // 翻译上下文:首页的欢迎标语
      <Trans i18nKey="home.welcome">Welcome!</Trans>
    • 例(Python + Flask-Babel):
      # 翻译提示: 这是确认删除按钮的文字
      _('Confirm Delete')
  2. 自动化提取(Pre-commit Hook 或 CI 步骤)

    • 使用工具(如 i18next-parser, Babel Extract, gettext)扫描源代码,自动生成新的翻译模板(如 en.jsonmessages.pot)。
    • 这个工具会直接读取代码中的 t()<Trans> 调用,以及旁边的注释。
    • 自动提交:将更新后的模板文件自动提交到仓库。
  3. 翻译流程

    • 翻译者可手动编辑翻译文件,或使用翻译管理平台(如 Crowdin, Transifex, Weblate, POEditor)。
    • 这些平台可以订阅 GitHub/GitLab 仓库的变更,自动拉取最新的模板文件,并显示哪些字符串是新的、已过期的或未翻译的。
    • 翻译完成后,平台自动生成更新后的翻译文件,并推回仓库的对应分支,创建 Pull Request。
  4. 代码审查

    • 开发者在 Review 代码时,也需要 Review 翻译文件的变动。
    • 检查:
      • 新增的字符串是否正确提取?
      • 翻译是否准确(尤其是术语、占位符)?
      • 有没有遗漏的翻译?
  5. 部署

    当含翻译文件的 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.jsx
    • en.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
  1. 将翻译文件视为一等公民:它们和代码一样,需要被版本控制、代码审查、自动化处理。
  2. 自动化提取是基石:永远不要让开发者手动维护翻译列表,使用 i18next-parser 或类似工具自动从代码中提取。
  3. 用平台解决协作:对于有多个翻译者的项目,使用 Crowdin/Weblate 等平台,它们能自动追踪字符串变化,提供上下文和评论,并自动同步回仓库。
  4. CI 检查:在 CI 中运行检查,确保:
    • 所有语言文件的键与模板一致。
    • 没有未翻译的字符串(根据需要设置)。
    • 占位符(如 %s, {name})在不同语言中正确匹配。
  5. 为翻译者提供上下文:在代码中写注释(// 翻译上下文: xxx),或利用翻译平台的“上下文”字段,这是解决“翻译质量”的关键。
  6. 不要破坏代码结构:翻译文件的结构应该合理(按模块、页面或组件划分),便于查找和维护。

最短路径:从零开始

  1. 选择一个支持自动提取的国际化库(如 react-i18next + i18next-parser)。
  2. 配置 i18next-parser,让它扫描你的 src 目录,生成 locales/en/translation.json
  3. en.jsonzh_CN.json 等文件提交到 Git。
  4. package.json 中添加脚本:
    "extract": "i18next-parser"
  5. 每次修改代码后,运行 npm run extract,然后提交 en.json 的更改。
  6. 人工或通过平台维护 zh_CN.json

通过这种方式,你至少能保证 en.json(源语言)永远与代码同步,其他语言的同步则取决于你的工作流是否跟得上。

抱歉,评论功能暂时关闭!