首页 > 解决方案 > 在 Angular 中为 i18n 使用 Webpack

问题描述

我非常喜欢 Angular 2+ 附带的 i18n 进程,特别是以下两个特性:

  1. 使用 CLI 命令 ( ng xi18n )从带注释的 HTML 模板生成翻译文件的能力。
  2. 在构建时用翻译替换模板文本的能力(在运行时节省资源)。

现在我正在从事一个非 Angular 项目,并希望实现一个类似于上述过程的 i18n 过程。该项目基于 AngularJS 并使用自定义 Webpack 捆绑。HTML 模板文件当前使用 Webpacks原始加载器加载并捆绑为字符串。

Webpack 本身建议将其HTML 和 i18n 加载器连接起来。虽然这可能会解决(2),但它不能解决(1),并且模板中所需的语法与 Angular 中使用的语法相去甚远(即向i18n=""必须翻译的元素添加属性)。

有没有人有这种问题的经验?有没有办法为这个用例使用专门的 Webpack 加载器,或者甚至是 Angular 2+ 构建系统的一小部分?

标签: angularwebpackinternationalization

解决方案


我有实现这样的用例的经验。您需要编写服务来读取包含 xml 翻译的配置文件,然后在应用程序的引导阶段将其注入 main.ts,以便它可以读取 xml 翻译

主要的.ts

        import { platformBrowserDynamic }  from '@angular/platform-browser-dynamic';
        import { getTranslationProviders } from './app/i18n-providers';

        import { AppModule } from './app/app.module';

        getTranslationProviders().then(providers => {
          const options = { providers };
          platformBrowserDynamic().bootstrapModule(AppModule, options);
        });

i18n-providers.ts

    import { TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID } from '@angular/core';

    export function getTranslationProviders(): Promise<Object[]> {

      // Get the locale id from the global
      const locale = document['locale'] as string;

      // return no providers if fail to get translation file for locale
      const noProviders: Object[] = [];

      // No locale or U.S. English: no translation providers
      if (!locale || locale === 'en-US') {
        return Promise.resolve(noProviders);
      }

      // Ex: 'locale/messages.es.xlf`
      const translationFile = `./locale/messages.${locale}.xlf`;

      return getTranslationsWithSystemJs(translationFile)
        .then( (translations: string ) => [
          { provide: TRANSLATIONS, useValue: translations },
          { provide: TRANSLATIONS_FORMAT, useValue: 'xlf' },
          { provide: LOCALE_ID, useValue: locale }
        ])
        .catch(() => noProviders); // ignore if file not found
    }

    declare var System: any;

    function getTranslationsWithSystemJs(file: string) {
      return System.import(file + '!text'); // relies on text plugin
    }

然后在你的 html

    <h1 i18n="User welcome|An introduction header for this sample">Hello i18n!</h1>

推荐阅读