AngularInDepth уходит от Medium. Более свежие статьи размещаются на новой платформе inDepth.dev. Спасибо за то, что участвуете в глубоком движении!

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

В этом мире мы рассмотрим все возможности, которые предоставляет нам Transloco, каковы проблемы и какие пути у нас есть для их решения.

Использование областей видимости

Первый вариант, который у нас есть, - поместить каждый из наших языковых файлов перевода в папку assets/i18n:

├─ 📂 i18n/
   ├─ 📜 en.json
   ├─ 📜 es.json

В этом случае Transloco загрузит файл активного языка и будет использовать его для переводов.

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

Чтобы помочь вам в этом, Transloco позволяет определить папку «объема» для каждого из наших языков, что дает нам возможность не только разделять наши файлы переводов, но и загружать их лениво.

├─ 📂 i18n/
   ├─ 📜 en.json
   ├─ 📜 es.json
   └─ 📂 admin/
      ├─ 📜 en.json
      ├─ 📜 es.json

Более подробную информацию об использовании прицелов можно найти здесь.

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

Использование встроенных загрузчиков

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

Посмотрим, как мы можем это использовать. Скажем, у нас есть следующий проект CLI:

├─ 📂 app/
   ├─ 📜 app-routing.module.ts
   ├─ 📜 app.component.css
   ├─ 📜 app.component.html
   ├─ 📜 app.module.ts
   ├─ 📜 transloco.loader.ts
   └─ 📂 feature/   
      ├─ 📜 feature.module.ts
      ├─ 📜 feature.component.ts
      ├─ 📜 feature.component.html
      ├─ 📜 feature.component.css
      ├─ 📜 feature.module.ts
      └─ 📂 i18n/
         ├─ 📜 en.json
         ├─ 📜 es.json
├─ 📂 assets/
   └─ 📂 i18n/
      ├─ 📜 en.json
      ├─ 📜 es.json‌

Чтобы загрузить переводы функции, мы можем определить TRANSLOCO_SCOPE провайдера и передать встроенный загрузчик, который использует функцию Webpack import для ленивой загрузки локальных файлов перевода:

Обратите внимание, что при использовании встроенного загрузчика ключ scope используется как alias.

Теперь мы можем просто перевести наш контент, используя scope, который мы определили:

Совет: начиная с Transloco v2.11, мы можем использовать флаг --inline-Loader для создания наших областей действия с помощью встроенных загрузчиков! 😁

Работа с Monorepos

Бывают случаи, когда мы хотим использовать Transloco в наших npm библиотеках (что является обычным явлением в monorepo среде). В этих случаях мы, вероятно, захотим, чтобы файлы перевода находились в папке библиотеки и отправляли их вместе с ней.

К сожалению, есть две основные трудности: ‌

  1. У нас нет доступа к каталогу public приложения, поэтому мы не можем загрузить их с помощью HTTP-запроса.
  2. Динамический Webpack imports не работает с библиотеками.

Давайте посмотрим, какие варианты у нас есть для решения этих проблем:

Загрузить файлы перевода с сервера

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

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

Такой подход подойдет, но он подходит не всем, давайте посмотрим другое решение.

Загрузка переводов Eagrly

Другой вариант - быстро загрузить каждый из файлов перевода и использовать метод setTranslation для их добавления.

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

📦projects
└─ 📂core
   └─ 📂src
      └─ 📂lib
         ├─ 📜core.component.ts
         ├─ 📜core.module.ts
         ├─ 📜public-api.ts
         ├─ 📜ng-package.json
         ├─ 📜package.json
         └─ 📂 i18n/
            ├─ 📜 en.json
            ├─ 📜 es.json‌
📦src
└─ 📂 app/
   ├─ 📜 app-routing.module.ts
   ├─ 📜 app.component.css
   ├─ 📜 app.component.html
   ├─ 📜 app.module.ts
   ├─ 📜 transloco.loader.ts
   └─ 📂 assets/
      └─ 📂 i18n/
         ├─ 📜 en.json
         ├─ 📜 es.json‌

Мы могли бы передать каждый из используемых языков, вызвав метод setTranslation:

Transloco объединит предоставленный объект перевода с предоставленным языком.

Мы также можем ограничить его определенным пространством имен, например:

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

Библиотеки с ограниченной областью видимости

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

Но это была бы работа обезьяны

К счастью, Transloco предоставляет нам еще один отличный инструмент для этой задачи: Scoped Library Extractor, который сделает эту работу за нас.

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

📦projects
└─ 📂core
   └─ 📂src
      └─ 📂lib
         ├─ 📜core.component.ts
         ├─ 📜core.module.ts
         ├─ 📜public-api.ts
         ├─ 📜ng-package.json
         ├─ 📜package.json
         └─ 📂 i18n/
            ├─ 📜 en.json
            ├─ 📜 es.json‌
📦src
└─ 📂 app/
   ├─ 📜 app-routing.module.ts
   ├─ 📜 app.component.css
   ├─ 📜 app.component.html
   ├─ 📜 app.module.ts
   ├─ 📜 transloco.loader.ts
   └─ 📂 assets/
      └─ 📂 i18n/
         ├─ 📜 en.json
         ├─ 📜 es.json‌

Во-первых, нам нужно объявить TRANSLOCO_SCOPE в модуле библиотеки:

Теперь мы можем использовать scope внутри библиотеки:

‌Далее нам нужно установить transloco-scoped-libs:

$ npm install @ngneat/transloco-scoped-libs --save-dev

‌ Первое, что нам нужно сделать, это добавить i18n конфигурацию с путем к папке перевода в package.json библиотеки:

Затем нам нужно добавить путь к библиотеке в transloco.config.js следующим образом (мы также можем передать пакет npm):

Наконец, нам нужно добавить следующий скрипт к основному package.json

"scripts": {
  "transloco:extract-scoped-libs": "transloco-scoped-libs"
}

‌Обратите внимание, что он также поддерживает «режим просмотра» с использованием флага --watch.

Теперь, если мы запустим скрипт, произойдет следующее:

  1. Скрипт извлечет файлы перевода из нашей библиотеки и скопирует их в корневую папку переводов основного проекта (например, src/assets/i18n).
  2. Он добавит файлы перевода библиотеки в .gitignore.

Стратегия соединения

‌Этот инструмент поддерживает две разные стратегии. Вариант по умолчанию, тот, который мы использовали выше, и join.

‌Стратегия join объединит все файлы перевода в один файл под корневым путем перевода для каждого языка (например, en.vendor.json).

Мы можем установить стратегию в package.json нашей библиотеки:

‌Тогда мы можем использовать его в нашем загрузчике приложений:

Использование с плагином Webpack

Мы также можем использовать плагин Webpack с помощью такого инструмента, как ngx-build-plus, и добавить плагин в webpack.config файл:

Жадные модули

«Активные модули - это все модули, которые загружаются до запуска приложения».

Как и любой другой провайдер, области также подчиняются правилам Angular DI. Следовательно, если мы используем активный модуль, который объявляет область видимости, в функции модуля, которая также объявляет ее, область действия функционального модуля будет перекрывать область действия активного модуля.

Чтобы этого не произошло, у нас есть несколько вариантов:

  1. Первый - просто объявить переводы активного модуля в файлах глобального перевода.
  2. Другой вариант - использовать технику из раздела «Загрузка переводов Eagrly».
  3. Последний вариант - объявить область видимости либо в поставщике компонента:

Или в HTML-шаблоне компонента:

🎁 Бонусная секция - Split & Join

Разделение нашего перевода между файлами иногда может быть обузой, особенно когда нам нужно отправить их переводчикам как единое целое.

Transloco решает эту проблему за нас, предоставляя нам две команды схемы: Split & Join.

Присоединиться

Команда join объединит все наши файлы переводов в одну часть для каждого языка.

$ ng g @ngneat/transloco:join

‌По умолчанию сценарий сборки перебирает корневой каталог файла перевода и будет ссылаться на каждый подкаталог как на область.

Обратите внимание, если у вас есть несколько папок с записями для файлов перевода, вам нужно будет добавить сопоставление для каждой записи папки и имени области. Это можно сделать с помощью свойства scopePathMap в вашем transloco.config.js файле.

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

├─ 📂 i18n/
   ├─ 📜 en.json
   ├─ 📜 fr.json
   ├─ 📜 es.json
   └─ 📂 todos/
      ├─ 📜 en.json
      ├─ 📜 fr.json
      ├─ 📜 es.json

Сценарий выполнит все файлы каталогов (за вычетом языка по умолчанию) и объединит файлы области видимости с основными файлами перевода.

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

Если у нас есть несколько папок ввода для области, мы можем указать карту между именем области и путем к переводам, используя свойство scopePathMap в вашем transloco.config.js файле:

Обратите внимание, что как только вы укажете scopePathMap, сценарий будет использовать его автоматически.

Расколоть

Команда split действует противоположно join: она берет переведенные файлы и обновляет файлы перевода проекта.

$ ng g @ngneat/transloco:split

📢 Пример проекта, содержащий все вышеперечисленное, можно найти здесь.

Если вам понравился пост, поделитесь им и не забудьте выразить свою признательность, отметив библиотеку на Github!

⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️