Строгая конфигурация в FormatJS формирует набор правил, при которых система интернационализации перестаёт быть «гибкой по умолчанию» и начинает требовать явной дисциплины в описании сообщений, идентификаторов и структуры переводов. Основная цель — исключить неоднозначности между исходным кодом и файлами локализации, а также предотвратить ситуации, когда интерфейс частично работает на fallback-языке без явного контроля.
Строгий режим затрагивает сразу несколько уровней: статический анализ
(ESLint), компиляцию сообщений (Babel-плагин), извлечение переводов
(CLI-инструменты) и поведение runtime-библиотек
(react-intl, intl-messageformat).
В экосистеме FormatJS строгий режим опирается на три ключевых принципа:
Явные идентификаторы сообщений Каждое сообщение
должно иметь стабильный id, исключающий зависимость от
текста как ключа.
Полная формализация ICU-синтаксиса Сообщения должны соответствовать ICU Message Format без синтаксических неоднозначностей.
Запрет неявных fallback-сценариев Отсутствие перевода, некорректный формат или пропущенные поля рассматриваются как ошибка, а не как допустимое состояние.
Статический анализ через eslint-plugin-formatjs является
основным механизмом внедрения строгого режима на этапе разработки.
Правило formatjs/enforce-id требует наличия
id во всех вызовах форматирования сообщений.
import { defineMessages } from 'react-intl';
const messages = defineMessages({
welcome: {
id: 'app.home.welcome',
defaultMessage: 'Добро пожаловать'
}
});
В строгой конфигурации отсутствие id приводит к ошибке
линтинга, а не предупреждению.
Правило formatjs/no-raw-text предотвращает появление
текстовых строк вне системы интернационализации.
// Ошибка в строгом режиме
<div>Привет</div>
// Корректный вариант
import { FormattedMessage } from 'react-intl';
<div>
<FormattedMessage id="app.greeting" defaultMessage="Привет" />
</div>
Это правило устраняет риск появления неинтернационализированных фрагментов интерфейса.
Некорректный ICU-синтаксис может быть выявлен на этапе линтинга:
// Ошибка: некорректная ICU-конструкция
const msg = {
id: 'app.errors.count',
defaultMessage: 'Ошибок {count plural one {# ошибка} other {# ошибок}'
};
В строгом режиме такие ошибки блокируют сборку.
babel-plugin-formatjs отвечает за подготовку сообщений к
извлечению и оптимизации. В строгой конфигурации он используется не
только как трансформатор, но и как валидатор.
Позволяет стандартизировать генерацию идентификаторов:
{
"plugins": [
[
"formatjs",
{
"idInterpolationPattern": "[sha512:contenthash:base64:6]"
}
]
]
}
В строгих конфигурациях исключается ручное управление ID в пользу детерминированных шаблонов.
Некоторые сборки используют режим строгой проверки сообщений:
{
"plugins": [
[
"formatjs",
{
"ast": true,
"strict": true
}
]
]
}
В этом режиме любые некорректные ICU-выражения вызывают ошибку трансформации.
В строгих конфигурациях этот параметр часто отключается:
{
"preserveEmptyDefaultMessage": false
}
Это означает, что сообщения без defaultMessage считаются
неполными и не допускаются к извлечению.
@formatjs/cli используется для извлечения сообщений из
кода в JSON-файлы локализации. В строгом режиме он выполняет
дополнительную валидацию структуры сообщений.
formatjs extract "src/**/*.{ts,tsx,js}" --out-file messages.json --strict
Флаг --strict включает дополнительные проверки:
iddefaultMessageПри строгом извлечении CLI может сравнивать существующие файлы локализации:
На уровне исполнения строгий режим влияет на поведение
IntlProvider и функций форматирования.
В строгих конфигурациях отсутствующий перевод не заменяется тихим fallback:
<IntlProvider locale="ru" messages={{}}>
<App />
</IntlProvider>
При отсутствии ключа:
При форматировании сообщений выполняется проверка соответствия переданных значений шаблону:
intl.formatMessage(
{
id: 'app.cart.items',
defaultMessage: 'Товаров: {count}'
},
{ count: undefined }
);
В строгом режиме отсутствие count рассматривается как
ошибка выполнения, а не как подстановка пустого значения.
Строгая конфигурация часто требует единообразной стратегии ID.
Подход на основе хэшей:
app.header.title → a8f3c1
Преимущества:
Недостатки:
{
"id": "settings.profile.saveButton"
}
В строгом режиме допускается только структурированная иерархия, а не произвольные строки.
FormatJS использует ICU Message Format как основу интернационализации. В строгой конфигурации синтаксис проверяется на нескольких уровнях.
{
"defaultMessage": "Привет, {name}"
}
Ошибкой считается:
name при форматировании{
"defaultMessage": "{count, plural, one {# файл} few {# файла} other {# файлов}}"
}
Строгий режим требует:
countСтрогая конфигурация FormatJS чаще всего закрепляется на уровне пайплайна сборки.
- name: Extract messages
run: npx formatjs extract "src/**/*.{ts,tsx}" --strict
- name: Lint messages
run: npx eslint "src/**/*.{ts,tsx}" --rule 'formatjs/enforce-id:error'
При нарушении правил:
При увеличении количества языков строгая конфигурация становится механизмом защиты целостности переводов.
Основные эффекты:
Типичная строгая конфигурация объединяет ESLint, Babel и CLI:
{
"eslint": {
"rules": {
"formatjs/enforce-id": "error",
"formatjs/no-raw-text": "error"
}
},
"babel": {
"plugins": [
[
"formatjs",
{
"ast": true,
"idInterpolationPattern": "[sha512:contenthash:base64:6]",
"preserveEmptyDefaultMessage": false
}
]
]
},
"cli": {
"strict": true
}
}
Строгий режим переводит FormatJS из «инструмента поддержки локализации» в «контрактную систему».
При нарушениях:
Такая модель обеспечивает детерминированность интерфейсной локализации и предотвращает накопление скрытых ошибок в переводах.