Первый и главный шаг для архитектора — переоценка требований и контекста. Зачем мигрировать? Причины могут быть разными: выход CodePush из активной поддержки в определенных конфигурациях, потребность в большей кастомизации пайплайна, переход на другую облачную платформу (с AWS Amplify или Firebase App Distribution), ужесточение требований Apple и Google к OTA-обновлениям (особенно касающихся изменений в нативной части или основных функциональных возможностях), или просто соображения стоимости. Четкое понимание драйверов миграции определит выбор целевой платформы и стратегию.
Выбор целевой технологии — это архитектурное решение. Вариантов несколько:
- **App Center Distribute (новый)**. Если вы уже в экосистеме Microsoft Azure, это естественный путь. Distribute фокусируется на распространении сборок, но для OTA-обновлений JS-кода потребуется комбинация с сервисами сборки. Нужно оценить совместимость API и workflow.
- **Expo Updates**. Для проектов, использующих Expo (или Bare workflow), Expo Updates — это встроенное, хорошо интегрированное решение. Миграция с CodePush на Expo Updates относительно гладкая, если приложение уже на Expo. Для чистого React Native это не вариант.
- **Кастомное решение на своем бэкенде**. Наиболее гибкий, но и самый ресурсоемкий путь. Архитектор должен спроектировать серверную часть для хранения и распространения обновлений (часто на S3/CDN), клиентский SDK для проверки и применения обновлений, механизм контроля версий, отката и A/B-тестирования. Это оправдано для крупных проектов с уникальными требованиями.
- **Сторонние альтернативы**. Существуют платформы вроде BugSnag (с функциями деплоя), или сервисы, специфичные для OTA.
**Фаза 1: Анализ и подготовка (параллельная работа).**
Проведите полный аудит текущего использования CodePush. Какие приложения (iOS/Android), какие среды (Staging, Production), как устроен пайплайн деплоя? Документируйте все вызовы API CodePush, конфигурации (`appCenter-config.json`), логику проверки обновлений в коде. Создайте подробную карту зависимостей. Одновременно настройте новое целевое окружение (например, проект в App Center или инфраструктуру под кастомное решение) в *параллельном* режиме. Оно должно работать, но не использоваться в продакшене.
**Фаза 2: Реализация двойного режима (Dual-Runtime).**
Это ключевая фаза для минимизации риска. Модифицируйте клиентское приложение так, чтобы оно могло работать с *обоими* системами обновлений — старой (CodePush) и новой. Реализуйте абстракционный слой (Adapter Pattern) для менеджера обновлений. В рантайме, на основе конфигурации (например, флага удаленного конфига или версии приложения), приложение решает, какую систему использовать для проверки обновлений. Это позволяет начать развертывать обновления через новую систему в тестовой среде или для небольшой группы бета-тестеров, в то время как основная масса пользователей продолжает получать обновления через старую, проверенную систему.
**Фаза 3: Поэтапный перенос и тестирование.**
Начните деплоить некритичные обновления (например, исправление текстов или мелкие стилистические правки) через новую систему для все увеличивающегося процента пользователей (канареечные деплои). Тщательно мониторьте метрики: процент успешных установок, ошибки, откаты, производительность приложения после обновления. Используйте инструменты аналитики и краш-репортинга (App Center, Firebase Crashlytics). Особое внимание уделите сценариям отката (rollback) в новой системе — они должны работать безупречно.
**Фаза 4: Отключение старой системы и финализация.**
После нескольких успешных циклов обновлений через новую систему и достижения уверенности в ее стабильности, можно отключить старый механизм CodePush. Измените конфигурацию по умолчанию в приложении на использование новой системы. Важно: *не удаляйте* старый код сразу. Оставьте его на несколько циклов обновлений, защищенным флагом, на случай критической необходимости быстрого отката. После подтверждения стабильности можно рефакторить код, удаляя адаптер и старые зависимости от CodePush.
На протяжении всего процесса архитектор должен учитывать **критические риски**: согласованность версий нативного кода и OTA-обновлений (чтобы обновление JS не требовало новых нативных модулей, которых нет у пользователя), безопасность (подписывание обновлений, использование HTTPS), сетевую устойчивость (повторные попытки, работа в оффлайне). Также важен план коммуникации с командой разработки и DevOps, для которых изменится процесс сборки и деплоя.
Миграция CodePush — это не просто технический debt, это возможность переосмыслить и улучшить весь процесс доставки обновлений. Правильно спланированная миграция, основанная на инкрементальной, безопасной стратегии с двойным режимом работы, превращает потенциально болезненный процесс в управляемое эволюционное улучшение архитектуры вашего мобильного приложения.
Комментарии (8)