Современная экосистема локализации в JavaScript редко ограничивается ручной работой с текстами и форматами. Библиотека FormatJS формирует подход, в котором значительная часть процессов интернационализации переводится в автоматический конвейер: извлечение сообщений, синхронизация переводов, проверка целостности ключей, генерация артефактов и интеграция в сборку приложения.
Автоматизация в контексте FormatJS строится вокруг нескольких взаимосвязанных слоёв: статический анализ кода, работа с CLI-инструментами, форматирование ICU-сообщений и интеграция с системой сборки. Каждый слой выполняет строго определённую роль и может быть встроен в CI/CD пайплайн.
Основой автоматизации выступает процесс извлечения локализуемых
строк. FormatJS использует парсер AST для анализа JavaScript и
TypeScript-кода, выделяя конструкции defineMessages,
intl.formatMessage и аналогичные вызовы.
Типовой сценарий основан на CLI-инструменте
formatjs extract, который просматривает исходный код и
формирует JSON-файл сообщений.
Пример команды:
formatjs extract "src/**/*.{ts,tsx,js}" --out-file messages.json
На этом этапе происходит:
Результатом становится файл, пригодный для дальнейшей синхронизации с переводческими системами.
После извлечения сообщений важным этапом становится их унификация. FormatJS требует строгой структуры:
{
"app.title": {
"defaultMessage": "Dashboard",
"description": "Main page title"
}
}
Автоматизация включает:
ICU Message Format является центральной частью системы и требует строгого соблюдения синтаксиса:
Hello, {name}
You have {count, plural, one {1 message} other {# messages}}
Ошибки в синтаксисе выявляются автоматически при валидации через CLI или плагины сборщика.
После извлечения и распределения сообщений между языковыми файлами выполняется этап проверки целостности.
Автоматические проверки включают:
Пример структуры локали:
{
"app.title": "Панель управления",
"app.messages": "У вас {count, plural, one {# сообщение} few {# сообщения} many {# сообщений}}"
}
При автоматической валидации система сравнивает базовую локаль (обычно en) с целевыми переводами и выявляет расхождения.
Автоматизация в FormatJS тесно связана с инструментами сборки: Webpack, Vite, Rollup.
В Webpack используется babel-plugin-react-intl, который
трансформирует сообщения на этапе транспиляции.
Пример конфигурации:
module.exports = {
plugins: [
[
"react-intl",
{
messagesDir: "./build/messages"
}
]
]
};
На этапе сборки происходит:
В результате приложение получает оптимизированный набор переводов без избыточных данных.
FormatJS поддерживает строгую типизацию сообщений через ICU Message Syntax. Автоматизация включает форматирование и проверку сложных выражений:
Пример автоматической нормализации:
Исходный вариант:
You have {count} messages
После автоматизации:
You have {count, plural, one {# message} other {# messages}}
Такая трансформация может выполняться через кастомные скрипты или линтеры, встроенные в CI.
В крупных проектах локализация редко хранится в репозитории вручную. FormatJS позволяет интегрировать автоматическую синхронизацию с внешними системами управления переводами.
Поддерживаемые сценарии:
Типовой pipeline:
extract сообщенийcompile и валидацияАвтоматизация устраняет необходимость ручного обновления локалей.
После обработки переводов формируются runtime-файлы, используемые приложением. FormatJS поддерживает компиляцию сообщений в оптимизированный формат.
Пример результата:
export const messages = {
"app.title": "Dashboard",
"app.messages": [
{
type: "plural",
value: {
one: "# message",
other: "# messages"
}
}
]
};
Автоматизация включает:
Отдельный слой автоматизации отвечает за семантическую целостность переводов.
Проверяются:
Пример ошибки, выявляемой автоматически:
en: {count, plural, one {...} other {...}}
ru: {count, plural, one {...}}
Такая несогласованность блокируется на этапе CI.
FormatJS опирается на стандарты Intl, которые позволяют
унифицировать форматирование без ручной настройки.
Пример автоматического форматирования:
intl.formatDate(date, {
year: "numeric",
month: "long",
day: "2-digit"
});
Автоматизация обеспечивает:
Для чисел и валют используется аналогичный механизм:
intl.formatNumber(1000, {
style: "currency",
currency: "USD"
});
В современных проектах FormatJS интегрируется в pipeline непрерывной интеграции.
Типичный набор шагов:
Пример GitHub Actions шага:
- name: Extract messages
run: npm run intl:extract
- name: Validate translations
run: npm run intl:validate
Автоматизация позволяет блокировать сборку при нарушении структуры переводов.
В больших системах переводческие файлы рассматриваются как часть версии приложения. FormatJS-подход допускает автоматическое отслеживание изменений сообщений.
Механизм включает:
Пример состояния:
{
"app.title": {
"defaultMessage": "Dashboard",
"status": "changed"
}
}
Автоматизация часто расширяется генерацией типов, чтобы исключить ошибки использования сообщений.
Пример генерируемого интерфейса:
export interface IntlMessages {
"app.title": string;
"app.messages": string;
}
Это позволяет:
Автоматизация включает удаление неиспользуемых сообщений. Процесс tree-shaking локализации:
formatMessageРезультат — уменьшение размера финального бандла без изменения логики приложения.
FormatJS поддерживает fallback-цепочки локалей. Автоматизация определяет:
Пример:
ru-RU → ru → en
При отсутствии перевода система автоматически использует следующий уровень цепочки.
В процессе автоматизации добавляется слой телеметрии:
Пример диагностического события:
Missing translation: "app.header.title" (locale: ru)
Такая информация может быть собрана в централизованной системе мониторинга.
При микрофронтенд-архитектуре каждый модуль может иметь собственные локализации. FormatJS позволяет автоматизировать их объединение:
Это позволяет поддерживать независимость модулей при общей системе переводов.