Мультиязычность ngx-translate в Angular 9 c монорепозиторием Nx.

Aleksandr Serenko
F.A.F.N.U.R
Published in
4 min readFeb 18, 2020
Angular + nx + ngx-translate internationalization

В данной статье поговорим о подходах мультиязычности в Angular 9 с использованием монорепозитория Nx. Рассмотрим механизм локализации в Angular, приведём решение для Angular Universal (SSR).

В предыдущей статье — Internationalization в Angular с помощью ngx-translate, в которой уже описаны основные подходы и принципы. В данной статье мы актуализируем знания и немного изменим SSR реализацию, изменения которой вызваны изменениями серверной сборки.

Подробнее про новые изменения и настройку SSR приложений в Angular, можно прочитать в статье — Angular 9, Universal и Nx. Новые правила сборки SSR приложения.

В Angular есть два подхода для реализации мультиязычности.

Первый подход построен на стандартной реализации локализации — angular/i18n. В основе подхода находится международный стандарт CLDR (Common Locale Data Repository|Общий Репозиторий Языковых Данных).

Второй подход это использование ngx-translate, принцип работы которого заключается в сопоставлении ключей и переводов к ним, для заданных локалей.

Ранее, автор был сторонником второго подхода, так как видел существенные недостатки первого подхода — невозможность смены языка без перезагрузки. Но спустя время, поддерживая и развивая мультиязычный проект, автор столкнулся с минусами и второго подхода — сложность поддержки локализации текста, содержащего HTML. Также явная потребность в смене языка без перезагрузки отсутствует.

Настройка локализации

В данной статье будет рассмотрен второй подход.

Установка зависимостей

Для установки ngx-translate достаточно установить два пакета:

yarn add @ngx-translate/core @ngx-translate/http-loader
  • ngx-translate/core — реализация мультиязычности и соответствующих сервисов и пайпов
  • ngx-translate/http-loader — загрузчик локали по http, который используется для браузерной версии приложения

Если у вас не настроен Universal, но вы хотите получить SSR приложение, тогда, прежде чем продолжить, ознакомьтесь с документацией и со статьей.

Подключение локализации

Сначала подключим локализацию для браузерной версии.
В файле app.browser.module.ts (или app.module.ts, если вы не меняли названия или не приводили проект к ssr) добавим следующий конфиг:

Как видно, в imports был добавлен TranslateModule:

  • TRANSLATION_PREFIX — префикс, который будет использоваться лоадером, чтобы найти файл при загрузке файла, который по умолчанию равен ‘assets/i18n’
  • TRANSLATION_SUFFIX — суффикс, который определяет расширения файла локали, который по умолчанию равен ‘.json’.

Функция translateHttpFactory, которая в данном контексте является фабрикой и создаёт новый загрузчик локализации для TranslateModule.

Данных настроек достаточно для работы браузерной версии. Теперь перейдём к настройке серверной части.

Для этого создадим серверный загрузчик, который будет брать локаль не по http, а с папки, где размещается браузерная версия приложения:

Серверный загрузчик — ServerTranslateLoader, просто с помощью пакетов NodeJS, открывает файл и возвращает локаль.

Фабрика по созданию загрузчика — serverTranslateFactory, как и в предыдущем примере, принимает два аргумента prefix и suffix, которые являются путём расположения файлов и расширением соответственно. Параметр appDist, является необходимым параметром только в монорепозитории Nx, чтобы выбрать локаль из нужного проекта. Поэтому, если вы не используете Nx, просто не передавайте в фабрику данный параметр.

Подключим загрузчик в app.server.module.ts:

TranslateModule сконфигурирован и его можно использовать.

Отметим, разработчик должен сам реализовать сохранение выбранной локали и её восстановление при перезагрузке приложения. Или же реализовать модуль translation, о котором будет рассказано ниже.

Translation Module

Как можно заметить, ngx-translate хранит информацию о локали внутри сервиса.

Для того чтобы настройки локали сохранялись нужен сервис, который будет сохранять настройки локали в веб хранилище или куки. А также сервис, который при первой загрузке приложения будет восстанавливать настройки из хранилища.

Так как автор сторонник использования Redux, данная функциональность будет вынесена в TranslationState. Но как говорилось ранее, потребность локализации и её смене настолько мала, что вместо того, чтобы создавать множество файлов для реализации и поддержки state, достаточно вызвать один метод класса сервиса — init.

Объявление интерфейсов

Сначала добавим интерфейс для настроек локали и сервиса, который будет сохранять настройки.

TranslationStorage:

TranslationService:

Вынесем токены в один общий файл:

Реализация сервисов

Добавим реализацию для TranslationStorage:

Добавим реализацию для TranslationService:

Добавим конфигурацию для TranslationModule и сам модуль:

Как видно из реализации, используется APP_INITIALIZER, для определения инициализации приложения и запуск сервиса установки языка.

Отметим, что translationLoader возвращает промис, а это значит, что приложение не отрисуется пока не выполняться все APP_INITIALIZER промисы.

Добавим TranslationModule в AppModule и запустим проект:

Все отлично работает.

TranslationState

Если вам по какой-то необходимости необходимо вынести все события в Redux, то приведём реализацию с TranslateState:

Заметим, что state разработан с предыдущим style guide от Nx. В последней версии style guide Nx, удалось сократить дублирование кода. Подробнее можно посмотреть в схемах Nx.

Добавим наш state в TranslationModule:

Запустим и убедимся, что это тоже работает как и предыдущий вариант:

Резюме

Обобщая выше сказанное, в данной статье:

  • Поговорили о способах реализации мультиязычности в Angular.
  • Выбрали в качестве мультиязычности подход перевода методом ключ — значение, предоставляемое ngx-translate.
  • Произвели установку и настройку ngx-translate для браузерной и серверной версий.
  • Привели решение для сохранения и восстановления локали, реализовав TranslationModule в двух вариантах с и без использования ngrx.

Исходники

Все исходники находятся на github, в репозитории:

Для того, чтобы посмотреть состояние проекта на момент написания статьи, нужно выбрать соответствующий тег — translation-second.

git checkout translation-second

Код можно посмотреть в разделе https://github.com/Fafnur/medium-stories/tree/master/apps/frontend/translation.

Спасибо за внимание!
Подписывайтесь на канал, чтобы не пропустить новые статьи про Angular и новости из мира фронтенд разработки.

Предыдущие статьи:

  1. GraphQL API для Angular с помощью NX и Nest.
  2. Интеграция GraphQL API в Angular приложение
  3. Динамические формы в Angular или автоматизируем создание Angular форм
  4. Создание переменных в шаблонах Angular. Превращение реактивных свойств в простые объекты.
  5. Angular 9, Universal и Nx. Новые правила сборки SSR приложения.
  6. Кроссплатформенные web storage в Angular 9. Реализация LocalStorage, SessionStorage и Cookies в Angular Universal.

--

--

Aleksandr Serenko
F.A.F.N.U.R

Senior Front-end Developer, Angular evangelist, Nx apologist, NodeJS warlock