findxc / blog

88 stars 5 forks source link

Angular 项目怎么实现国际化 #76

Open findxc opened 2 years ago

findxc commented 2 years ago

一个项目支持国际化一般会需要以下步骤:

  1. 根据项目代码提取需要翻译的文本
  2. 把文本上传到 TMS ,也就是翻译管理系统,进行翻译
  3. 把翻译后的文本同步到项目代码中,或者在打包时才去拉取,项目本身不维护其它语言文本

关于 TMS

Do You Really Need a Translation Management System? - Rubric 这里有对 TMS 的介绍。简单来说, TMS 是关于国际化的流程的工具,比如你可以通过命令行来上传文件,你可以在界面上先一键机器翻译,然后再校对和审核,可以在界面上指派翻译人员和查看翻译进度,最后可以通过命令行来下载文件。

现在各种 TMS 很多,比如 A Comparison of the 15 Best Translation Management Systems - Rubric 这里列举了 15 个。由于选项太多,并且无 TMS 使用经验,短时间内无法一一分析各自优缺点,所以我们选一个看起来没坑的即可,比如 Crowdin

Projects search - Crowdin 上面也可以发现一些你知道的应用,比如:

Angular 项目实施国际化的大概步骤

第一步,在代码中标记哪些是需要国际化的

ng add @angular/localize ,然后再用 i18n i18n-xxx $localize 标记代码,详见 https://angular.io/guide/i18n-common-prepare ,下面是几个简单例子。

<div class="xsp-h1-title" i18n>Welcome to SuiteSpot™</div>

<img src="./logo.png" i18n-title title="Angular logo" />

title = $localize`hello world`;
<div>{{ title }}</div>

第二步,生成待翻译文件

使用 ng extract-i18n 即可生成,详见 https://angular.io/guide/i18n-common-translation-files#extract-the-source-language-file

第三步,集成 Crowdin ,用命令行上传源语言文件和下载翻译后文件

详见 https://support.crowdin.com/cli-tool/

先在 Crowdin 上创建一个项目,然后在界面的 Tools - API 可以看到一个 Project Id 值,后面会用到。

E0A3D2BA-960C-40AF-923B-937F320D4A37

还要去账号的 Settings - API 生成一个 token ,然后把环境变量 CROWDIN_PERSONAL_TOKEN 的值设为这个 token 。

547F3FA9-29E6-44E2-847D-E266F270DAE3

然后 npm i @crowdin/cli ,然后在 package.jsonscripts 中补充 "crowdin": "crowdin" ,然后执行 npm run crowdin -- init 来生成一份初始配置,初始化时选择不授权,后面通过增加配置项 "api_token_env" : "CROWDIN_PERSONAL_TOKEN" 来从环境变量中读取 token 。

然后再配置下 crowdin.yml 的 source 和 translation 即可,如下是一个示例。

# 上传时,源语言所在路径
"source" : "/src/i18n/en-US/*",
# 下载时,翻译的语言存放的路径
"translation" : "/src/i18n/%locale%/%original_file_name%",

然后就可以 npm run crowdin -- upload 来上传文件了,然后 npm run crowdin -- download 来下载翻译后的文件。

补充, Crowdin 支持一键机器翻译,也支持每次上传新内容时自动先机器翻译,详见 Pre-Translation via Machine | Crowdin Documentation

732CB3DB-42BB-4472-A999-1D954468E2CE

第四步,打包时生成多份语言对应的包

修改 angular.json ,在 architect.build.configurations.production 下增加 "localize": true ,然后在 projects.xxx 下增加:

"i18n": {
  "sourceLocale": "en-US",
  "locales": {
    "zh-CN": "src/i18n/zh-CN/messages.xlf",
    "es-ES": "src/i18n/es-ES/messages.xlf",
    "fr-FR": "src/i18n/fr-FR/messages.xlf"
  }
}

然后再参照 Internationalization | NG-ZORRO 来配置 antd 的国际化。

这样配置完后,本地开发是默认语言,打包后是多种语言。打包后目录如下所示,一个语言对应一个目录。

EEECFBEC-5E83-4B81-AA4A-30ECA6226DD8

其它资料

Docusaurus 文档上不建议把翻译后的文件保存在代码仓库中,因为 Crowdin 对并发的上传/下载支持不够好。

Crowdin does not support well multiple concurrent uploads/downloads: it is preferable to only include translations to your production deployment, and keep deploy previews untranslated.

所以我们实际应用时,想稳妥点的话,就是在打包时才去上传和下载,可以参照 Jest 官网的打包命令,先执行 netlify:crowdin 来同步 crowdin 数据再 yarn build

"netlify:ci:production": "yarn netlify:prepare && yarn netlify:crowdin && yarn build",
"netlify:prepare": "yarn fetchSupporters && yarn build:js",
"netlify:crowdin": "yarn write-translations && yarn crowdin:upload && yarn crowdin:download"