Angular 国际化实践:按需导入 Locale 全局数据变体(@angular/common/locales/global)
2026/9/7 1:41:11 网站建设 项目流程

Angular 国际化实践:按需导入 Locale 全局数据变体(@angular/common/locales/global)

【免费下载链接】angularDeliver web apps with confidence 🚀项目地址: https://gitcode.com/GitHub_Trending/an/angular

Angular 的国际化(i18n)机制依靠各语言区域的 locale 数据来格式化日期、货币、数字与百分比。本文讲解「导入全局 locale 数据变体(Global variants of the locale data)」的两种触发方式——通过 CLI 构建期自动内嵌,以及在应用入口处手动import指定区域数据,并结合当前仓库源码剖析全局 locale 文件的结构与生成原理。读完你能够为任意目标语言区域(如法语fr)正确加载数据,并理解ng build --localize与手工导入之间的分工关系。

构建期自动包含:ng build --localize

当你使用 Angular CLI 的本地化构建命令时,CLI 会自动把目标区域的 locale 数据打包进产物,无需手工编写任何导入语句:

ng build --localize

Angular 官方建议(见原文档)中明确的两点前提:

  • Angular 初始安装时只内置了美国英语en-US的 locale 数据,其他语言区域需要额外提供;
  • 使用--localize配合ng build时,Angular CLI 会自动包含对应的 locale 数据,并同步设置LOCALE_ID注入令牌的值。

也就是说,构建期本地化(在每个目标语言产物中预编译翻译并固化LOCALE_ID)时,区域数据属于 CLI 自动处理的范畴;而当应用需要在构建期之外(例如手动切换LOCALE_ID、或运行自定义打包流程)使用某个区域的数据时,就需要下面介绍的显式导入方式。

全局 locale 数据变体存放在哪里

发布在 npm 上的@angular/common包中带有全部 locale 数据文件。除每个语言一个的常规模块(默认导出 locale 数据对象)外,还存在一组全局变体(global variants),位于:

@angular/common/locales/global

在本仓库源码中,与这些发布文件对应的生成逻辑与目录位于 packages/common/locales,其子目录与文件分工如下:

路径内容
packages/common/locales/generate-locales-tool/依据 CLDR 数据生成全部 locale 文件的 Bazel 生成工具
packages/common/locales/extra/各 locale 的扩展数据(如 day period 细分化数据)
packages/common/locales/global/全局变体目录
packages/common/locales/ff-CM.ts常规 locale 模块的代表性文件

需要特别说明的是:global 目录中直接检入的仅剩ff-CM.jsff-GN.jsff-MR.js这类历史遗留文件。文件头部的注释明确写道:locale 文件本应全部通过 Bazel 在打包时生成、从不作为源码检入仓库,此处保留少量文件只是为了向后兼容早期 Gulp 构建时期的产物。因此仓库中看不到完整的global/fr.js,不代表@angular/commonnpm 包中不存在——发布包内包含完整集合,而仓库侧负责生成它们的代码才是重点。

导入全局数据变体:以法语为例

当应用不使用--localize构建,却需要en-US之外区域的数据时,可以在应用引导入口导入目标语言的全局变体。官方示例使用了法语fr,见 i18n 示例应用的 main.ts:

// #docregion global-locale import '@angular/common/locales/global/fr'; // #enddocregion global-locale import {bootstrapApplication} from '@angular/platform-browser'; import {AppComponent} from './app/app.component'; bootstrapApplication(AppComponent);

要点解读:

  • 该导入是副作用导入(side-effect import),没有默认导出对象需要接收,其作用在于让该区域数据在全局注册表中可用;
  • 在 Standalone /bootstrapApplication架构下,放在main.ts中即可(如上所示);
  • 在基于NgModules的传统架构中,原文档提示应在app.module中完成同样的导入,作用等价。

全局变体的命名规则为@angular/common/locales/global/{locale-id},其中locale-id使用小写的 Unicode 区域标识,例如法语为fr,法语(加拿大)为fr-ca

全局文件到底做了什么:源码级剖析

为什么一次 side-effect import 就能让 Angular 找到对应区域的数据?答案藏在生成全局文件的工具代码中。查看 locale-global-file.ts,generateLocaleGlobalFile生成的产物骨架如下:

(function(global) { global.ng ??= {}; global.ng.common ??= {}; global.ng.common.locales ??= {}; const u = undefined; // ...plural 函数定义... global.ng.common.locales['fr'] = [ /* 结构化 locale 数据数组 */ ]; })(globalThis);

由此可以得到几个关键结论:

  1. 数据挂载在全局对象globalThis.ng.common.locales上,以归一化后的 locale ID 为键——归一化规则(见 locale-global-file.ts)是转小写并把_替换为-,例如fr_CA会注册为fr-ca
  2. 数据本身是一个按索引读取的数组,Angular 运行时通过LocaleDataIndex中定义的固定下标取用日期时间格式、数字格式、货币符号、方向性等字段(详见 generate-locales-tool/README.md);
  3. 每个文件都内联了该 locale 的plural 复数规则函数,供NgPlural等机制使用;
  4. 数据去重优化:当某一项与前一索引相同或与默认en基线一致时,生成工具会以undefined占位(可压缩成更短的数组字面量),运行时自动向前回溯查找,以此压缩体积;同理,与默认 locale 相同的货币符号会被省略,框架会回退到@angular/common内置的基础货币数据。

除了全局变体,CLDR 数据还会生成常规 locale 模块(默认导出一个数组),供编程式注册使用。@angular/common暴露的registerLocaleData函数(见 locale_data.ts)只是把参数转交给@angular/core中的ɵregisterLocaleData完成注册——这说明「按 ID 查找并应用 locale 数据」的底层能力属于 core,而@angular/common提供数据文件与辅助入口。两种注册路线对比:

路线语句适用场景
全局变体import '@angular/common/locales/global/fr';引导入口副作用导入,适合构建期外固定/静态设置区域
编程注册registerLocaleData(localeFr)运行时动态注册、需要接收返回值或传入额外数据的场景

这些数据最终服务谁:数据格式化管道与 LOCALE_ID

加载 locale 数据本身不是目的,其消费方是@angular/common提供的数据变换管道。它们统一读取LOCALE_ID令牌,再按对应区域规则输出结果(详见数据按区域格式化指南):

数据变换管道作用
DatePipe格式化日期值
CurrencyPipe将数字转换为货币字符串
DecimalPipe将数字转换为十进制字符串
PercentPipe将数字转换为百分比字符串

因此,导入法语全局变体的实际价值就是:当LOCALE_ID指向fr时,{{ today | date }}{{ amount | currency }}等管道能输出符合法语书写习惯的格式。若某个管道需要临时覆盖全局LOCALE_ID,还可以像{{ amount | currency: 'USD' : 'symbol' : '1.2-2' : 'en-US' }}这样在管道末位显式传入en-US,其优先级高于应用级LOCALE_ID

关于区域 ID 本身,Angular 遵循 Unicode CLDR 与 BCP 47 规范,ID 形如{language_id}-{locale_extension},例如en-USfr-CA。默认情况下项目的源语言区域即en-US;如需更改构建时使用的源语言,可在angular.jsoni18n段配置sourceLocale,详见按 ID 引用区域指南:

{ "projects": { "your-project": { "i18n": { "sourceLocale": "ca" } } } }

实践路线小结

  1. 优先使用构建期本地化:只要运行ng build --localize,目标区域的 locale 数据与LOCALE_ID均由 CLI 自动处理;
  2. 默认只有en-US:其余区域要么走构建期自动包含,要么显式加载;
  3. Standalone 应用:在main.ts中写import '@angular/common/locales/global/<locale>';NgModule 应用:在app.module中导入同一语句;
  4. 验证渠道:导入后,DatePipeCurrencyPipeDecimalPipePercentPipe的输出应随LOCALE_ID指向的区域而变化。

关于 locale 数据集的完整生命周期(CLDR 数据来源、默认enlocale 内置于@angular/core、基础货币信息拆分存放于@angular/common/src/i18n、数组化存储与undefined去重优化等),可继续阅读 generate-locales-tool/README.md。整个国际化功能线的其余环节(翻译准备、翻译文件、合并与部署)可参考 i18n 指南目录 下相邻文档。

【免费下载链接】angularDeliver web apps with confidence 🚀项目地址: https://gitcode.com/GitHub_Trending/an/angular

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询