Angular 5 在运行时使用 Angular CLI 加载语言环境

Posted

技术标签:

【中文标题】Angular 5 在运行时使用 Angular CLI 加载语言环境【英文标题】:Angular 5 loading locale at runtime with Angular CLI 【发布时间】:2018-05-09 02:51:37 【问题描述】:

Angular 5 提供了一种在运行时使用 registerLocaleData

加载 i18n 语言环境的方法

https://angular.io/guide/i18n#i18n-pipes

我想根据设置动态加载语言环境(例如存储在 localStorage 中)。我的第一个测试是加载单个语言环境(fr):

import(`@angular/common/locales/fr`).then(locale => 
    registerLocaleData(locale.default);
);

这很好用。

当基于存储在 localStorage 中的值进行加载时,如下所示:

const localeName = localStorage.getItem('locale') || 'en';

import(`@angular/common/locales/$localeName`).then(locale => 
    registerLocaleData(locale.default);
);

它也可以工作,并且成功加载了语言环境。使用 Angular CLI 构建项目时,由于在构建时它不知道要捆绑哪个语言环境,它会捆绑所有语言环境,这很好。唯一的问题是构建过程会为其加载的每个语言环境发出警告:

模块构建失败:错误: node_modules\@angular\common\locales\af-NA.d.ts 不是 编译输出。有关详细信息,请查看其他错误消息。

./node_modules/@angular/common/locales/af-NA.js.map 中的警告 模块解析失败:意外令牌 (1:10) 您可能需要适当的加载程序来处理此文件类型。

我已经尝试包含语言环境 *.ts 文件并排除 *.map 文件,但它似乎没有选择它们。

这是我的 tsconfig.app.json


  "extends": "../tsconfig.json",
  "compilerOptions": 
    "outDir": "../out-tsc/app",
    "baseUrl": "./",
    "module": "esnext",
    "types": []
  ,
  "exclude": [
    "test.ts",
    "**/*.spec.ts",
    "../node_modules/@angular/common/locales/**/*.map"
  ],
  "include": [
    "**/*",
    "../node_modules/@angular/common/locales/**/*.ts"
  ]

TypeScript 需要 esnext 作为模块来进行动态导入。用 es2015 就不行了

【问题讨论】:

【参考方案1】:

仅导入 *.js 文件似乎可以解决问题,如下所示:

import(`@angular/common/locales/$localeName.js`).then(locale => 
   registerLocaleData(locale.default); 
);

tsconfig.app.json

中无需包含或排除文件

【讨论】:

如何确保加载正确的 localeName?例如,如果我在设置为 en-US 时使用 navigator.language,则没有对应的 js 文件...(名称为“en-US-POSIX.js”) 没有en-US,因为它与en相同。我认为这里描述了原因github.com/angular/angular/issues/20340#issuecomment-343865420 这个解决方案是为 Angular 4 实现的,也许在较新的版本中,有一种更安全的方法来实现同样的事情。如果您找到解决方案,请分享。 导入是否失败,您能在catcherror 处理程序中发现错误吗?一种解决方法可能是做这样的事情(不确定代码是否运行,理想情况下导入部分应该是一个单独的函数而不是复制):ts import(`@angular/common/locales/$localeName.js`).then(locale => registerLocaleData(locale.default); ).error(() => const baseLocale = 'en'; // extract the first part from the locale (i.e.'en' from 'en-US') import(`@angular/common/locales/$baseLocale.js`).then(locale => registerLocaleData(locale.default); ); 感谢您的更新。首先设置的变量 localeName 是什么? localeName 的值是从 API 检索的,它是与经过身份验证的用户关联的区域设置。默认为en

以上是关于Angular 5 在运行时使用 Angular CLI 加载语言环境的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular 5 中使用电子生成器构建电子应用程序

angular打包版本号

运行离子服务时出错:[ng] 错误:Angular 编译器需要 TypeScript >=4.4.2 和 <4.5.0,但找到了 4.5.2

在 Angular 1.5 中将模块注入业力测试

在 Angular 7 运行时动态生成 CSS 类

Angular 2 - 使用 ComponentResolver 加载在运行时下载的组件