0

i18n在我的 React 应用程序中使用该模块,该模块作为应用程序(我将其称为实时应用程序)托管S3cloudfront位于其前面。

我想将 s3 url 存储在配置文件中,以避免在我的应用程序中对其进行硬编码,以便在public/locales开发时可以处理本地存储在文件夹中的翻译文件。

最初,我设置了后端选项,以便它始终尝试查找locales路径中的文件。这在本地工作,但在 S3 上停止工作,尽管 locales 文件夹存在于 S3 存储桶中。我还注意到应用程序没有发送任何请求来检索翻译文件。

backend: {
    loadPath: 'locales'
  }

然后我决定将翻译文件上传到另一个 S3 存储桶并将它们托管在那里,看看这是否能解决问题。我将配置更改为对 s3 存储桶路径进行硬编码。这在本地和实时应用程序上都有效。但这意味着我不能使用我的配置文件来确定 loadPath 选项。

 backend: {
    loadPath: '<myhardcoded-s3-bucket-url>/{{lng}}/translation.json',
    crossDomain: true
  }

然后我想我可以这样构建 url:

/*global AWS_CONFIG */
/*eslint no-undef: "error"*/
...
...
...
backend: {
    loadPath: `${AWS_CONFIG.aws_app_translations_path}/{{lng}}/translation.json`,
    crossDomain: true
  }

奇怪的是,这在本地工作时AWS_CONFIG.aws_app_translations_pathhttp://localhost:3000/locales<myhardcoded-s3-bucket-url>。但是,一旦我将其推送到现场,它又失败了。这次提出请求https://<my-apps-base-path>/undefined/en-GB/translation.json,例如。所以它试图使用应用程序路径并附加我在loadPath.

然后我看到我可以loadPath作为一个函数来构造我的 url。这也不适用于实时应用程序,但再次在本地工作。

backend: {
    loadPath: function (lng) {
      return `${AWS_CONFIG.aws_app_translations_path}/${lng}/translation.json`
    },
    crossDomain: true
  }

这是我的整个i18n文件

/*global AWS_CONFIG */
/*eslint no-undef: "error"*/
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-http-backend";
import { initReactI18next } from "react-i18next";


const options = {
  order: ['navigator', 'localStorage'],
  caches: ['localStorage'],
  fallbackLng: "en-GB",
  debug: true,
  interpolation: {
    escapeValue: false // not needed for react as it escapes by default
  },
  backend: {
    loadPath: function (lng) {
      return `${AWS_CONFIG.aws_app_translations_path}/${lng}/translation.json`
    },
    crossDomain: true
  }
}

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init(options);

export default i18n;

什么可以解释这种奇怪的行为?我在这里缺少配置吗?

4

2 回答 2

0

一旦我改变了导入配置文件的方式,它就起作用了。我猜现场存在加载问题,但已将我的 i18n 文件从

/*global AWS_CONFIG */
/*eslint no-undef: "error"*/
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-http-backend";
import { initReactI18next } from "react-i18next";


const options = {
  order: ['navigator', 'localStorage'],
  caches: ['localStorage'],
  fallbackLng: "en-GB",
  debug: true,
  interpolation: {
    escapeValue: false // not needed for react as it escapes by default
  },
  backend: {
    loadPath: function (lng) {
      return `${AWS_CONFIG.aws_app_translations_path}/${lng}/translation.json`
    },
    crossDomain: true
  }
}

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init(options);

export default i18n;

import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-http-backend";
import { initReactI18next } from "react-i18next";
import {config} from './config';

const {aws_app_translations_path} = config;


const options = {
  order: ['navigator', 'localStorage'],
  caches: ['localStorage'],
  fallbackLng: "en-GB",
  debug: true,
  defaultNS: 'translation',
  load: 'currentOnly',
  interpolation: {
    escapeValue: false // not needed for react as it escapes by default
  },
  backend: {
    loadPath: (lng, ns) => {
      return `${aws_app_translations_path}/${lng}/${ns}.json`;
    },
    crossDomain: true
  }
}

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init(options);

export default i18n;

解决它。尽管为整个应用程序的其余部分工作,但最初AWS_CONFIG 被返回为未定义。将配置文件更改为位于项目的根目录及其导入方式解决了该问题。

于 2020-07-15T10:10:10.097 回答
0

根据您在评论中的回复,您似乎缺少翻译部分,并且它undefined作为名称空间预先附加在 url 中。

尝试这个:

// i18n

const options = {
  order: ['navigator', 'localStorage'],
  caches: ['localStorage'],
  fallbackLng: "en-GB",
  debug: true,
  interpolation: {
    escapeValue: false // not needed for react as it escapes by default
  },
  backend: {
    loadPath: function () {
      return `${AWS_CONFIG.aws_app_translations_path}/{{lng}}/{{ns}}.json`
    },
    crossDomain: true
  }
}

基于loadPath配置文档:

加载资源的路径,或返回路径的函数: function(lngs, namespaces) { return customPath; }

返回的路径将插入 lng, ns 如果提供像给出静态路径

于 2020-07-13T08:47:40.280 回答