TMS 平台对比:Crowdin / Phrase / Lokalise
High Contrast
Dark Mode
Light Mode
Sepia
Forest
4 min read852 words

TMS 平台对比:Crowdin / Phrase / Lokalise

核心问题:Translation Management System(TMS)平台能帮你做什么?三大平台各有什么优势?如何接入 GitHub CI/CD?


真实场景

你的产品支持 8 种语言,有 5 名外部翻译人员(来自不同国家),每周约有 200 个新 key 需要翻译。手动管理翻译包已经无法应对:你需要 TMS 平台来自动同步、分配任务、跟踪进度、管理术语表。


为什么需要 TMS

问题 没有 TMS 有 TMS
新翻译分发 手动打包 → 邮件发送 自动同步(GitHub PR 触发)
翻译进度 手动统计 Excel 实时仪表板
术语表 手动维护 Word 文档 翻译界面实时高亮
翻译记忆 无法复用历史翻译 自动复用相似翻译
协作 邮件来回 在线评论、实时协作
机器翻译 手动调用 API 一键 MT,人工后审
代码回流 手动复制粘贴 自动 PR 合并

三大 TMS 平台对比

特性 Crowdin Phrase(原 Phrase Strings) Lokalise
定价模式 按用户 + 字符串 按用户 按项目 + 字符串
免费计划 ✅(开源项目免费) 限制性免费试用 14 天试用
GitHub 集成 ✅ 原生应用
GitLab/Bitbucket
支持的文件格式 60+ 40+ 40+
机器翻译集成 ✅ DeepL/Google/Microsoft
翻译记忆
术语表
QA 检查
API ✅ REST + CLI ✅ REST + CLI ✅ REST + CLI
中文界面
适合场景 开源/中小企业 中大型企业 中大型企业

Crowdin 接入(最流行的选择)

Step 1:配置 crowdin.yml

# crowdin.yml(放在项目根目录)
project_id: "123456"
api_token_env: CROWDIN_API_TOKEN  # 从环境变量读取
files:
# 上传:本地翻译文件 → Crowdin
- source: /src/locales/zh-CN/*.json
translation: /src/locales/%locale%/%original_filename%
# locale 映射(Crowdin locale → 你的文件名)
languages_mapping:
locale:
zh-CN: zh-CN
en-US: en-US
ja-JP: ja-JP
ko-KR: ko-KR
ar-SA: ar-SA
de-DE: de-DE
# 翻译文件中 key 的格式
type: json
# 不要导出未翻译的 key
export_patterns:
ignore: ["/^$/"]    # 空字符串不导出
# 额外设置
commit_message: "feat(i18n): update translations from Crowdin [skip ci]"
pull_request_title: "🌍 New translations from Crowdin"

Step 2:GitHub Actions 自动同步

# .github/workflows/crowdin.yml
name: Crowdin Sync
on:
# 推送到 main 时上传新的源文件
push:
branches: [main]
paths:
- 'src/locales/zh-CN/**'
# 定期下载翻译(每天一次)
schedule:
- cron: '0 9 * * *'  # UTC 09:00 = 北京时间 17:00
workflow_dispatch:  # 手动触发
jobs:
synchronize-with-crowdin:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Upload source files to Crowdin
uses: crowdin/github-action@v2
with:
upload_sources: true
upload_translations: false
crowdin_branch_name: main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_API_TOKEN }}
download-translations:
runs-on: ubuntu-latest
needs: []
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
steps:
- uses: actions/checkout@v4
- name: Download translations from Crowdin
uses: crowdin/github-action@v2
with:
upload_sources: false
upload_translations: false
download_translations: true
# 自动创建 PR 合并翻译
create_pull_request: true
pull_request_base_branch_name: main
pull_request_labels: "translations,automated"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_API_TOKEN }}

Step 3:Crowdin CLI 手动操作

# 安装 Crowdin CLI
npm install -g @crowdin/cli
# 上传源文件
crowdin upload sources
# 下载翻译文件
crowdin download
# 查看翻译进度
crowdin status translation
# 输出:
# en-US:  95% (1187/1250 strings)
# ja-JP:  88% (1100/1250 strings)
# ko-KR:  64% (800/1250 strings)
# 预翻译(使用 TM + MT 自动填充)
crowdin pre-translate \
--method tm \
--auto-approve-option perfectly-match \
--language-ids en-US,ja-JP

Lokalise 接入

Lokalise GitHub App 配置

# .lokalise.yml
project_id: "abc123def456"
file_format: json
# 监听的 branch
branch: main
# 文件映射
upload:
files:
- src/locales/zh-CN/%file_name%.json
download:
destination: src/locales/%lang_iso%/%file_name%.json
lang_map:
zh_CN: zh-CN
en_US: en-US
ja_JP: ja-JP
# Lokalise CLI
npm install -g @lokalise/node-api
# 上传
lokalise2 file upload \
--token $LOKALISE_API_TOKEN \
--project-id $LOKALISE_PROJECT_ID \
--file src/locales/zh-CN/common.json \
--lang-iso zh_CN \
--keys-to-values \
--include-path true
# 下载
lokalise2 file download \
--token $LOKALISE_API_TOKEN \
--project-id $LOKALISE_PROJECT_ID \
--format json \
--dest ./src/locales \
--unzip-to .

完整 CI/CD 翻译工作流

sequenceDiagram participant Dev as 开发者 participant GitHub as GitHub participant Actions as GitHub Actions participant Crowdin as Crowdin participant Trans as 翻译人员 Dev->>GitHub: push 代码(含新 key) GitHub->>Actions: 触发 workflow Actions->>Crowdin: 上传新源文件(zh-CN) Crowdin->>Trans: 通知新字符串待翻译 Trans->>Crowdin: 完成翻译(在线编辑器) Note over Crowdin: 每天定时任务 Actions->>Crowdin: 下载已完成翻译 Crowdin-->>Actions: 返回翻译文件 Actions->>GitHub: 创建 PR(翻译更新) Dev->>GitHub: Review 并合并 PR GitHub->>Actions: 触发部署

翻译记忆和术语表 API

// 通过 API 管理术语表
import crowdinApi from '@crowdin/crowdin-api-client';
const { glossariesApi } = crowdinApi({
token: process.env.CROWDIN_API_TOKEN!,
});
// 批量添加术语
async function updateGlossary(terms: Array<{ source: string; translation: string; locale: string }>) {
const projectId = Number(process.env.CROWDIN_PROJECT_ID);
const glossaries = await glossariesApi.listGlossaries({});
const glossaryId = glossaries.data[0]?.data?.id;
if (!glossaryId) throw new Error('No glossary found');
// 批量添加术语
await glossariesApi.importGlossaryFile(glossaryId, {
storageId: /* upload glossary file */,
});
}
// 从本地术语表同步到 Crowdin
const localGlossary = JSON.parse(fs.readFileSync('glossary/zh-CN-en-US.json', 'utf-8'));
const terms = Object.entries(localGlossary).map(([source, translation]) => ({
source,
translation: translation as string,
locale: 'en-US',
}));
await updateGlossary(terms);

TMS 平台选型建议

团队规模 预算 推荐平台 理由
< 5 人,开源项目 免费 Crowdin 开源免费,中文界面
5-20 人,初创公司 Crowdin Team 性价比高
20-100 人,成长期 Lokalise 功能全面,API 完善
> 100 人,企业 Phrase 企业级功能,合规支持
重视 DeepL 质量 任何(配 DeepL API) 三家都支持 DeepL

常见问题

Q:翻译文件格式不是平台原生支持的怎么办?

A:三大平台都支持 60+ 格式,ICU JSON 和 i18next JSON 都在支持列表中。如果格式确实不支持,可以在上传前用脚本转换。

Q:TMS 平台的翻译员能看到我的产品代码吗?

A:不能。TMS 平台只同步翻译字符串和源文件,不暴露代码库。但翻译字符串本身可能包含产品信息,需要根据 NDA 要求管理翻译员权限。

Q:多个环境(dev/staging/prod)如何处理?

A:通常使用分支策略:main 对应 prod,develop 对应 staging。Crowdin 和 Lokalise 都支持多分支同步。


进入第 07 章:翻译工作流建立好了,接下来处理最容易被忽视的挑战——阿拉伯语、希伯来语等从右到左语言的 RTL 布局和文化适配。

CSS 逻辑属性与 dir="rtl" 布局