Skip to main content

无需 TMS 的持续本地化

代码持续部署,译文也应如此。以下介绍如何在开发工作流中自动完成本地化。

什么是持续本地化?

持续本地化是指在开发工作流中自动翻译新字符串,而不是定期批量发布译文。开发者添加包含 UI 字符串的新功能时,这些字符串会在功能发布前完成翻译。

传统方式

大多数团队会批量处理翻译:收集新字符串、导出到 TMS、等待译员、导入结果,再发布。这会形成本地化瓶颈,让国际版本延迟数天或数周。

1

开发者向源语言文件添加新字符串

2

导出字符串并上传到 TMS 平台

3

通知译员并开始翻译

4

审核并批准译文

5

下载翻译文件并合并回项目

6

功能随译文一起发布(数天至数周后)

Days to weeks

IDE 原生方式

使用 IDE 原生翻译时,开发者会在日常编码工作流中完成字符串翻译。无需导出、上传或等待,翻译与开发在同一会话中完成。

1

开发者向源语言文件添加新字符串

2

开发者让 AI 助手翻译文件

3

翻译文件直接写入项目

4

功能和译文在同一提交中发布

Same commit

传统方式

6 steps

Multiple tools and platforms

Days to weeks per cycle

IDE 原生方式

4 steps

Inside your editor

Same commit

3

设置翻译管线

如果团队希望在 IDE 之外实现自动翻译,可添加 CI/CD 步骤,在每次推送到 main 时翻译新增或变更的字符串。GitHub Actions、GitLab CI 或任何 CI/CD 系统都支持这种方式。

小型团队可先使用 IDE 原生翻译。当团队超过 3-4 名开发者,或需要确保每次合并到 main 时都有译文,再添加 CI/CD 自动化。

在现有 CI/CD 管线中添加翻译步骤。翻译会在构建成功后、部署前运行,确保每个版本都包含最新译文。
.github/workflows/translate.yml
# .github/workflows/translate.yml
name: Translate
on:
  push:
    branches: [main]
    paths: ['locales/en/**']

jobs:
  translate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Translate changed strings
        run: |
          npx i18n-agent translate locales/en.json \
            --to de,ja,es,fr,ko,zh-Hans \
            --api-key ${{ secrets.I18N_AGENT_API_KEY }}

      - name: Commit translations
        run: |
          git config user.name "github-actions"
          git config user.email "[email protected]"
          git add locales/
          git diff --cached --quiet || git commit -m "chore: update translations"
          git push
.gitlab-ci.yml
# .gitlab-ci.yml
translate:
  stage: deploy
  only:
    changes:
      - locales/en/**
  script:
    - npx i18n-agent translate locales/en.json
        --to de,ja,es,fr --api-key $I18N_AGENT_API_KEY
    - git add locales/ && git commit -m "chore: translations" && git push
4

向 CI 添加翻译 QA

CI 管线中的自动检查会在问题进入生产环境前发现缺失译文、损坏的占位符和无效 ICU 消息格式。这些简单脚本会将源语言文件与所有目标语言进行比较。

如果没有 CI 级翻译验证,缺失译文会悄然进入生产环境。用户看到的是 "settings.title" 等原始键或空字符串,而不是译文。花 5 分钟执行 CI 检查即可完全避免此问题。
check-translations.sh
#!/bin/bash
# check-translations.sh — Run in CI to catch missing translations

SOURCE="locales/en.json"
LANGS=("de" "ja" "es" "fr")
EXIT_CODE=0

# Extract all keys from source
SOURCE_KEYS=$(jq -r '[paths(scalars)] | map(join(".")) | .[]' "$SOURCE" | sort)
SOURCE_COUNT=$(echo "$SOURCE_KEYS" | wc -l)

for lang in "${LANGS[@]}"; do
  TARGET="locales/$lang.json"
  if [ ! -f "$TARGET" ]; then
    echo "❌ Missing: $TARGET"
    EXIT_CODE=1
    continue
  fi

  TARGET_KEYS=$(jq -r '[paths(scalars)] | map(join(".")) | .[]' "$TARGET" | sort)
  MISSING=$(comm -23 <(echo "$SOURCE_KEYS") <(echo "$TARGET_KEYS"))

  if [ -n "$MISSING" ]; then
    COUNT=$(echo "$MISSING" | wc -l)
    echo "❌ $lang: $COUNT missing keys"
    echo "$MISSING" | head -5
    EXIT_CODE=1
  else
    echo "✅ $lang: all $SOURCE_COUNT keys present"
  fi
done

exit $EXIT_CODE
check-placeholders.sh
#!/bin/bash
# check-placeholders.sh — Validate placeholder consistency

SOURCE="locales/en.json"
LANGS=("de" "ja" "es")

for lang in "${LANGS[@]}"; do
  TARGET="locales/$lang.json"

  # Compare placeholders like {{name}}, {count}, %s, %d
  jq -r 'paths(scalars) as $p | [($p | join(".")), (getpath($p))]
    | @tsv' "$SOURCE" | while IFS=$'\t' read -r key value; do
    SOURCE_PH=$(echo "$value" | grep -oE '\{\{[^}]+\}\}|%[sd@]' | sort)
    TARGET_VAL=$(jq -r "getpath($(echo $key | jq -R 'split(".")'))" "$TARGET")
    TARGET_PH=$(echo "$TARGET_VAL" | grep -oE '\{\{[^}]+\}\}|%[sd@]' | sort)

    if [ "$SOURCE_PH" != "$TARGET_PH" ]; then
      echo "❌ $lang/$key: placeholder mismatch"
      echo "   Source: $SOURCE_PH"
      echo "   Target: $TARGET_PH"
    fi
  done
done

在 CI 中验证译文

将 i18n-validate 添加到 CI 管线,自动发现缺失键、损坏的占位符和复数问题。使用 i18n-pseudo 生成伪译文,以进行视觉回归测试。
5

检测并处理译文漂移

源字符串发生变化而译文未更新时,就会出现译文漂移。例如,英语已改为 "Save changes",德语却仍显示旧文本。漂移检测会比较源文件与翻译文件的时间戳或内容哈希。

过时译文比缺失译文更糟。缺失译文显然不对,用户会看到键或回退语言;过时译文却会煞有介事地表达错误内容,可能误导用户或引发支持问题。
detect-drift.sh
#!/bin/bash
# detect-drift.sh — Find stale translations

SOURCE="locales/en.json"
SOURCE_HASH=$(md5sum "$SOURCE" | cut -d' ' -f1)
HASH_FILE=".translation-hashes"

# Compare current source hash with stored hash
if [ -f "$HASH_FILE" ]; then
  STORED_HASH=$(grep "^en:" "$HASH_FILE" | cut -d: -f2)
  if [ "$SOURCE_HASH" != "$STORED_HASH" ]; then
    echo "⚠️  Source strings changed since last translation"
    echo "   Run translations to update all locales"

    # Show which keys changed
    git diff HEAD~1 "$SOURCE" | grep '^[+-]' | grep -v '^[+-][+-]'
  fi
fi

# Update stored hash
echo "en:$SOURCE_HASH" > "$HASH_FILE"
6

选择翻译方式

并非所有内容都需要相同翻译方式。UI 字符串和标签很适合 AI 翻译;营销文案适合 AI 加人工审核;法律和合规文本则应始终交由专业人工译员。

AI 翻译能以生产级质量处理普通应用中 80% 以上的字符串。人工译员应专注于法律文本、品牌语气和文化敏感内容,因为这些内容最需要细腻把握。
Cost Comparison
Translation Approach Comparison:

Content Type         | Approach          | Cost/word  | Quality
─────────────────────┼───────────────────┼────────────┼──────────
UI strings, labels   | AI/LLM            | $0.001-01  | Production
Tooltips, help text  | AI/LLM            | $0.001-01  | Production
Marketing copy       | AI + human review | $0.05-0.15 | High
Legal / compliance   | Human translator  | $0.15-0.40 | Certified
Brand voice content  | Human translator  | $0.20-0.50 | Premium
7

翻译的 Git 工作流

请在合并前于功能分支上完成翻译,而不是合并后再做。这样能确保每次合并到 main 时都包含完整译文。添加合并前检查,验证所有受支持语言的翻译完整性。

多个分支同时修改大型 JSON 本地化文件时,会频繁产生合并冲突。按字母顺序排列键,并让每行只包含一个键,以减小差异并简化冲突解决。

翻译文件与代码一同存放在仓库中,接受版本控制,可在拉取请求中审核,并通过与其他内容相同的管线部署。
.gitattributes + package.json
# .gitattributes — reduce merge conflicts in locale files
locales/*.json merge=union

# Sort keys alphabetically to minimize diffs:
# package.json script:
"sort-locales": "node -e \"
  const fs = require('fs');
  const f = process.argv[1];
  const d = JSON.parse(fs.readFileSync(f));
  const s = (o) => Object.keys(o).sort().reduce((r,k) =>
    ({...r, [k]: typeof o[k]==='object' ? s(o[k]) : o[k]}), {});
  fs.writeFileSync(f, JSON.stringify(s(d), null, 2)+'\\n');
\""

常见问题

把本地化当作开发后工作

最大的错误是等开发完成后才翻译。这会造成瓶颈、推迟发布,并让翻译沦为事后补救。请在开发过程中翻译,而不是开发后再做。

缺少 CI 级翻译验证

没有自动检查时,缺失译文、损坏的占位符和无效格式会进入生产环境。请在 CI 管线中加入完整性和格式验证。

使用 TMS 过度设计

TMS 原本用于管理人工译员工作流。如果使用 AI 翻译,可能根本不需要承担 TMS 开销。先从简单方式开始,在 IDE 或 CI/CD 中翻译;只有确实需要管理人工译员时再加入 TMS。

未跟踪译文新鲜度

不跟踪新鲜度,就无法知道哪些译文已经过时。源字符串发生变化,旧译文却继续存在。请在工作流中加入漂移检测,以发现过时内容。

立即试用 i18n Agent

将翻译文件拖放到此处

JSON, YAML, PO, XML, CSV, Markdown, Properties

或点击选择文件

目标语言

无需注册即时估价

常见问题