如何在Firebase托管中提供有效的AOT语言Angular应用程序?

9
我有一个Angular 4应用程序,由Firebase托管服务托管,有一个自定义域名(例如:www.something.com 重定向到firebase网址)。
我使用了i18n国际化技术,我的问题是: 根据用户所在国家/地区提供正确编译的应用程序的最佳方法是什么?
目前只有标准--aot en在线版本,如果有人来自意大利,我想提供--aot it版本。
谢谢。
2个回答

7

我也遇到了类似的问题。 我通过更改firebase.json中的Hosting属性来解决它。

{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "redirects": [
      {
        "source" : "/",
        "destination" : "/en",
        "type" : 301
      }
    ],
    "rewrites": [
      {
        "source": "/en/**",
        "destination": "/en/index.html"
      },
      {
        "source": "/es/**",
        "destination": "/es/index.html"
      },
      {
        "source": "/fr/**",
        "destination": "/fr/index.html"
      }
    ]
  }
}

希望这能帮到你!

我已经尝试过这种方法。重定向有效,以及重写规则也是如此。很好,但是:每个对 domain.com 的请求都被重定向到“/en”路线,然后是“/en/index.html”。即使我有一个“fr”区域设置,就像您设置在 firebase.json 文件中的那样。仍然缺少区域设置检测/与您的应用支持的区域设置比较的部分,并重定向到正确路径'domain.com/fr',例如。 - Johan Chouquet
在dist/project目录中创建一个简单的index.html文件,并编写一个JS函数来确定用户的语言环境并将其重定向,这可能是一个不错的解决方案。 - Ambrus Tóth
1
我也看到一些网站默认显示英文页面,然后弹出一个选项框,让用户选择是否跳转到本地语言页面。例如,从日本访问apple.com会显示一个头部弹窗,其中包含一个URL链接,可以导航到日本网站。希望这种方法对您有帮助。@JohanChouquet - yashmurty

2

我也曾遇到同样的问题,但一直找不到解决方案。因此,我采用了另一种方法,即使用i18n国际化。这样,我可以在单个构建中使用多种语言。

我不确定这是否是最佳方法,但这是我的做法:

我创建了一个非常简单的服务,它提供窗口。将其作为根目录提供!

function _window(): any {
  // return the global native browser window object
  return window;
}

@Injectable()
export class WindowRef {
  get nativeWindow(): any {
    return _window();
  }

  public ln = 'en'; //default language


  constructor() {
    try {
      if (!isNullOrUndefined(this.nativeWindow.navigator.language) && this.nativeWindow.navigator.language !== '') {
        let lang = this.nativeWindow.navigator.language;
        if (lang.indexOf('-') >= 0) {
          lang = lang.split('-')[0]; //replace en-us with en.
        }
        this.ln = lang;
      }
    } finally {
    }
  }
}

对于默认的Angular管道,我创建了一个简单的包装器:

@Pipe({name: 'datepipe', pure: true})
export class MyDatePipe extends DatePipe implements PipeTransform {
  constructor(private win: WindowRef) {
    super(win.ln);
  }

  transform(value: any, pattern?: string): string | null {
    return super.transform(value, pattern);
  }
}

对于文本,我创建了一个非常简单的管道:

@Pipe({name: 'translate'})
export class TranslationPipe implements PipeTransform {
  constructor(private translationService: TranslationService) {

  }

  transform(value: string) {
    return this.translationService.getTranslation(value);
  }
}

管道使用此翻译服务:

@Injectable()
export class TranslationService {
  lng: string = 'en';

  nl: Array<KV> = [
    {key: 'Hello', value: 'Hallo'},
  ];

  languages = [
    {key: 'nl', value: this.nl}

  ];

  constructor() {
    if (!isNullOrUndefined(navigator.language)) {
      this.lng = navigator.language;
    }
    if (this.lng.indexOf('-') >= 0) {
      this.lng = this.lng.split('-')[0];
    }
  }

  getTranslation(key: string): string {
    return this.findByKey(this.findByKey(this.languages, this.lng), key) || key;
  }

  private findByKey(list: { key, value }[], key: string): any {
    if (!isNullOrUndefined(list)) {
      for (let i = 0; i < list.length; i++) {
        if (list[i].key === key) {
          return list[i].value;
        }
      }
    }
    return undefined;
  }
}

export class KV {
  key: string;
  value: string;
}

希望您会发现这很有用


嗨,我喜欢这个解决方案,但是这样做会使翻译变得运行时,并且没有使用 Angular 国际化(i18n)。我主要的问题是是否可以使用该解决方案提供应用程序(否则我就看不到 i18n 的效用了)。 - Danilo Dughetti
我知道这不是理想的解决方案,但我在Firebase托管中找不到更好的解决方案。这是我能想到的最好的方法。我更希望看到一种可以部署多个实例的解决方案。 - Robin Dijkhof

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接