Проверка полноты переводов

Проверка полноты переводов в i18next опирается на механизм сопоставления ключей переводов между исходным языком и целевыми локалями, а также на инструменты обнаружения отсутствующих ресурсов во время выполнения и сборки. В основе лежит концепция ресурсных словарей, где каждая языковая версия представляет собой набор namespace-структур с ключами и значениями.


Переводы в i18next организуются по следующей схеме:

  • язык (например, en, ru, de)
  • namespace (например, common, auth, validation)
  • ключи (например, button.save, error.required)

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

{
  "common": {
    "button.save": "Save",
    "button.cancel": "Cancel"
  }
}

Отсутствие любого ключа в конкретной локали приводит к срабатыванию fallback-логики или возврату ключа как строки, что используется как основной индикатор неполноты.


Механизмы определения отсутствующих переводов

Проверка через t и fallback-цепочку

Функция t выполняет поиск ключа в следующем порядке:

  1. текущий язык
  2. fallback язык(и)
  3. возвращение ключа

Если ключ отсутствует во всех уровнях, он считается непереведённым.

i18next.t('common.button.save')

Поведение при отсутствии зависит от конфигурации:

  • returnKeyIfNotFound: true — возвращается ключ
  • fallbackLng — используется язык-запас
  • parseMissingKeyHandler — обработка отсутствующих ключей

Режим debug как инструмент аудита

Включение режима debug позволяет фиксировать все случаи отсутствующих переводов:

i18next.init({
  debug: true,
  fallbackLng: 'en'
});

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


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

Одним из ключевых механизмов контроля является обработчик отсутствующих ключей:

i18next.init({
  missingKeyHandler: function(lng, ns, key, fallbackValue) {
    console.warn('Missing translation:', { lng, ns, key });
  }
});

Этот механизм позволяет:

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

Опция saveMissing и серверная фиксация пробелов

При включении saveMissing i18next автоматически отправляет отсутствующие ключи в backend:

i18next.init({
  saveMissing: true,
  backend: {
    loadPath: '/locales/{{lng}}/{{ns}}.json'
  }
});

Сценарий работы:

  1. ключ не найден
  2. вызывается missingKeyHandler
  3. отправляется запрос на сервер
  4. сервер сохраняет ключ в файл или базу

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


Проверка через exists

Метод exists позволяет явно проверять наличие ключа:

i18next.exists('common.button.save', { lng: 'ru' });

Возвращает:

  • true — ключ присутствует
  • false — ключ отсутствует

Этот метод используется для:

  • статической валидации интерфейса
  • тестов покрытия переводов
  • проверки перед рендерингом UI

Анализ ресурсного хранилища

i18next хранит переводы в resourceStore, который можно использовать для аудита полноты:

const store = i18next.services.resourceStore.data;

Структура:

{
  ru: {
    common: {
      "button.save": "Сохранить"
    }
  },
  en: {
    common: {
      "button.save": "Save"
    }
  }
}

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

  • отсутствующие переводы
  • неполные namespace
  • рассинхронизацию версий

Проверка полноты по namespace

Часто используется проверка на уровне namespace:

const enKeys = Object.keys(i18next.getResourceBundle('en', 'common'));
const ruKeys = Object.keys(i18next.getResourceBundle('ru', 'common'));

const missing = enKeys.filter(k => !ruKeys.includes(k));

Этот подход позволяет получить список недостающих переводов для конкретного языка.


Влияние вложенных ключей и separator-логики

i18next поддерживает вложенные структуры:

{
  "error": {
    "required": "Field is required"
  }
}

При использовании keySeparator: '.' ключи интерпретируются как:

error.required

Проверка полноты должна учитывать:

  • глубину вложенности
  • разделители keySeparator
  • разделители namespace nsSeparator

Плагины для анализа полноты переводов

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

  • парсеры исходного кода, извлекающие ключи
  • сравнение с ресурсами JSON
  • генерация отчётов

Пример логики парсинга:

  1. извлечь все t('...') из кода
  2. сформировать список ключей
  3. сопоставить с ресурсами каждого языка
  4. вычислить разницу множеств

i18next-parser и генерация базового покрытия

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

  • сканирование JSX / JS / TS
  • построение карты используемых ключей
  • генерация шаблонов переводов

Это позволяет выявить:

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

Полнота с учётом pluralization

Множественные формы добавляют дополнительный слой проверки:

{
  "item": "{{count}} item",
  "item_plural": "{{count}} items"
}

Отсутствие хотя бы одной формы считается неполнотой.

Проверка должна учитывать:

  • plural
  • singular
  • zero формы (в некоторых языках)

Интерполяция и пропущенные параметры

Ключи с интерполяцией требуют дополнительной проверки структуры:

{
  "welcome": "Hello {{name}}"
}

Неполные переводы могут проявляться как:

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

Сравнение выполняется по шаблону:

  • извлечение {{...}}
  • сопоставление наборов переменных между языками

Контроль полноты через тестирование

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

const resources = i18next.getDataByLanguage('ru');

Object.keys(resources.common).forEach(key => {
  if (!i18next.exists(key, { lng: 'ru' })) {
    throw new Error(`Missing translation: ${key}`);
  }
});

Такой подход позволяет интегрировать проверку в CI-пайплайны.


Проверка fallback-эффекта как индикатора неполноты

Fallback поведение часто маскирует отсутствие переводов. Поэтому анализ включает:

  • отключение fallback в тестовой среде
  • фиксацию случаев возврата английского текста в локалях
  • сравнение языка вывода с запрошенным языком

Если язык запроса не совпадает с языком результата — перевод считается неполным.


Практика аудита покрытия переводов

Полноценный аудит обычно включает:

  • сбор всех используемых ключей из кода
  • сбор всех ключей из ресурсов
  • построение матрицы покрытия по языкам
  • анализ namespace-дисбаланса
  • проверку plural и interpolation

Результатом становится карта покрытия:

ru: 92%
en: 100%
de: 78%

Проблемы, влияющие на точность проверки

Основные источники ошибок:

  • динамические ключи (t(getKey()))
  • составные ключи
  • runtime-генерация namespace
  • ленивые загрузчики backend

Эти случаи требуют дополнительного статического или runtime-логирования, поскольку простое сравнение ресурсов не выявляет всех пробелов.