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

斯科特·迪尔韦斯特

我正在尝试在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);
    }
}

在甚至执行此代码的过程中,我收到大量由于导入表单而导致的错误:

/home/me/somerepo/node_modules/@angular/common/locales/zu.d.ts中的警告模块构建失败(来自/home/me/somerepo/node_modules/@ngtools/webpack/src/index.js):错误:TypeScript编译中缺少/home/me/somerepo/node_modules/@angular/common/locales/zu.d.ts。请通过“文件”或“包含”属性确保它在您的tsconfig中。

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

斯科特·迪尔韦斯特

Eliseo的评论中提到优秀文章就是答案。Typescript的import函数不是普通的函数调用。简而言之,这里发生的事情是import告诉Webpack为与参数中的模式匹配的所有内容创建块这是一个问题,因为该模式匹配.d.tslocales目录中的所有文件,而实际上我们只需要这些.js文件。解决方案是使用Webpack的“魔术注释”。以下内容足以使所有内容正确加载:

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. 每个语言环境都变成了一块。这将创建1,000多个块。哎哟。

  2. 这些块只是以数字作为名称。

魔术再次对救援发表评论:

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。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章