В экосистеме 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). Наиболее распространённые решения:
Они обходят JavaScript/TypeScript код и формируют список ключей, включая:
Пример конфигурации 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. Например:
t('auth:login.title')
t('checkout:payment.cardNumber')
После экспорта формируются отдельные файлы:
Это позволяет:
В продвинутых пайплайнах экспорт переводов интегрируется с системами управления локализацией:
В таких системах экспорт выполняет роль синхронизации состояния:
Пример интеграции с Locize:
import LocizeBackend from 'i18next-locize-backend';
i18next.use(LocizeBackend).init({
backend: {
projectId: 'project-id',
apiKey: 'api-key'
}
});
Экспорт переводов включает контроль жизненного цикла ключей. При удалении ключа из кода возможны стратегии:
Пример подхода с сохранением:
{
"_deprecated": {
"old.key": "legacy value"
}
}
Такой подход предотвращает потерю контекста при рефакторинге.
В современных проектах экспорт встроен в непрерывную интеграцию:
Пример CI-шага:
npm run extract:i18n
git diff --exit-code locales/
Если обнаружены изменения, пайплайн фиксирует обновлённые ресурсы.
Экспорт переводов также учитывает неполные языковые пакеты. i18next использует fallback-языки:
i18next.init({
fallbackLng: 'en',
lng: 'ru'
});
При экспорте система может:
Для тестирования интерфейса используется псевдолокализация:
{
"title": "[!!! Ťĥîš îš ţëšţ !!!]"
}
Экспорт может автоматически генерировать такие наборы для проверки:
Экспорт часто сопровождается версионированием ресурсов:
locales/
v1/
v2/
или через hash-based подход:
{
"_version": "2.4.1"
}
Это позволяет отслеживать изменения ключей между релизами и синхронизировать переводческие обновления с версиями приложения.