本文目录导读:

开源项目的本地化与国际化分离,通常遵循代码与翻译内容解耦的原则,核心思路是:国际化(i18n)负责机制,本地化(l10n)负责内容,以下是具体的分离策略和实践方法:
核心分离原则
- 国际化(i18n):在代码中通过抽象层(如
i18n()函数、ICU MessageFormat)标记所有需要翻译的字符串,并定义语言环境(locale)和区域规则(日期、数字格式),这部分由开发者负责。 - 本地化(l10n):将翻译内容(JSON/YAML/PO 文件)与代码分离,由翻译人员、社区或自动化工具(如 Crowdin、Transifex)独立维护,这部分不涉及代码逻辑。
具体实施步骤
步骤1:代码中只保留语言标识符(Key)
-
不要硬编码显示文本,而是使用 Key 或 ID。
-
示例(JavaScript/React):
// 错误:直接写入中文 <button>保存</button> // 正确:使用国际化函数 <button>{i18n('save_button')}</button>
步骤2:将翻译内容放到独立的资源文件中
-
每一门语言一个文件,与代码仓库分离(或位于独立的
locales/目录)。 -
文件结构示例:
locales/ en-US.json zh-CN.json ja-JP.json src/ components/ utils/i18n.js (不包含任何翻译文本) -
en-US.json:{ "save_button": "Save" } -
zh-CN.json:{ "save_button": "保存" }
步骤3:在 CI/CD 或构建时合并
- 开发环境:使用动态加载语言文件(按需加载)。
- 生产环境:通过构建工具(Webpack、Vite)将翻译文件打包成独立 chunk,或预编译为静态资源。
步骤4:为翻译贡献者提供隔离的工作流
- 使用翻译管理系统(TMS)(如 Crowdin、Lokalise、Weblate):
- 开发者只上传 Key 和默认语言(如英文)的字符串。
- 翻译人员在 TMS 上协作,翻译完成后自动生成对应语言文件,并提交 PR 到仓库。
- 避免翻译人员直接修改代码:他们只接触
.po、.json或.xliff文件,不涉及业务逻辑。
常见工具与框架的实现方式
| 语言/框架 | 国际化方法 | 本地化文件格式 | 推荐分离方式 |
|---|---|---|---|
| React/Next.js | react-i18next, next-intl |
JSON / YAML | 使用 locales/ 目录,按语言分文件夹 |
| Vue | vue-i18n |
JSON / YAML | 通过 messages 选项动态导入 |
| Angular | @angular/localize |
XLIFF / JSON | CLDR 数据 + 独立翻译文件夹 |
| Python/Django | gettext, django-i18n |
.po / .mo |
在 locale/ 目录下,每个语言独立的文件夹 |
| Rust | rust-i18n, fluent |
.ftl (Fluent) |
使用 fluent-resources 分离 |
| Kotlin/Android | Android Resources | strings.xml |
按 values-zh、values-ja 目录隔离 |
高级分离:区域规则与翻译内容分离
除了文本翻译,还需要分离:
- 日期/时间格式(短、长、含时区)
- 数字/货币格式(千分位、小数位、货币符号位置)
- 复数规则(零、一、多)
- 方向(RTL/LTR)(阿拉伯语、希伯来语)
推荐做法:
使用 CLDR(通用区域数据仓库)或 ICU 消息格式 来处理规则,而不是在翻译文件中硬编码格式。
避免的陷阱
- ❌ 在翻译文件中包含 HTML 标签或逻辑(应使用组件级抽象)。
- ❌ 将 Key 命名为描述性文本(如
"Welcome to the app"),应使用无歧义 ID(如welcome_app_message)。 - ❌ 在代码中动态拼接翻译(如
i18n(t) + i18n(s)),应使用参数化消息(i18n("greeting", {name}))。
| 职责 | 由谁负责 | 输出 |
|---|---|---|
| 国际化(i18n) | 开发者 | 代码设施、Key 定义、格式规则 |
| 本地化(l10n) | 翻译人员 / 社区 | 语言资源文件(JSON/PO/FTL) |
| 构建与发布 | CI/CD 系统 | 按语言打包、动态加载或独立产物 |
核心目标:修改翻译时无需修改代码,修改代码时无需修改翻译。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播