【问题标题】:Angular: Localization in to multiple languagesAngular:本地化为多种语言
【发布时间】:2020-01-03 03:43:45
【问题描述】:

我有一个已经构建好的 Angular 6 应用程序。现在我们计划将其支持为多种语言。我能够创建多个 xlf 文件并将目标字符串替换为语言。我的语言环境文件包含三个文件,例如 messages.en.xlf、messages.es.xlf 和 messages.fr.xlf,分别用于英语、西班牙语和法语。

根据浏览器的语言,应用程序应选择所需的语言文件。如果浏览器设置为法语,它应该会自动获取 messages.fr.xlf 并以法语显示应用程序。

最初我的构建命令将是ng build --prod --output-hashing all,但随着本地化更改,我需要使用--aot=false--build-optimizer=false,我的应用程序的性能和加载时间变得更糟。

ng build  --prod --output-hashing all --aot=false --build-optimizer=false

我的 main.ts 文件如下:

declare const require;
var userLang;

window.addEventListener('languagechange', function () {
  // callLangugae();
  location.reload(true);
});

function callLangugae() {
  userLang = navigator.language;
  userLang = userLang.split("-")[0];
  switch (userLang) {
    case 'es': {
      registerLocaleData(localeEs);
      break;
    }
    case 'fr': {
      registerLocaleData(localeFr);
      break;
    }
    case 'en': {
      registerLocaleData(localeEn);
      break;
    }
    default: {
      userLang = 'en';
      registerLocaleData(localeEn);
      break;
    }
  }

}

callLangugae();

const translations = require(`raw-loader!./locale/messages.${userLang}.xlf`);

platformBrowserDynamic().bootstrapModule(AppModule, {
  providers: [
    { provide: TRANSLATIONS, useValue: translations },
    { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }
  ]
})
  .catch(err => console.log(err));

我想知道是否有一种正确的方法可以根据浏览器的语言加载 xlf 文件,而不会出现性能问题并且不会使 AOT 为假。

【问题讨论】:

  • 如果您使用内置的 i18n 进行翻译,通常最好为每种语言创建 1 个包集。或者,您可以使用@ngx-translate,它可以动态切换语言,甚至无需重新加载窗口。
  • 我们只需要创建 1 个构建包。我们不能为每种语言创建一个。我见过 ngx-translate 但我想知道是否有内置的角度来做到这一点
  • I am wondering is there a proper way to load the xlf file based on the language of the browser without the performance problems and with out making aot false. ← 您必须选择具有每种语言不同应用程序文件的 aot jit,它可以在运行时引导语言环境。如果使用内置的 i18n 翻译,则没有混合方法。
  • 就我个人而言,我更喜欢使用@ngx-translate,尤其是当您有多种翻译或语言数量会增加时。这将允许您使用 AOT 进行编译并支持组件中文本的动态替换(即翻译)。
  • 到目前为止没有人提供答案的原因与动机无关(即添加赏金),这个问题无法回答,因为您想要的解决方案不存在。您必须在浏览器中的动态翻译加载和以 JIT 运行 Angular、为每个翻译创建包并作为 AOT 运行或使用像 @ngx-translate 这样的库之间进行选择。

标签: angular angular-cli angular-i18n angular-cli-v8


【解决方案1】:

使用 Angular 9 和 Ivy,运行时、单一构建的翻译越来越接近现实。 Ivy 已经具备在运行时加载翻译的功能,如下所述:

https://angular.fun/post/2020-01-11-angular-ivy-localize/

还有这里:

https://jaxenter.com/angular-9-ivy-167934.html

但是,由于需要外部工具来提取字符串,它似乎还没有准备好生产。

考虑到创建一种构建一种语言是多么痛苦,我很想尝试这种新方法。

【讨论】:

    【解决方案2】:

    关于如何在应用程序中使用翻译,您有 3 个主要选项。

    AoT Build per Language

    您可以使用i18n 内置的角度功能并创建AoT build per language。然后,您需要确保在加载网页时在运行时加载正确的语言相关构建文件。一般的做法是让每种语言相关的构建在他们自己的文件夹中,该文件夹以区域设置/语言的 ISO 代码命名。然后,您可以指向此文件夹,然后指向页面导航中包含的 index.html(或在您使用的任何主机页面中加载包含的 .js 文件)。根据您想要支持的语言环境的数量,这会导致您的构建时间显着增加。从积极的方面来说,您可以获得 AoT 的所有运行时性能优势。

    One JiT build and resource file per language

    您可以使用内置的 i18n 功能并在运行时创建单个 JiT build and point to the appropriate translation file。您的构建时间会快得多(当您发布应用程序时),但客户端在加载应用程序时以及可能在应用程序执行期间也会受到性能影响。积极的一面是,当您处理多种语言时,这种结构可能更容易维护,尤其是在语言数量预计会增长的情况下。

    外部工具(如@ngx-translate

    在处理越来越多需要支持的语言时,这是我的首选方法。此外部工具允许您使用单个 AoT 构建。然后,您在模板中定义翻译键并配置工具以从某些(可能)外部源(如服务器或磁盘上的文件)检索翻译。可能还有其他人,但我不会将它们包括在这个答案中。


    关于 JiT 与 AoT 的说明。已经有一个写得很好的答案,比较了 JiT 构建与 AoT 构建,可以在 StackOverflow 上找到:Angular 2 : Just-in-Time (JiT) vs Ahead-of-Time (AoT) compilation。我不会在这里重新总结这些答案。

    【讨论】:

    • 或者等待 Ivy - 他们建议我们可以在运行时通过 AOT 动态地国际化我们的应用程序。
    • @ngx-translate 对我来说也是最可取的。它支持在运行时添加或删除,也无需重新部署。
    • 我同意@khush,ngx-translate 是一个不错的选择。我不得不在一个项目中使用它,而且它非常容易使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多