Backend-плагины в i18next отвечают за получение, загрузку и, в некоторых сценариях, создание переводов из внешних источников. Основная идея заключается в разделении ответственности: ядро i18next управляет интернационализацией, а backend-слой определяет способ доставки языковых ресурсов.
Такая архитектура позволяет абстрагироваться от конкретного источника переводов: файловая система, HTTP API, база данных или комбинированные решения становятся взаимозаменяемыми компонентами без изменения логики приложения.
i18next оперирует структурой ресурсов следующего вида:
Пример внутреннего представления:
{
"ru": {
"translation": {
"welcome": "Добро пожаловать"
}
}
}
Backend-плагин участвует в процессе, когда требуется:
Любой backend для i18next реализует строго определённый контракт. Наиболее часто используются методы:
read(language, namespace, callback)readMulti(languages, namespaces, callback)create(languages, namespace, key, fallbackValue)init(services, backendOptions, i18nextOptions)type (идентификация backend)Минимальная форма:
class CustomBackend {
constructor(services, options = {}) {
this.init(services, options);
}
init(services, options = {}, i18nextOptions = {}) {
this.services = services;
this.options = options;
this.i18nextOptions = i18nextOptions;
}
read(language, namespace, callback) {
callback(null, {});
}
}
Метод read является ключевым: именно он возвращает набор
переводов для конкретного языка и namespace.
Одним из наиболее распространённых решений является файловый backend для Node.js. Он используется в серверных приложениях, где доступна файловая система.
Типичная реализация:
import Backend from "i18next-fs-backend";
i18next
.use(Backend)
.init({
lng: "ru",
fallbackLng: "en",
backend: {
loadPath: "./locales/{{lng}}/{{ns}}.json"
}
});
Шаблоны путей позволяют динамически формировать структуру:
./locales/en/translation.json
./locales/ru/translation.json
В клиентских приложениях используется HTTP backend, который загружает переводы с удалённого сервера.
import HttpBackend from "i18next-http-backend";
i18next
.use(HttpBackend)
.init({
backend: {
loadPath: "https://example.com/locales/{{lng}}/{{ns}}.json"
}
});
Backend может поддерживать массовую загрузку:
readMulti(languages, namespaces, callback)
Пример вызова:
backend.readMulti(
["en", "ru"],
["translation", "common"],
(err, data) => {}
);
Это снижает количество запросов и оптимизирует старт приложения.
Backend интегрируется в систему i18next через последовательность этапов:
.use()init()Встроенные и кастомные backend-реализации часто используют кеширование:
В i18next кеширование происходит на уровне:
Одним из ключевых сценариев является загрузка переводов по мере необходимости.
Пример конфигурации:
i18next.init({
ns: ["common"],
defaultNS: "common",
partialBundledLanguages: true,
backend: {
loadPath: "/locales/{{lng}}/{{ns}}.json"
}
});
При запросе ключа из другого namespace backend автоматически инициирует загрузку.
Некоторые backend-реализации поддерживают запись переводов:
create(languages, namespace, key, fallbackValue)
Сценарии применения:
Пример:
backend.create("ru", "translation", "new_key", "Значение по умолчанию");
Создание кастомного backend необходимо при нестандартных источниках данных.
class ApiBackend {
init(services, options) {
this.apiUrl = options.apiUrl;
}
read(language, namespace, callback) {
fetch(`${this.apiUrl}/${language}/${namespace}`)
.then(res => res.json())
.then(data => callback(null, data))
.catch(err => callback(err, null));
}
}
i18next
.use(ApiBackend)
.init({
backend: {
apiUrl: "https://api.example.com/locales"
}
});
Backend обязан корректно обрабатывать ситуации:
Типичная стратегия:
read(language, namespace, callback) {
try {
const data = loadFromSource();
callback(null, data);
} catch (e) {
callback(e, null);
}
}
i18next при ошибке может использовать:
Backend тесно связан с системой fallback-языков.
Пример конфигурации:
i18next.init({
fallbackLng: ["en", "de"],
});
При отсутствии перевода:
Backend участвует в каждом этапе загрузки.
В сложных приложениях backend может быть составным:
Такая архитектура реализуется через обёртки:
class CompositeBackend {
constructor(backends) {
this.backends = backends;
}
read(language, namespace, callback) {
// попытка последовательно из разных источников
}
}
Backend не занимается интерполяцией напрямую, но влияет на структуру данных, которая будет обработана i18next.
Пример:
{
"greeting": "Привет, {{name}}"
}
Backend возвращает строку, а подстановка выполняется позже в core-слое.
Backend всегда оперирует связкой:
Namespace позволяет:
Пример структуры:
locales/
ru/
auth.json
dashboard.json
Backend-плагины используются в различных типах приложений:
Каждый сценарий диктует выбор backend-стратегии:
Ключевые факторы производительности:
Оптимизация достигается через:
Backend может стать точкой уязвимости при неправильной конфигурации:
Типичные меры: