Локализация в Angular 9 с помощью @angular/localize с universal

Aleksandr Serenko
F.A.F.N.U.R
Published in
5 min readApr 16, 2020

В данной статье поговорим о стандартном механизме локализации в Angular предоставляемая пакетом @angular/localize. Рассмотрим основы локализации и приведём примеры использования с Nx.

В предыдущих статьях был рассмотрен механизм локализации с помощью @ngx-translateМультиязычность ngx-translate в Angular 9 c монорепозиторием Nx.

Хоть ngx-translate представляет удобный подход по локализации приложения в runtime, однако потребность в этом невелика.

Одним из весомых аргументов использования ngx-translate если планируется использовать nativescript и Angular до 9 версии. В Angular 9, проблему с локализацией решили, с помощью изменения подхода к локализации шаблонов. Поброднее — Migration-localize.

Установка локали

Если в проекте не было локали, добавьте её с помощью команды:

/***************************************************************************************************
* Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
*/
import '@angular/localize/init';

После установления пакета, в polyfills добавиться строчка с подключением локали в проект:

import '@angular/localize/init';

По умолчанию в Angular основной локалью является Английский язык (en-US).

Для того, чтобы добавить другие языки, нужно в angular.json добавить конфиг:

"frontend-localization": {  
...
"i18n": {
"sourceLocale": "en-US",
"locales": {
"ru": {
"translation": "apps/frontend/localization/src/locales/messages.ru.xlf",
"baseHref": ""
},
"en": {
"translation": "apps/frontend/localization/src/locales/messages.en.xlf",
"baseHref": ""
}
}
},
...

Как видно, были добавлены две локализации ru и en (без привязки к стране).

Так как примеры будут приводиться в монорепозитории Nx, то все пути имеют префикс конкретного приложения — frontend-localization, равный apps/frontend/localization. Если вы используете просто Angular, то в конфигурации данного префикса не будет, и все пути будут выглядеть src/locales/messages.en.xlf

Для того, чтобы после компиляции были созданы локализированные сборки, добавим конфигурацию локали в сборку:

"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
...
"configurations": {
"production": {
...
"localize": ["ru", "en"]
},
"ru": {
"localize": true
}
}
}
}

Также добавим отдельную конфигурацию — “ru” для локальной разработки.

"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "frontend-localization:build"
},
"configurations": {
...
"ru": {
"browserTarget": "frontend-localization:build:ru"
}
}
}

Также для корректной работы Universal добавим в серверную сборку локаль:

"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"localize": false
},
"configurations": {
"production": {
...
"localize": ["en", "ru"]
}
}
},

Как видно, по умолчанию localize = false. Это необходимо, так как сейчас, сервер может корректно работать только с одной локалью. Поэтому немного изменим конфиг и добавим локаль при серверной сборке:

export function app(language) {
const distFolder = join(process.cwd(), 'dist/apps/frontend/localization/browser', language);
...
}
function run() {
const port = process.env.PORT || 4000;
const language = process.env.LANGUAGE || 'en';
}

Для тестирования Universal добавим конфиг:

"serve-ssr": {
"builder": "@nguniversal/builders:ssr-dev-server",
...
"configurations": {
...
"ru": {
"browserTarget": "frontend-localization:build:ru",
"serverTarget": "frontend-localization:server"
}
}
},

Общий конфиг будет следующим:

Полная настройка server.ts:

Использование локализации

При использовании pipe’ов (дата и тд.) необходимо импортировать и подключить соответствующие пакеты локалей в AppModule:

import { registerLocaleData } from '@angular/common';
import localeRu from '@angular/common/locales/ru';
registerLocaleData(localeRu);

Для использования локали создадим простой компонент, в котором выведем приветствие.

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

ng xi18n --output-path src/locales --project=frontend-localization

В результате выполнения команды, будет сгенерирован файл: messages.xlf.

Копируем файл, и переименовываем его в messages.ru.xlf.

Добавляем переводы в файл:

Запуск приложения с разными локализациями

Все команды для запуска приложения:

"localization:serve": "ng serve frontend-localization",
"localization:serve:ru": "ng serve frontend-localization --configuration=ru",
"localization:serve:ssr:dev": "ng run frontend-localization:serve-ssr",
"localization:serve:ssr:dev:ru": "LANGUAGE=ru ng run frontend-localization:serve-ssr --configuration=ru",
"localization:build:ssr": "ng build frontend-localization --prod && ng run frontend-localization:server:production",
"localization:serve:ssr:en": "PORT=4000 LANGUAGE=en node dist/apps/frontend/localization/server/en/main.js",
"localization:serve:ssr:ru": "PORT=4001 LANGUAGE=ru node dist/apps/frontend/localization/server/ru/main.js",
"localization:generate:translate": "ng xi18n --output-path src/locales --project=frontend-localization"

Для запуска локальной разработки используем команду:

ng serve frontend-localization --configuration=ru

Для запуска дев версии Universal используем команду:

LANGUAGE=ru ng run frontend-localization:serve-ssr --configuration=ru

Для сборки прод версии, используем команду:

ng build frontend-localization --prod && ng run frontend-localization:server:production

Для запуска прод версии в Universal для каждой локали нужно поднимать отдельный node server.

На 1 апреля 2020, нет адекватного решения как можно было бы объединить сервера в один.

Для того, чтобы сформировать префиксы путей (basePath) рекомендуется это делать на уровне прокси сервера (nginx).

Запустим русскую версию:

PORT=4001 LANGUAGE=ru node dist/apps/frontend/localization/server/ru/main.js

Резюме

В данной статье рассмотрели подключение и использование стандартного механизма локализации в Angular. Привели пример использования локализации и запустили приложение с Universal.

Спасибо за внимание!

Исходники

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

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

git checkout ln

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

Ссылки

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

Medium: https://medium.com/fafnur
Добавляйтесь в группу ВК: https://vk.com/fafnur
Добавляйтесь в группу в Fb: https://www.facebook.com/groups/fafnur/
Телеграм канал: https://t.me/f_a_f_n_u_r
Twitter: https://twitter.com/Fafnur1
Instagram: https://www.instagram.com/fafnur

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

  1. Мультиязычность ngx-translate в Angular 9 c монорепозиторием Nx.
  2. Redux в Angular. Управление состояниями в Angular с помощью Ngrx и Nx.
  3. Структура и подходы к организации экшенов, селекторов, редьюсеров и эффектов в Ngrx и Nx.
  4. Тестирование сервисов в Angular с помощью Jest. Тестирование реактивной/асинхронной логики.
  5. Тестирование Ngrx store в Angular. Методы и подходы для упрощения тестирование stat’ов Ngrx в Nx.
  6. Сборка Typescript приложения с помощью Webpack

--

--

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

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