일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 |
- DDD
- 비동기
- sharedvalue
- 코드 푸시
- rniap
- 애그리게이트
- 이펙티브 타입스크립트
- ui thread
- Expo
- React Native
- 정처기 준비물
- 불변식
- HTML
- BOUNDED CONTEXT
- nextJS
- 빌딩 블록
- 정처기 자격
- rn
- js
- react natvie
- collapsibletabview
- IAP
- Aggregate
- in app purchase
- expo updates
- TS
- 속도개선
- 정보처리기사
- typeScript
- 타입스크립트
- Today
- Total
nika-blog
React-Native: CodePush에서 EAS Update로의 마이그레이션 본문
✨ 배경과 고민
작년부터 저희 팀에서는 기존 CodePush 대체제를 본격적으로 검토하기 시작했습니다. 기존 CodePush는 Microsoft App Center의 일환으로 안정적으로 활용되어 왔지만, 다음과 같은 이유로 대체제가 필요하다는 판단을 내렸습니다:
- Microsoft가 App Center CodePush의 장기적인 지원을 중단할 가능성을 명시함
- CodePush의 New Architecture 미지원 문제로 인해 React Native 0.76 이상에서는 호환성 문제가 발생
- 자체 유지보수를 고려한 self-hosting(code-push-server)은 관리 포인트가 많고 인프라 종속성이 높음
- metro 외의 번들러를 사용할 경우 CodePush와 충돌 가능성 존재
이러한 이유로 CodePush 유지 비용 및 리스크가 점점 커지고 있었고, 안정적인 OTA(Over-The-Air) 업데이트 체계를 유지하기 위한 대체제가 필요했습니다.
CodePush: Microsoft App Center의 일환으로 제공된 OTA 업데이트 서비스로, 앱 스토어 재심사 없이 JS 번들을 실시간으로 배포할 수 있는 방식
🔍 초반 대안 탐색: code-push-server vs Expo Updates vs EAS Update
code-push-server
당시 Microsoft에서 공개한 code-push-server 외에는 뚜렷한 대안이 없었으며, 비용 측면에서는 self-hosting 방식이 유리해 보였습니다. 실제로 S1 인스턴스 기준 $72.72/월, 스토리지 비용 $5/월로 총 $120 이하에서 운영 가능했습니다.
그러나 Azure 인프라를 별도로 유지보수해야 하고, react-native-code-push SDK 자체의 유지보수도 직접 떠안아야 했습니다. 특히 New Architecture 대응이 되지 않아 React Native 0.76 이상을 사용하려면 Stable Interop Layer 설정이 필요하며, metro가 아닌 번들러를 사용하는 경우 code-push-cli 자체를 수정해야 하는 위험 요소도 있었습니다.
Expo Updates vs EAS Update
항목 | Expo Updates | EAS Update |
배포 제어 | ❌ 없음 (전체 앱에 무조건 배포) | ✅ 있음 (채널, 버전별 배포 가능) |
버전 고정 | ❌ 불가능 | ✅ runtimeVersion으로 제어 가능 |
무료 여부 | ✅ 항상 무료 | ✅ On-demand 플랜 존재 (기본 무료, 과금은 MAU 및 bandwidth 기준) |
Dashboard | ❌ 없음 | ✅ 웹 기반 배포 관리 UI 제공 |
CI/CD 통합 | ❌ 수동 설정 필요 | ✅ eas-cli로 구성 용이 |
Expo Updates는 간단히 배포할 수 있다는 장점이 있으나, 특정 앱 버전에만 업데이트를 적용하는 것이 불가능하여 QA, 심사, 실사용 중인 여러 버전을 동시에 운용할 경우 문제가 발생할 수 있습니다.
반면 EAS Update는 runtimeVersion, channel, branch 등으로 버전 타겟팅 및 관리가 가능하며, 점진적 롤아웃, 롤백 등도 제공되어 중대 앱에 더 적합한 구조를 갖추고 있습니다.
EAS Update vs code-push-server
항목 | EAS | Update code-push-server |
가격 | 참고 기준 $1124/월 | $120/월 이하 (self-host 기준) |
유지보수 | Expo Enterprise SLA 제공 (99.9% uptime) | 더 이상 공식 지원 없음 (deprecated 명시) |
설치/관리 | SaaS 기반, 관리 부담 적음 | Azure 종속적, 셀프호스트 인프라 관리 필요 |
RN New Arch 대응 | 공식 지원 | 미지원 (0.76 이상은 수동 대응 필요) |
CI/CD 통합 | eas-cli로 쉽게 구성 가능 | codepush-cli 유지보수 필요 |
통합 결정: EAS Update 도입
최종적으로 저희팀은 EAS Update를 도입하기로 결정했고, 2025년 3월 10일 배포 버전부터 적용되었습니다.
검토 과정에서는 토스 개발자 분이 오픈한 hot-updater도 비교 대상으로 고려했지만, 아직 안정성과 문서화 측면에서 Expo만큼 신뢰할 수 있는 수준은 아니었고, 역시 관리 포인트가 증가한다는 점에서 선택지에서 제외되었습니다.
⚡️ EAS Update 도입 작업 내용
- 기존 react-native-code-push 관련 코드 제거
- Expo 모듈 통합 (expo-updates, expo-modules-autolinking, expo-constants 등)
- eas.json 및 app.config.js 작성, runtimeVersion 정책 설정 (우리는 nativeVersion 사용)
- CI 파이프라인을 code-push 기반에서 eas update CLI 기반으로 전환
- 채널(channel), 브랜치(branch) 정책 설정: 기존 번들 이름 정책(24.8.1.12)을 그대로 유지하면서 EAS의 update 이름에도 반영
- OTA 대상 build에는 runtimeVersion을 고정하여, 과거 build와 update 간 호환 문제 방지
현재 발생 사항과 이슈
도입 이후 일부 빌드 환경에서 이슈가 있었는데, 주로 Release 빌드 환경에서의 bundle mismatch 문제였습니다. Android에서만 발생했으며, index.android.bundle 내에 로컬 경로가 포함되거나 AppRegistry 등록 실패가 확인되었습니다. 주 원인은 dev → release 빌드 전환 시 metro cache, watchman 캐시가 꼬이는 현상으로 분석되었고, 아래 명령어로 해결했습니다:
watchman watch-del-all
rm -rf $TMPDIR/metro-cache
rm -rf node_modules && yarn
EAS 도입 이후 체크포인트
- 브라운필드 형태(순정 RN + Expo 모듈만 통합)에서의 Expo 적용은 쉽지 않으며, 일부 가이드대로 작동하지 않는 부분 존재
- Expo 버전 업데이트 시마다 통합 모듈 호환성 확인 필요 → 일정 공수 발생
- runtimeVersion 정책은 우리의 versioning 정책(major.minor.patch.hotfix)과 잘 맞았으며, OTA 업데이트의 정확한 버전 타겟팅에 유리함
- 기존 codepush보다 update 체계가 명확하고 roll-out, rollback 등의 고급 전략도 가능
EAS Update 활용 방식
현재 EAS Update를 기존 CodePush의 대체재로만 사용하지 않고, 정식 기능 배포 전 테스트 및 QA 환경에서의 OTA 업데이트 수단으로 적극 활용하고 있습니다. 예를 들어 다음과 같은 방식으로 운영 중입니다:
- staging 채널에 QA 대상 업데이트를 미리 배포하여 테스트 효율화
- 각 빌드마다 고유한 runtimeVersion을 설정하여 배포 대상 버전을 정확히 타겟팅
- CodePush 시절처럼 실시간 JS 핫픽스를 제공하기보다는, 출시 전 마무리 점검을 위한 보조 수단으로 활용
이를 통해 OTA 업데이트의 이점을 유지하면서도, 앱 릴리즈 전략은 앱 마켓 심사를 전제로 하는 안정적인 구조로 설계하고 있습니다.
또한 CodePush와 앱 빌드 방식의 장단점을 아래와 같이 비교하고 내부 운영 기준을 명확히 세우고 있습니다:
CodePush vs 앱 빌드 배포 비교
항목 | CodePush 기반 배포 | 앱 빌드 후 배포 (스토어 등록) |
업데이트 속도 | ✅ 매우 빠름 (OTA) | ❌ 심사 지연 있음 |
플랫폼 정책 준수 | ❌ 회피 가능성 있음 | ✅ 명시적 심사 통과 |
QA 및 기능 추적 | ❌ 번들 기준 추적 어려움 | ✅ 빌드 기준으로 추적 가능 |
네이티브 기능 대응 | ❌ 한계 있음 | ✅ 완전 대응 가능 |
유지보수 부담 | ✅ 낮음 (SaaS 사용 시) | ❌ 높은 편 (릴리즈 주기 관리 필요) |
이러한 운영 방식을 통해 우리는 안정성과 민첩성을 동시에 확보하고 있으며, EAS Update는 그 균형을 유지하기 위한 핵심 수단으로 작동하고 있습니다.
마무리
EAS Update 도입은 단순히 업데이트의 관리, 추적, 배포 전략을 체계화하려는 목적에서 출발했습니다. 가격은 기존 CodePush보다 높을 수 있지만(내부 테스터용으로만 사용한다면 무료 플랜도 고려 가능), 인프라 관리/유지보수/신뢰성/배포 전략 등의 총합을 고려하면, 합리적인 선택지라고 판단했습니다.
'React Native' 카테고리의 다른 글
React-Native: CollapsibleTabView Reanimated 기반 성능 최적화 (0) | 2025.05.06 |
---|---|
React Native에서 In-App Purchase 구현하기 (0) | 2025.02.06 |
RNIap subscription promotion, ios introductory offer (인앱 결제 이상한 ios 프로모션 정책) React Native (2) | 2025.01.31 |
global service - in app purchase(iap) currency issue, react-native (0) | 2025.01.11 |