i18n загрузить переводы из s3bucket - PullRequest
0 голосов
/ 10 июля 2020

Я использую модуль i18n в моем приложении для реагирования, которое размещено как приложение (которое я буду называть живым приложением) на S3, и перед ним cloudfront.

Я хочу сохранить URL-адрес s3 в файле конфигурации, чтобы избежать его жесткого кодирования в моем приложении, чтобы я мог работать с файлами перевода, хранящимися локально в папке 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_path было одновременно http://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;

Чем объясняется такое странное поведение? Мне здесь не хватает конфигурации?

Ответы [ 2 ]

0 голосов
/ 15 июля 2020

Как только я изменил способ импорта файла конфигурации, все заработало. Я предполагаю, что есть проблема с загрузкой в ​​реальном времени, но, изменив мой файл 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 возвращалось как undefined, несмотря на то, что он работал для остальной части всего приложения. Изменение файла конфигурации для размещения в каталоге root проекта и способ его импорта решили проблему.

0 голосов
/ 13 июля 2020

Судя по вашим ответам в комментариях, похоже, что вам не хватает части перевода, и она предварительно добавляет 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 do c:

путь, откуда загружаются ресурсы, или функция, возвращающая путь: function (lngs, namespaces) {return customPath; }

Возвращаемый путь будет интерполировать lng, ns, если он предоставлен, например, с указанием stati c path

...