Этот пост предназначен для людей, использующих react-intl вместе с create-react-app, которые не хотят выгружать.

Я написал это, поскольку обнаружил, что довольно много людей пытаются решить эту проблему, в том числе и я.

В конце у вас будет приложение, выполняющее несколько переводов на два языка с использованием вышеупомянутой технологии.

TL;DR

  1. Сделайте примерно так: https://github.com/facebook/create-react-app/issues/1227#issuecomment-266202754
  2. Тогда это: https://medium.freecodecamp.org/setting-up-internationalization-in-react-from-start-to-finish-6cb94a7af725 из заголовка Пора начинать перевод.

Выполнение описанного выше даст вам все необходимое, но с некоторыми настройками, которые все еще необходимы.

Для полного решения, которое на 100% определенно будет работать с первого раза, как всегда работает код 🤥 - читайте дальше.

Что это покрывает

Процесс состоит из 3 этапов:

1. Найдите места, требующие перевода.

Мы пробежимся по нашему приложению с помощью babel-plugin-react-intl и найдем react-intl компоненты, которые нужно перевести. Результатом этого шага будет набор файлов JSON, которые выглядят следующим образом:

2. Сделайте наши переводы.

Используя определения, созданные выше ☝, мы будем искать переводы, которые вы вручную добавили в свой проект, и создавать из них localeData.json файл внутри нашего каталога ./src, который выглядит следующим образом:

3. Передайте переводы в react-intl.

Ну тогда:

  • импортируйте наш новый localeData.json файл в наши приложения index.js.
  • получить локаль на основе языка браузеров.
  • передать сообщения перевода для правильных стран в react-intl, чтобы он мог их отображать.

Вот как это сделать.

Реализация

1. Найдите места, требующие перевода.

Давайте сначала добавим нужные нам пакеты:

yarn add react-intl
yarn add -D @babel/cli @babel/core babel-plugin-react-intl babel-preset-react-app

Теперь добавьте .babelrc файл в корень вашего проекта, содержащий это:

{
  "presets": ["react-app"],
  "plugins": [
    [ 
      "react-intl", {
        "messagesDir": "./build/messages/"
      }
    ]
  ]
}

Затем добавьте новый сценарий в свой package.json. Помните, что эта часть будет запускать наше приложение с babel-plugin-react-intl, как определено в .babelrc, и выводить файлы определений, которые нам понадобятся:

"scripts": {
  ...
  "build:messages": "NODE_ENV=production babel ./src >/dev/null"
}

Итак, если у меня, например, есть файл по адресу src/components/Headline.js, с некоторым кодом React и несколькими компонентами из react-intl:

И я запускаю новый скрипт, который мы создали выше:

yarn build:messages

Теперь, если вы заглянете в свою ./build папку, вы увидите файл: ./build/messages/src/components/Heading.json, который выглядит примерно так:

Конец первого шага.

2. Сделайте наши переводы.

Теперь нам нужно использовать файлы JSON, созданные в нашем каталоге ./build, для создания переводов.

Для этого вам понадобится скрипт, который:

  • прочитать все созданные файлы JSON
  • используйте найденный идентификатор для сопоставления с переводами, которые вы создадите
  • сделайте большой файл всех ваших переводов, который будет выглядеть примерно так:

Это мой сценарий 👇, адаптированный из показанного здесь. Я знаю, это длинновато. К сожалению, это то, что нужно. Прочтите его и комментарии, чтобы понять, что происходит.

Или, как любой настоящий профессиональный программист, просто скопируйте и вставьте его в свой проект и забудьте об этом.

Обратите внимание, что в приведенном выше сценарии мы пишем в const WRITE_PATH = ‘./src/localeData.json’ (строка 6), потому что приложение create-response-app заставляет нас ссылаться на файлы внутри папки ./src.

Итак, теперь мы можем добавить новый сценарий npm к нашему package.json, который будет запускать наш новый сценарий, а также другой сценарий, который мы создали ранее:

"scripts": {
  ...
  "build:messages": "NODE_ENV=production babel ./src >/dev/null",
  “build:translations”: “npm run build:messages && node ./scripts/mergeMessages”
}

Обратите внимание на путь в build:translations, что я поместил свой mergeMessages.js скрипт в ./scripts каталог в корне моего проекта (но вы можете поместить его в любое удобное для вас место).

Теперь приступим к созданию наших переводов.

  • создайте папку ./public/locales/ (при использовании приложения create-response-app у вас уже должна быть /public папка).
  • создайте, например, файл итальянского перевода it.json с вашими переводами внутри:
{
  "Headline.main": "Benvenuti nel sito.",
  "Headline.sub": "Ben fatto per aver fatto tutto in questo modo. Congratulazioni."
}

Теперь вы можете запустить свой новый скрипт

yarn build:translations

Если это сработало, теперь у вас должен быть файл по адресу ./src/localeData.json, внутри которого будут находиться ваши определения перевода, например:

Трудная часть сделана.

Конец второго шага.

3. Передайте переводы в react-intl.

Теперь это самое легкое.

Вам необходимо импортировать определения перевода, которые вы создали на localeData.json, и скормить их react-intl в своем приложении. Итак, в вашем index.js будет что-то вроде этого:

Здесь есть несколько вещей (номера строк):

  • импорт localeData.json из нашего сгенерированного файла. (8)
  • получение языка из браузера. Даже IE, шок, ужас. (14)
  • вычеркивая область, чтобы en-GB стало просто en. (18)
  • использование языка для получения определения перевода из localeData.json (20)
  • передача языкового стандарта и переведенных сообщений на react-intl. (26)

И вы сделали. Поздравляю. поздравления. Glückwunsch. Felicidades. Proficiat. Все, что вы действительно хотите.

Таким образом, вы сделали следующее:

  • определил, какие вещи вы хотите перевести, используя <FormattedMessage /> от react-intl.
  • добавил их определение в формате JSON в ваш ./build каталог (теоретически их можно разместить в любом месте, которое игнорируется в вашем .gitignore,, поскольку это одноразовый файл. Чтобы изменить его, измените ключ messagesDir в вашем .babelrc).
  • добавил несколько ваших переводов в ./public/locales/it.json.
  • использовал сценарий, чтобы объединить ваши переводы вместе с языком по умолчанию и поместить их в./src/localeData.json в свой проект.
  • использовал язык браузера, чтобы выбрать, какие переводы использовать.

Вот и все!

Вероятность того, что я совершил ошибку, составляет 99%, поэтому дайте мне знать, если у вас возникнут какие-либо проблемы.