angular - 如何在 Angular 9 中动态导入语言环境?

标签 angular typescript

我正在尝试在 Angular 9(基于monorepo)应用程序中动态导入语言环境。我正在做如下事情:

import { Injectable } from '@angular/core';
import { registerLocaleData } from '@angular/common';

@Injectable()
export class LocaleService {
    ...

    private capitalize(str: string): string {
        return str.charAt[0].toUpperCase() + str.substring(1).toLowerCase();
    }

    registerLocales() {
        for (const lang of ['de', 'fr', 'es']) {
            const basePkg = `locale${this.capitalize(lang)}`;
            const extraPkg = basePkg + 'Extra';

            const base = import(`@angular/common/locales/${lang}`).then(m => m[basePkg]);
            const extra = import(`@angular/common/locales/extra/${lang}`).then(m => m[extraPkg]);

            registerLocaleData(base, extra);
        }
    }
}

代替:
import { Injectable } from '@angular/core';
import { registerLocaleData } from '@angular/common';

import localeDe from '@angular/common/locales/de';
import localeDeExtra from '@angular/common/locales/extra/de';
import localeEs from '@angular/common/locales/es';
import localeEsExtra from '@angular/common/locales/extra/es';
import localeFr from '@angular/common/locales/fr';
import localeFrExtra from '@angular/common/locales/extra/fr';

@Injectable()
export class LocaleService {
    ...

    registerLocales() {
        registerLocaleData(localeDe, localeDeExtra);
        registerLocaleData(localeEs, localeEsExtra);
        registerLocaleData(localeFr, localeFrExtra);
    }
}

即使在执行此代码时,我也会收到由表单导入引起的大量错误:

WARNING in /home/me/somerepo/node_modules/@angular/common/locales/zu.d.ts Module build failed (from /home/me/somerepo/node_modules/@ngtools/webpack/src/index.js): Error: /home/me/somerepo/node_modules/@angular/common/locales/zu.d.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property.



注释掉导入并调用 registerLocaleData消除错误。我到底做错了什么?

最佳答案

excellent article Eliseo 的评论中提到的有答案。 typescript import function 不是普通的函数调用。简而言之,这里发生的事情是 import 告诉 Webpack 为与参数中的模式匹配的所有内容创建块。这是一个问题,因为模式匹配所有 .d.ts locales 目录中的文件,而我们实际上只想要 .js文件。解决方案是使用 Webpack 的“magic comments”。以下内容足以让所有内容正确加载:

const base = import(
  /* webpackExclude: /\.d\.ts$/ */
  `@angular/common/locales/${key}`).then(m => m[basePkg]);

const extra = import(
  /* webpackExclude: /\.d\.ts$/ */
  `@angular/common/locales/extra/${key}`).then(m => m[extraPkg]);

但是……有几个问题。
  • 每个语言环境都变成了一个块。这会创建 1,000 多个块。哎哟。
  • 块只是以数字作为名称。

  • 魔术评论再次拯救:
    const base = import(
      /* webpackExclude: /\.d\.ts$/ */
      /* webpackMode: "lazy-once" */
      /* webpackChunkName: "i18n-base" */
      `@angular/common/locales/${key}`).then(m => m[basePkg]);
    
    const extra = import(
      /* webpackExclude: /\.d\.ts$/ */
      /* webpackMode: "lazy-once" */
      /* webpackChunkName: "i18n-extra" */
      `@angular/common/locales/extra/${key}`).then(m => m[extraPkg]);
    

    这变得更近了,创建了两个块而不是数千块,但它们很大。如果我们知道我们对哪些地区感兴趣,我们可以做得更好。这是最终版本:
    const base = import(
      /* webpackInclude: /(de|en|es|fr|it|nl|no|pl|pt-BR|pt|fi|sv|ko|ru|zh|zh-Hans|zh-Hant|ja)\.js/ */
      /* webpackMode: "lazy-once" */
      /* webpackChunkName: "i18n-base" */
      `@angular/common/locales/${key}`).then(m => m[basePkg]);
    
    const extra = import(
      /* webpackInclude: /(de|en|es|fr|it|nl|no|pl|pt-BR|pt|fi|sv|ko|ru|zh|zh-Hans|zh-Hant|ja)\.js/ */
      /* webpackMode: "lazy-once" */
      /* webpackChunkName: "i18n-extra" */
      `@angular/common/locales/extra/${key}`).then(m => m[extraPkg]);
    

    这将逻辑从指定要忽略的文件更改为指定要加载的文件。它导致大约 100Kb 而不是 6Mb 的块。

    关于angular - 如何在 Angular 9 中动态导入语言环境?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61035621/

    相关文章:

    typescript - 输入gapi.savetoandroidpay

    javascript - 在 Angular 2 typescript 中获取模态元素

    angular - 当没有当前规范时使用'expect'

    javascript - 输入时动画不起作用(Tailwind、TransitionGroup、Typescript)

    typescript - Typescript 中是否需要访问器?

    html - 如何在 Angular2 应用程序中禁用 HTML5 表单验证?

    html - 如何在 angular 2/type 脚本中使用 href 调用函数

    javascript - Nativescript Angular : Can't read object from inside a function (this. 未定义?)

    javascript - 将对象转换为 typescript 中的模型

    javascript - TypeScript - 使用 knockout.js 的 JavaScript 在 IE8 中不工作 - "Object doesn' t 支持此属性或方法”