Апгрейд стратегии

В экосистеме интернационализации ключевым фактором стабильности выступает предсказуемость поведения форматирования сообщений, дат, чисел и плюрализации. В рамках FormatJS апгрейд стратегии строятся вокруг сохранения совместимости ICU-сообщений, стабильности runtime API и контролируемого обновления инструментов экстракции сообщений.

Развитые проекты редко ограничиваются одной версией библиотеки. Обычно одновременно существуют несколько слоёв: runtime форматирования, build-time экстракция и слой интеграции с UI-фреймворками, например React Intl. Каждый слой требует собственной стратегии миграции, поскольку изменения в одном уровне могут неявно влиять на другие.


Семантика версий и природа breaking changes

Апгрейд FormatJS подчиняется семантике, в которой критическими считаются изменения в следующих областях:

  • ICU Message Format parsing
  • поведение plural rules
  • fallback локалей
  • форматирование дат через Intl API
  • поведение default locale resolution

Даже минимальные изменения в этих слоях способны привести к изменению отображаемого текста без изменения исходных данных. Это делает обновления чувствительными, а стратегии миграции — строго регламентированными.

Особое значение имеет совместимость сообщений ICU. Сообщения вида:

{count, plural, one {# item} other {# items}}

должны сохранять идентичную семантику при переходе между версиями. Любое изменение интерпретации plural rules фактически эквивалентно изменению бизнес-логики.


Стратегии миграции зависимостей FormatJS

Lockstep upgrade

Lockstep стратегия предполагает одновременное обновление всех пакетов экосистемы FormatJS:

  • runtime библиотеки
  • babel-плагинов
  • CLI инструментов экстракции
  • интеграций с React слоями

Такая модель минимизирует риск несовместимости, но увеличивает стоимость релиза. Основное преимущество заключается в том, что отсутствует состояние частичной несовместимости между версиями message compiler и runtime parser.


Incremental upgrade

Инкрементальная стратегия строится на последовательном обновлении компонентов:

  1. сначала обновляется CLI экстракции сообщений
  2. затем runtime библиотека
  3. затем UI-интеграция (например, React Intl)
  4. затем обновляются polyfill-слои Intl

Ключевой риск — временная рассинхронизация между форматом сообщений и runtime интерпретацией. Для его минимизации используются backward-compatible AST-форматы и расширенная телеметрия ошибок парсинга ICU.


Dual runtime strategy

Dual runtime модель предполагает параллельное существование двух версий FormatJS:

  • legacy runtime обрабатывает старые сообщения
  • new runtime обрабатывает новые сообщения

Переключение между ними происходит через feature flags или runtime detection версии message catalog. Такой подход используется в системах, где невозможно одновременно обновить все клиентские приложения (например, при большом количестве web-версионных артефактов или мобильных webviews).


Совместимость ICU сообщений

ICU Message Format является ядром системы форматирования. При апгрейде критично учитывать:

  • изменения в plural rules для отдельных локалей
  • расширение синтаксиса select expressions
  • поведение вложенных сообщений
  • escape-последовательности

Например, изменение интерпретации вложенных plural-конструкций может привести к различиям в строках без изменения исходного JSON каталога сообщений.

Стабильность ICU-совместимости достигается через:

  • фиксацию версии parser-а сообщений
  • snapshot-тестирование локализованных строк
  • диффы финального formatted output

Изменения в pipeline экстракции сообщений

В FormatJS значительная часть логики перенесена в build-time слой. Апгрейд CLI и babel-плагинов влияет на:

  • структуру AST извлекаемых сообщений
  • порядок ключей в message catalog
  • обработку defaultMessage fallback
  • генерацию id сообщений

Изменения в pipeline часто приводят к неявным регрессиям, особенно при использовании автоматической генерации id.

Типовой риск — изменение deterministic hashing алгоритма, что приводит к изменению message IDs и, как следствие, к потере переводов без явного предупреждения.


Babel plugin и трансформации кода

Babel-плагины в экосистеме FormatJS отвечают за:

  • извлечение строк
  • нормализацию ICU синтаксиса
  • генерацию metadata для переводов

При апгрейде важно учитывать:

  • изменение visitor-логики AST
  • новые правила нормализации whitespace
  • изменение обработки template literals
  • поддержку новых ECMAScript синтаксических конструкций

Особое значение имеет совместимость с современными версиями Babel, поскольку устаревшие версии могут некорректно передавать AST структуру, влияя на финальные message descriptors.


Стратегии управления polyfill Intl

Хотя современные среды предоставляют встроенный Intl, экосистема FormatJS исторически включает polyfill-слой.

При апгрейде учитываются:

  • различия между браузерными реализациями Intl
  • поведение fallback для старых окружений
  • синхронизация версий CLDR данных

Стратегии:

  • externalized polyfill: загрузка отдельно от runtime
  • bundled polyfill: включение в сборку
  • conditional polyfill: загрузка по feature detection

Критическая проблема заключается в несоответствии CLDR данных между версиями, что может изменять формат чисел и дат даже при одинаковом исходном коде.


Feature flags как инструмент миграции

Feature flags применяются для поэтапного включения новых возможностей runtime FormatJS:

  • новый parser ICU сообщений
  • новая логика fallback локалей
  • альтернативный формат message catalog
  • экспериментальные правила pluralization

Использование feature flags позволяет поддерживать A/B сравнение результатов форматирования и выявлять расхождения до полного переключения системы.


Стратегия тестирования при обновлениях

Тестирование в контексте i18n апгрейдов должно учитывать не только функциональную корректность, но и стабильность визуального вывода.

Основные подходы:

  • snapshot-тесты локализованных строк
  • golden files для ключевых локалей
  • диффы formatted output между версиями
  • property-based тестирование ICU сообщений

Особое внимание уделяется регрессионным сценариям, где изменение версии FormatJS может изменить форматирование без изменения входных данных.


Rollback стратегия и контроль деградаций

Rollback в системах интернационализации сложнее, чем в типичных runtime библиотеках, поскольку изменения могут затрагивать уже сгенерированные каталоги сообщений.

Стратегия отката включает:

  • хранение версий message catalog
  • сохранение совместимых AST snapshots
  • возможность переключения runtime версии без пересборки
  • изоляцию CLDR данных по версиям

При использовании dual runtime подхода rollback часто сводится к переключению feature flag, однако при lockstep обновлениях требуется откат всего стека FormatJS.


Контроль расхождений между средами

Одной из наиболее сложных проблем является различие между средами выполнения:

  • браузерные реализации Intl
  • Node.js runtime
  • серверный SSR слой
  • edge runtime окружения

Даже при идентичной версии FormatJS поведение форматирования может различаться из-за различий в ICU data и системных локалях. Для контроля вводится слой нормализации и унификации форматтеров, который фиксирует поведение независимо от среды исполнения.