Экспорт переводов для переводчиков

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

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

Форматы ресурсов i18next и структура данных

Основной формат хранения переводов в i18next — JSON. Типичная структура включает пространства имён (namespaces) и языковые коды:

{
  "greeting": "Hello",
  "cart": {
    "title": "Shopping cart",
    "empty": "Cart is empty"
  }
}

При масштабировании приложения применяется разбиение на namespaces:

locales/
  en/
    common.json
    auth.json
    checkout.json
  ru/
    common.json
    auth.json
    checkout.json

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

Извлечение ключей из исходного кода

Экспорт переводов начинается с анализа исходного кода. В i18next ключи обычно используются через функцию t:

t('auth.login.title');
t('checkout.totalPrice');
t('errors.requiredField');

Автоматическое извлечение осуществляется через инструменты анализа AST (Abstract Syntax Tree). Наиболее распространённые решения:

  • i18next-parser
  • i18next-scanner

Они обходят JavaScript/TypeScript код и формируют список ключей, включая:

  • строковые литералы
  • шаблонные ключи
  • пространства имён
  • контексты pluralization

Пример конфигурации i18next-parser:

module.exports = {
  input: ['src/**/*.{js,ts,jsx,tsx}'],
  output: './',
  options: {
    func: {
      list: ['t', 'i18next.t'],
      extensions: ['.js', '.ts']
    },
    lngs: ['en', 'ru'],
    ns: ['common', 'auth'],
    defaultLng: 'en',
    defaultNs: 'common'
  }
};

Генерация файлов ресурсов

После извлечения ключей формируются JSON-файлы, которые могут:

  • создаваться заново при каждой сборке
  • дополняться новыми ключами
  • синхронизироваться с существующими переводами

Типичный сценарий генерации:

i18next-parser

или через npm-скрипт:

{
  "scripts": {
    "extract:i18n": "i18next-parser"
  }
}

Результат работы — обновлённые ресурсы с пустыми значениями для новых ключей:

{
  "auth": {
    "login": {
      "title": "",
      "button": ""
    }
  }
}

Обработка интерполяции и контекста

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

t('welcome.user', { name: 'John' });

Соответствующий ключ в ресурсах:

{
  "welcome": {
    "user": "Welcome, {{name}}"
  }
}

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

Pluralization также учитывается автоматически:

t('cart.item', { count: 3 });
{
  "cart": {
    "item_one": "{{count}} item",
    "item_other": "{{count}} items"
  }
}

Нормализация и формат ключей

В процессе экспорта ключи могут быть:

  • точечными (auth.login.title)
  • вложенными (auth:login:title)
  • плоскими (auth_login_title)

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

Правила нормализации:

  • разделение по .
  • удаление дублирующих сегментов
  • приведение к единому стилю именования

Разделение по namespace при экспорте

При масштабных системах ключи автоматически распределяются по namespace. Например:

t('auth:login.title')
t('checkout:payment.cardNumber')

После экспорта формируются отдельные файлы:

  • auth.json
  • checkout.json

Это позволяет:

  • параллелизовать работу переводчиков
  • снижать конфликтность изменений
  • оптимизировать загрузку переводов

Синхронизация с переводческими платформами

В продвинутых пайплайнах экспорт переводов интегрируется с системами управления локализацией:

  • Locize
  • Phrase
  • Crowdin
  • Lokalise

В таких системах экспорт выполняет роль синхронизации состояния:

  • новые ключи добавляются автоматически
  • устаревшие помечаются как deprecated
  • переводы обновляются по версии

Пример интеграции с Locize:

import LocizeBackend from 'i18next-locize-backend';

i18next.use(LocizeBackend).init({
  backend: {
    projectId: 'project-id',
    apiKey: 'api-key'
  }
});

Обработка удалённых и устаревших ключей

Экспорт переводов включает контроль жизненного цикла ключей. При удалении ключа из кода возможны стратегии:

  • удаление из ресурсов
  • пометка как deprecated
  • перенос в архивный файл

Пример подхода с сохранением:

{
  "_deprecated": {
    "old.key": "legacy value"
  }
}

Такой подход предотвращает потерю контекста при рефакторинге.

CI-пайплайн экспорта переводов

В современных проектах экспорт встроен в непрерывную интеграцию:

  1. Сканирование кода
  2. Извлечение ключей
  3. Генерация JSON
  4. Проверка изменений
  5. Отправка в репозиторий или платформу переводов

Пример CI-шага:

npm run extract:i18n
git diff --exit-code locales/

Если обнаружены изменения, пайплайн фиксирует обновлённые ресурсы.

Работа с fallback и недостающими переводами

Экспорт переводов также учитывает неполные языковые пакеты. i18next использует fallback-языки:

i18next.init({
  fallbackLng: 'en',
  lng: 'ru'
});

При экспорте система может:

  • создавать базовый язык как источник истины
  • генерировать пустые переводы для других языков
  • маркировать отсутствующие ключи

Псевдолокализация как часть экспорта

Для тестирования интерфейса используется псевдолокализация:

{
  "title": "[!!! Ťĥîš îš ţëšţ !!!]"
}

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

  • переполнения UI
  • корректности шрифтов
  • обработки Unicode

Версионирование переводов

Экспорт часто сопровождается версионированием ресурсов:

locales/
  v1/
  v2/

или через hash-based подход:

{
  "_version": "2.4.1"
}

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