Автоматизация workflow в i18next представляет собой совокупность практик и инструментов, позволяющих минимизировать ручную работу с переводами, снизить вероятность рассинхронизации ключей и обеспечить стабильную доставку локализаций на всех этапах разработки — от написания кода до продакшена.
Типовой workflow строится вокруг нескольких уровней:
Каждый уровень может быть автоматизирован отдельно, но максимальный эффект достигается при их совместном использовании.
Одним из базовых этапов автоматизации является анализ исходного кода и сбор всех используемых ключей переводов.
Чаще всего применяется инструмент i18next-parser,
который сканирует JavaScript/TypeScript/JSX файлы и формирует
JSON-структуры ресурсов.
module.exports = {
input: ['src/**/*.{js,jsx,ts,tsx}'],
output: './locales/$LOCALE/$NAMESPACE.json',
options: {
func: {
list: ['t', 'i18next.t', 'i18n.t']
},
lngs: ['en', 'ru', 'de'],
defaultLng: 'en',
defaultNs: 'common',
resource: {
loadPath: './locales/{{lng}}/{{ns}}.json',
savePath: './locales/{{lng}}/{{ns}}.json'
}
}
};
{
"button.save": "",
"form.title": "",
"errors.required": ""
}
Пустые строки сигнализируют о необходимости заполнения переводов.
Проблема рассинхронизации возникает при параллельной разработке. Разные ветки могут добавлять новые ключи, не учитывая существующие ресурсы.
Автоматизация решает это через:
const fs = require('fs');
function mergeLocales(base, target) {
return {
...base,
...Object.fromEntries(
Object.keys(base).map(key => [
key,
target[key] || ''
])
)
};
}
В промышленной разработке локализации редко хранятся только в репозитории. Используются системы управления переводами:
Типовой pipeline:
source.jsoni18next-parser
crowdin upload sources
crowdin download translations
CI/CD пайплайн позволяет проверять корректность переводов до попадания кода в main-ветку.
function validateTranslations(locales) {
const base = locales.en;
return Object.keys(base).filter(key => {
return !Object.values(locales).every(lang => lang[key]);
});
}
Если список непустой — сборка может завершаться ошибкой.
Husky и lint-staged позволяют предотвращать попадание неконсистентных переводов в репозиторий.
{
"lint-staged": {
"src/**/*.{js,ts,tsx}": [
"i18next-parser",
"node scripts/validate-i18n.js"
]
}
}
Такой подход обеспечивает актуальность ключей в момент коммита, а не после деплоя.
При использовании TypeScript важным элементом становится типизация ключей переводов.
export interface I18nKeys {
"button.save": string;
"form.title": string;
"errors.required": string;
}
Более продвинутый вариант — автогенерация через CLI:
i18next-types-generator --input ./locales --output ./types/i18n.d.ts
Это позволяет исключить ошибки обращения к несуществующим ключам на этапе компиляции.
Автоматизация загрузки переводов уменьшает размер бандла и ускоряет старт приложения.
i18next
.use(Backend)
.init({
ns: ['common', 'auth'],
defaultNS: 'common',
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json'
}
});
В Webpack или Vite перевод может загружаться вместе с компонентом:
import('locales/ru/auth.json');
В продакшене часто требуется fallback-механизм и логирование отсутствующих ключей.
i18next.on('missingKey', function(lng, ns, key) {
console.warn(`Missing translation: ${key}`);
});
Эти данные могут автоматически отправляться в систему аналитики или TMS.
Псевдолокализация позволяет выявлять UI-проблемы до реального перевода.
Пример трансформации:
Save → ŜȧṽḗProfile settings →
[!!! Pŕôƒīļë śëţţīñğś !!!]function pseudoLocalize(str) {
return str
.replace(/a/g, 'á')
.replace(/e/g, 'ë')
.replace(/i/g, 'ï')
.replace(/o/g, 'ô')
.replace(/u/g, 'ü');
}
Разделение переводов на namespaces снижает нагрузку и упрощает поддержку.
Типовая структура:
locales/
en/
common.json
auth.json
dashboard.json
Скрипт может анализировать префиксы:
auth.login.title → auth.jsondashboard.header.title →
dashboard.jsonАвтоматизация включает метрики:
function generateReport(locales) {
const keys = Object.keys(locales.en);
const stats = keys.map(key => ({
key,
missing: Object.values(locales).some(lng => !lng[key])
}));
return {
total: keys.length,
missing: stats.filter(s => s.missing).length
};
}
В современных приложениях i18next тесно связан с системой сборки.
module.exports = {
module: {
rules: [
{
test: /locales\/.*\.json$/,
type: 'javascript/auto',
use: 'json-loader'
}
]
}
};
export default {
optimizeDeps: {
include: ['i18next']
}
};
Тесты позволяют гарантировать целостность переводов.
test('all keys exist in all locales', () => {
const keys = Object.keys(locales.en);
localesList.forEach(locale => {
keys.forEach(key => {
expect(locales[locale][key]).toBeDefined();
});
});
});
Скрипты watch-режима позволяют поддерживать актуальность ресурсов в реальном времени.
i18next-parser --watch
При изменении файлов ключи мгновенно добавляются в JSON-ресурсы.
Переводы часто требуют версионирования отдельно от кода.
Стратегии:
{
"a8f4c2_login_title": "Вход"
}
i18next поддерживает плагины кэширования:
i18next.use(Backend).init({
backend: {
loadPath: '/locales/{{lng}}/{{ns}}.json',
requestOptions: {
cache: 'force-cache'
}
}
});
Современный production workflow обычно включает:
t('key')