Библиотека Validator.js изначально проектировалась как набор чистых функций валидации без жёсткой привязки к языку сообщений. Такой подход позволяет отделить логику проверки данных от представления ошибок, что критически важно для интернационализируемых приложений.
Локализация в данном контексте не является встроенным механизмом ядра библиотеки, а реализуется через внешние слои — обёртки, словари сообщений и интеграцию с системами i18n. Это делает Validator.js гибким инструментом, который может адаптироваться под любые языковые среды без изменения исходного кода валидации.
Ключевая идея заключается в том, что каждая функция валидации
возвращает либо true, либо false, либо
строку-идентификатор ошибки, которая затем интерпретируется системой
локализации.
Validator.js не навязывает формат сообщений об ошибках. В простейшем виде результат проверки выглядит так:
true — значение корректноfalse — значение не прошло проверкуТакой подход позволяет вынести текстовые сообщения в отдельные структуры:
const messages = {
en: {
required: "This field is required",
email: "Invalid email format"
},
ru: {
required: "Поле обязательно для заполнения",
email: "Некорректный формат email"
}
};
Валидационная функция при этом возвращает ключ:
function validateEmail(value) {
return /\S+@\S+\.\S+/.test(value) ? true : "email";
}
На практике Validator.js часто используется вместе с функциями-обёртками, которые сопоставляют результаты проверки с конкретной локалью.
Пример базового механизма:
function localizeValidator(validator, locale = "en") {
return function(value) {
const result = validator(value);
if (result === true) return true;
return messages[locale][result] || "Unknown error";
};
}
Такой подход позволяет динамически переключать язык без изменения логики валидации.
При масштабировании приложения обычно используется централизованное хранилище локалей. Оно может быть реализовано как модуль или подключено через внешнюю систему интернационализации.
Структура локалей обычно организуется следующим образом:
locales/
en.json
ru.json
kz.json
Каждый файл содержит плоскую или иерархическую структуру сообщений:
{
"required": "Поле обязательно",
"email": "Некорректный email",
"minLength": "Слишком короткое значение"
}
Validator.js в таком случае выступает только как генератор кодов ошибок, а не как источник текстов.
Одним из ключевых аспектов локализации является возможность изменения языка в рантайме. Это особенно важно для SPA-приложений.
Пример реализации:
let currentLocale = "en";
function setLocale(locale) {
currentLocale = locale;
}
function translate(key) {
return messages[currentLocale][key] || key;
}
В связке с Validator.js это позволяет мгновенно переключать язык интерфейса без повторной инициализации валидаторов.
Некоторые расширенные версии Validator.js или его обёртки включают предопределённые правила: email, URL, IP-адрес, длина строки и другие. Для них также требуется локализация.
Пример типовой структуры:
const validators = {
email: (value) => /\S+@\S+\.\S+/.test(value) || "email",
required: (value) => value !== undefined && value !== null && value !== "" || "required",
minLength: (value, len) => value.length >= len || "minLength"
};
Далее слой локализации интерпретирует ключи:
const messages = {
ru: {
minLength: "Минимальная длина не соблюдена"
}
};
Сложные правила требуют передачи параметров в сообщения. Validator.js не ограничивает формат, поэтому часто используются шаблоны.
Пример:
const messages = {
ru: {
minLength: (len) => `Минимальная длина: ${len} символов`
}
};
Использование:
function validateMinLength(value, len) {
return value.length >= len ? true : { key: "minLength", params: { len } };
}
Обработчик локализации:
function resolveError(error) {
if (typeof error === "string") {
return translate(error);
}
if (typeof error === "object") {
return messages[currentLocale][error.key](error.params.len);
}
}
Validator.js часто используется совместно с системами интернационализации уровня приложения:
В таких случаях Validator.js полностью делегирует работу с текстами внешнему слою.
Типовая интеграция:
import i18n from "i18next";
function validateRequired(value) {
return value ? true : "required";
}
function translateError(key) {
return i18n.t(`validation.${key}`);
}
При большом количестве полей формы и частых переключениях языков возникает необходимость оптимизации. Распространённый подход — кэширование уже переведённых сообщений.
const cache = new Map();
function translateCached(key, locale) {
const cacheKey = `${locale}:${key}`;
if (cache.has(cacheKey)) {
return cache.get(cacheKey);
}
const result = messages[locale][key];
cache.set(cacheKey, result);
return result;
}
В сложных формах одно поле может возвращать несколько ошибок одновременно. В таком случае локализация должна учитывать порядок приоритета и группировку сообщений.
function validatePassword(value) {
const errors = [];
if (value.length < 8) errors.push("minLength");
if (!/[A-Z]/.test(value)) errors.push("uppercase");
return errors.length ? errors : true;
}
Локализация:
function translateErrors(errors) {
return errors.map(e => translate(e));
}
При росте приложения возникает необходимость поддержки дополнительных языков без изменения логики валидаторов. Используются следующие подходы:
Такая архитектура позволяет масштабировать Validator.js без модификации ядра.
При поддержке языков с направлением письма справа налево локализация затрагивает не только текст ошибок, но и представление форм. Validator.js не занимается UI, но передаёт корректные данные для адаптации интерфейса:
Это позволяет интеграционному слою корректно перестраивать визуальное отображение.
В корпоративных системах Validator.js часто используется в связке с доменными правилами, где локализация выходит за рамки простого перевода:
Пример: формат номера телефона может проверяться одинаково, но сообщение для пользователя будет различаться в зависимости от региона.
const messages = {
ru: {
phone: "Неверный формат номера телефона РФ"
},
en: {
phone: "Invalid phone number format"
}
};