新的 Angular 渲染引擎 Ivy 的一部分包括一种本地化应用程序的新方法 – 特别是提取和翻译文本。本文解释了这种新方法的好处和一些实施。
在 Ivy 之前,向 Angular 应用程序添加可本地化消息的唯一方法是使用i18n
属性在组件模板中标记它们:
<div i18n>Hello, World!</div>
如果编译器配置中提供了一组翻译,则 Angular 编译器会在使用不同文本编译模板时替换此文本。 i18n
标签非常强大——它们可以用在属性和内容中;它们可以包含复杂的嵌套ICU(Unicode 国际组件)表达式;他们可以附加元数据。请参阅我们的i18n 指南了解更多信息。
但这种方法也有一些缺点。
最重要的问题是翻译必须在模板编译期间进行,这发生在构建管道的开始处。这样做的结果是,对于您希望在应用程序中支持的每个语言环境,都必须进行完整的构建、编译-捆绑-缩小等。
如果单个构建需要 3 分钟,那么支持 9 个语言环境的总构建时间将为 3 分钟 x 9 个语言环境 = 27 分钟。
此外,无法在应用程序代码中标记文本进行翻译,只能在组件模板中标记文本。这导致了尴尬的解决方法,即创建人工组件纯粹是为了保存要翻译的文本。
最后,无法在运行时加载翻译,这意味着无法将应用程序提供给可能想要提供自己的翻译的最终用户,而不必自己构建应用程序。
新的本地化方法基于使用名为$localize
模板文字标记处理程序在代码中标记字符串的概念。这个想法是使用此标签“标记”需要翻译的字符串:
const message = $localize `Hello, World!`;
这个$localize
标识符可以是一个真正的函数,可以在运行时在浏览器中进行翻译。但值得注意的是,它也是一个在缩小后仍然存在的全局标识符。这意味着它可以简单地充当代码中的标记,静态后处理工具可以使用该标记在部署代码之前用翻译后的文本替换原始文本。例如,以下代码:
warning = $localize `${this.process} is not right`;
可以替换为:
warning = "" + this.process + ", ce n'est pas bon.";
结果是所有对$localize
引用都被删除,并且渲染翻译文本的运行时成本为零。
Ivy 的 Angular 模板编译器经过重新设计,可以生成$localize
标记字符串,而不是自行进行翻译。例如以下模板:
<h1 i18n>Hello, World!</h1>
将被编译为类似:
ɵɵelementStart(0, "h1"); // <h1>
ɵɵi18n(1, $localize`Hello, World!`); // Hello, World!
ɵɵelementEnd(); // </h1>
这意味着,在 Angular 编译器完成工作后,所有标有i18n
属性的模板文本都已转换为$localize
标记字符串,可以像任何其他标记字符串一样进行处理。
另请注意, $localize
标记字符串可以出现在任何代码(用户代码或从应用程序或库中的模板生成)中,并且不受缩小的影响,因此虽然后处理工具可能会收到如下所示的代码
...var El,kl=n("Hfs6"),Sl=n.n(kl);El=$localize`Hello, World!`;let Cl=(()=>{class e{constructor(e)...
它仍然能够识别和翻译标记的消息。结果是我们可以重新排序构建管道以在过程的最后进行翻译,从而显着缩短构建时间。
在这里您可以看到构建时间仍然是 3 分钟,但由于翻译是作为后处理步骤完成的,因此我们只产生一次构建成本。此外,翻译的后处理速度非常快,因为该工具只需解析$localize
标记字符串的代码。在本例中大约需要 5 秒。
结果是,9 个语言环境的总构建时间现在为 3 分钟 + ( 9 x 5 秒) = 3 分 45 秒。相比之下,Ivy 翻译前的版本需要 27 分钟。
已经使用这种方法的团队在现实生活中也看到了类似的改进:
翻译后处理已内置于 Angular CLI 中,如果您已根据我们的i18n 指南配置了您的项目,您应该已经从这些更快的构建时间中受益。
目前,在应用程序代码中使用$localize
尚未得到公开支持或记录。我们将在未来几个月内努力提供全面支持。它需要新的消息提取工具——当前(Ivy 之前)的消息提取器在应用程序代码中找不到$localize
文本。它现在正在集成到 CLI 中,并应作为 10.1.0 的一部分发布。
我们还在研究如何使用这种新方法更好地支持第三方库中的翻译。由于这会影响 Angular 包格式 (APF),我们希望在实施之前运行征求意见 (RFC)。
同时,享受改进的构建时间并密切关注对文本应用程序级本地化的全面支持。
文章来源地址:https://blog.angular.dev/angular-localization-with-ivy-4d8becefb6aa