Экосистема FormatJS опирается на строгий синтаксис ICU MessageFormat, поэтому первый уровень контроля связан с парсингом и валидацией строки сообщения до выполнения приложения.
Сообщение интерпретируется через AST-парсер
(@formatjs/icu-messageformat-parser), который выявляет
синтаксические ошибки:
plural и
selectnumber,
date, time, selectordinal)При обнаружении ошибки парсинга формируется структурированное исключение, содержащее позицию в строке и тип нарушения.
Типичный пример некорректного сообщения:
const msg = "У вас {count, plural, one {1 файл} other {# файлов}";
// отсутствует закрывающая скобка
Такое сообщение не проходит стадию компиляции и не может быть использовано в рантайме.
FormatJS строго связывает строку сообщения с набором входных параметров. На этапе компиляции или выполнения проверяется:
Пример несоответствия:
const message = "У пользователя {name} {age, number} лет";
formatMessage(message, {
name: "Алексей"
});
Отсутствие age приводит к ошибке или использованию
fallback-режима в зависимости от конфигурации.
В строгой конфигурации react-intl такие ошибки
обрабатываются как критические, поскольку нарушают целостность
локализационного контракта.
Одной из ключевых проблем интернационализации является неполнота переводов между локалями. FormatJS решает это через механизмы извлечения и сравнения сообщений.
Используется CLI-инструмент @formatjs/cli:
npx formatjs extract "src/**/*.{ts,tsx,js}" --out-file messages.json
Результатом является единый каталог сообщений:
{
"app.title": {
"defaultMessage": "Dashboard"
},
"user.greeting": {
"defaultMessage": "Hello, {name}"
}
}
Для каждой локали формируется отдельный файл переводов. Далее выполняется проверка:
Типичная структура проверки:
en.json -> источник истины
ru.json -> проверяемая локаль
de.json -> проверяемая локаль
При отсутствии ключа система фиксирует:
ICU MessageFormat требует соблюдения полноты ветвлений, особенно для
plural и select.
Пример:
"{count, plural, one {# файл} few {# файла} other {# файлов}}"
Для языков с более сложной системой множественных форм (например, славянские языки) отсутствие одной из форм приводит к некорректному отображению.
Валидация проверяет:
other ветки (обязательная по ICU)При несоответствии возникает ошибка компиляции или предупреждение зависимости от режима strictness.
FormatJS использует данные CLDR (Common Locale Data Repository) для определения правил форматирования чисел, дат и множественных форм.
Валидация включает:
Если локаль не зарегистрирована:
import { IntlProvider } fr om "react-intl";
<IntlProvider locale="ru">
и отсутствуют данные CLDR, возможны fallback-режимы или ошибки форматирования.
В react-intl проверки происходят во время
выполнения:
Пример отсутствующего сообщения:
formatMessage({ id: "missing.key" })
Результат зависит от конфигурации:
defaultMessageStrict mode усиливает контроль качества локализации. Включение режима приводит к:
Пример конфигурации:
<IntlProvider
locale="ru"
defaultLocale="en"
onEr ror={(err) => {
console.error(err);
}}
/>
В строгих настройках любые несоответствия трактуются как ошибки интеграции, а не как допустимые деградации интерфейса.
Статическая валидация усиливается через линтер.
Основные правила:
formatjs/no-missing-message-idformatjs/enforce-idformatjs/no-missing-pluralformatjs/no-invalid-icuПример конфигурации:
rules: {
"formatjs/enforce-id": "error",
"formatjs/no-missing-message-id": "error"
}
Линтер позволяет выявлять ошибки до этапа сборки, включая:
Система сообщений требует уникальности ключей в пределах проекта. При
использовании extract CLI или Babel-плагинов может
возникать ситуация:
idТипичный конфликт:
"user.title": "User"
"user.title": "Account"
Такие ситуации обнаруживаются на этапе агрегации сообщений и приводят к перезаписи или ошибке сборки в зависимости от конфигурации.
FormatJS опирается на Intl.NumberFormat,
Intl.DateTimeFormat,
Intl.RelativeTimeFormat.
Проверяются:
short, long,
numeric)Пример:
formatNumber(1000, {
style: "currency",
currency: "KZT"
});
Если валюта или формат не поддерживаются окружением, происходит fallback или ошибка в зависимости от polyfill-конфигурации.
Fallback-цепочки локалей контролируются через:
defaultLocaleПример цепочки:
ru-KZ → ru → en
Валидация фиксирует:
При использовании компилятора FormatJS сообщения преобразуются в оптимизированный формат.
На этапе компиляции проверяются:
Ошибки компиляции блокируют сборку локализационных ресурсов, предотвращая попадание некорректных сообщений в production-сборку.
FormatJS поддерживает rich-text синтаксис:
"Привет, <b>{name}</b>"
или ICU-style rich format:
{
b: (chunks) => <b>{chunks}</b>
}
Валидация контролирует:
Ошибки в rich-text приводят к потере структуры или падению форматирования в рантайме.
MessageDescriptor требует строгой структуры:
Валидация проверяет:
Любое отклонение фиксируется как нарушение контракта локализации.
Система ошибок FormatJS обычно классифицирует проблемы:
Каждая ошибка содержит:
Это позволяет строить централизованную систему мониторинга качества локализации в приложениях с большим количеством языков и сообщений.