超详细的 Angular 国际化方案

第一次在 Angular 框架上落地国际化方案,将 Eoapi 的经验分享给大家~

1. 项目背景

  1. 需要支持 Web 和 Electron 桌面端
  2. 技术栈
  • 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
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于 Angular国际化翻译,可以使用 Angular 提供的内置模块 `@angular/localize` 来实现。具体步骤如下: 1. 在需要进行翻译的 HTML 模板中,使用 Angular 的内置指令 `i18n` 来标记需要翻译的文本。例如: ``` <div i18n="@@welcomeMsg">Welcome to my app, {{name}}!</div> ``` 其中 `@@welcomeMsg` 是一个翻译 ID,用于标识这段文本需要进行翻译。`{{name}}` 是一个变量名,用于在文本中动态插入用户的名字。 2. 在组件的 TypeScript 代码中,使用 `translate()` 函数来获取翻译后的文本。例如: ``` import { Component } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'app-welcome', template: ` <div>{{ welcomeMsg }}</div> ` }) export class WelcomeComponent { welcomeMsg: string; constructor(private translateService: TranslateService) {} ngOnInit() { this.translateService.get('@@welcomeMsg', { name: 'Alice' }).subscribe( (translation: string) => { this.welcomeMsg = translation; }, () => { this.welcomeMsg = '@@welcomeMsg'; } ); } } ``` 在 `ngOnInit()` 生命周期钩子函数中,我们调用 `translateService.get()` 函数来获取翻译后的文本。第一个参数是翻译 ID,第二个参数是一个对象,用于动态传递变量。如果找到了对应的翻译内容,我们将翻译后的文本赋值给组件的属性 `welcomeMsg`;否则,我们将变量名 `@@welcomeMsg` 直接赋值给 `welcomeMsg`。 这样,当 Angular 执行这个组件时,如果找到了对应的翻译内容,用户将看到翻译后的文本;否则,用户将看到变量名 `@@welcomeMsg`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值