Интернационализация (i18n) всегда была и всегда будет занозой в заднице. Перевод вашего приложения - сложная задача: от определения локали пользователя до уделения внимания различным структурам предложений на разных языках, вам нужно учесть довольно много вещей.

Эта статья покажет вам мой способ перевода приложения React путем сохранения переводов каждой строки в базе данных.

Идея

Стандартный способ хранения переводов - создать token вместо фактического текста в вашем коде. Затем где-то в вашем коде есть файл translations.json, содержащий переведенное сообщение. Служба перевода позаботится о токене, выполнив поиск его перевода в translations.json и заменив токен найденным значением.

Дополнительные вещи, которые мы сделаем:

  • Сохраните переводы в базе данных.
  • Каждый перевод автоматически добавляется в базу данных.
  • Создайте файл translations.js из базы данных

Весь процесс будет выглядеть так:

  • Напишите код JSX и добавьте токен вместо строки.
  • Извлеките все токены из кодовой базы.
  • Отправьте эти токены в базу данных.
  • Заполните соответствующие переводы для каждого токена.
  • Получите переводы из базы данных.

Куча

Я использовал AWS DynamoDB в качестве базы данных, AWS Lambda на бэкэнде и React (с использованием CRA) во внешнем интерфейсе, но эти методы будут работать с любой базой данных / серверной частью.

1. Напишите код JSX.

Я использовал react-intl, чтобы заменить токены на текст. Они сделали очень исчерпывающую документацию, но самое важное, что вам нужно знать:

Вы должны заключить свой App компонент в intlProvider и передать ему текущий язык и соответствующие переводы. Я венгр, поэтому в этой статье я буду использовать английский и венгерский переводы. Ваш index.js должен выглядеть примерно так:

React-intl предоставляет 2 метода внедрения текста в ваш проект: есть простое, но несовершенное решение и немного более сложное, но идеальное решение.

Простой вариант предлагает более чистый код, но вводимый текст всегда будет внутри тегов <span>. Иногда это приемлемо, но иногда может испортить ваш CSS или общую структуру страницы:

Сложный предлагает чистый текст за счет большего количества кода:

2. Извлеките все токены.

Извлечение означает поиск всех токенов и их объединение в отдельный файл JSON. К счастью, react-intl поддерживает извлечение.

Если вы не используете приложение Create React, вы можете просто установить babel-plugin-react-intl и использовать его для извлечения переводов.

К сожалению, CRA не поддерживает этот плагин, поэтому, покопавшись, я обнаружил react-intl-cra, что делает процесс извлечения безупречным.

Установите response-intl-cra, и если у вас еще не настроен babel, пора это сделать.

npm install --save-dev babel-cli babel-preset-env react-intl-cra

и создайте в корне .babelrc файл, содержащий:

{ "presets": ["env"] }

При извлечении создается огромный messages.json файл, в котором мы храним все наши токены. Я использую сценарий, чтобы преобразовать контент в структуру, более похожую на словарь. (Я взял сценарий из этой большой статьи). Создайте каталог scripts/ в корневом каталоге и поместите этот сценарий в файл с именем translate.js.

Создайте новую строку в вашем package.json файле в разделе скриптов:

При выполнении npm run build:translations будет сгенерирован JSON, содержащий наши токены и их сообщения по умолчанию.

3. Отправьте токены в базу данных

Создайте новый файл с именем copyTranslationsToDb.js и поместите его в свою scripts/ папку. Здесь мы публикуем сообщения в API для заполнения базы данных.

Давайте включим этот скрипт в npm run build:translations скрипт.

Выполнение npm run build:translations теперь извлечет все токены из нашей кодовой базы и отправит их в базу данных.

4. Заполните жетоны

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

5. Получить переводы из базы данных

Создайте новый файл с именем fetchTranslationsFromDb.js и поместите его в папкуscripts/.

Это создаст файл JSON для каждого языка, указанного в массиве supportedLanguages. Конечные точки, которые я использовал, являются простыми конечными точками CRUD, вы должны применить свою собственную логику, чтобы приспособить этот подход к вашему приложению.

Создайте новую строку в package.json:

Когда вы закончите заполнять переводы, вам просто нужно запустить

npm run fetch:translations

и страница будет перезагружена с новыми переводами.

Резюме

Это ни в коем случае не идеальное решение проблемы, больше похоже на рабочий MVP. Очевидным недостатком этого процесса является то, что вам нужно вручную запустить fetch:translations, чтобы фактически изменить переводы. Что мы сделали в моей компании, так это то, что мы встроили команды build и fetch в наш конвейер CI Gitlab, поэтому всякий раз, когда мы хотим изменить текст, достаточно просто нажать redeploy. В будущем мы планируем создать новый микросервис, который напрямую занимается доставкой и кэшированием переводов, но это создает единую точку отказа, поэтому текущий подход «развертывание переводов вместе с проектом» будет по-прежнему использоваться в качестве запасного механизма, если новая микрослужба выйдет из строя.

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

Даниэль