第一次在 Angular 框架上落地国际化方案,将 Eoapi 的经验分享给大家~
1. 项目背景
- 需要支持 Web 和 Electron 桌面端
- 技术栈
- Angular 14
- Electron 19
- NG-ZORR 13.0.6
2. 可能遇到的困难
- 各语言下样式不统一,例如阿拉伯文字展示从右到左,英文比中文长等等
- 变量本地化,例如初始化 API 数据、日志、时间戳、金额等单位
- 翻译成本高
- 协作流程复杂
- 技术标准的制定、落地
3. 调研
3.1 结论
先上表格看结论,满分三颗星,最终选定 I18n 方案。
一直在运行时语言包和编译手段两种方案徘徊,最后还是选定了使用 I18n 方案,有以下几点考虑:
- 对代码侵入性低,不影响现有开发模式
- 方案成熟,经过 angular 团队/社区验证,提前考虑到了各种条件
- 生成的文件 xlf 遵循国际规范 XLIFF,较通用,即使技术变迁,语言包仍通用
虽然无法支持同一个 URL 动态切换语言包,多套代码方案在桌面端实现不常规(可能需要把各种语言的安装包打进去),但考虑需求上切换语言包是一个超低频的操作以及使用编译手段可以提高良好的开发体验,还是为 i18n 方案所折服。
其实无论是运行时方案和编译手段,只要官方支持,完全可以实现相互转换,期待后续 Angular 支持将语言包反向编译成代码后支持动态切换语言包,那就是我理想中的完美方案了。
3.2 分析
3.2.1 在线翻译
API切换语言包的时候再调用 OpenAPI 翻译当前页面,类似于 google 翻译。
实现难度一般,只要实现了此工具,可以兼容各种语言。
翻译 API 不一定稳定,同时免费的有次数限制,适合表达精确度要求不高,需要支持多语言的静态页。
3.2.2 自研语言编译器
使用编译手段提取,例如识别到代码中的中文,提取出来成为语言包,打包的时候
感兴趣可以看这篇,原理类似:https://juejin.cn/post/6844904042489970695#heading-3
不改变原有开发的模式,没有学习成本。
对代码有一定的侵入性,同时针对不同母语的代码有不同的语言匹配规则。
自研的实现成本较高,可能无法配合市面上热门翻译平台打通流程,工具生态成熟需要时间沉淀。
3.2.3 Angular I18n
方案https://angular.cn/guide/i18n-overview
和自研编译提取语言文本类似,使用一些标识符标记哪些字段需要翻译,同时提供一些额外的附加规则,例如同词不同含义的标记。
较为成熟,代码侵入性低,有一定的开发学习成本。
官方文档推荐的实践都是不同的语言包打包成不同的代码,然后通过 nginx 映射到不同的代码,这适合 web,但在桌面端实现比较麻烦,无法动态加载文件。
理想情况是 angular 方案下支持一套代码加载语言包的国际化方案(one bundle for all languages),官方关于动态切换语言包的讨论:
https://github.com/angular/angular/issues/24549#issuecomment-398371120
https://github.com/angular/angular/issues/38953#issuecomment-862492065
截至本方案完成,Angular 只支持打包成多种语言包文件,动态切换语言包目前处于提案通过阶段,未来可期。
3.2.4 运行时语言包
支持 Angular 的方案有:
- http://www.ngx-translate.com/
- https://ngneat.github.io/transloco/docs/translation-in-the-template
- https