package.json (의존성 정의)
│
▼
[Babel] ← 트랜스파일러
최신 JS 문법 → 구형 런타임 호환 코드로 변환
│
▼
[Metro] ← 번들러
수백 개의 파일 → 하나의 번들(JS 파일)
│
▼
번들 (앱이 실제 실행하는 JS)
용어
핵심 설명
package.json
npm/yarn 의존성과 스크립트를 정의하는 파일. 라이브러리 버전 관리의 기준점
Babel
최신 JS 문법(ES2022+, JSX)을 구형 런타임에서도 돌아가게 변환하는 트랜스파일러
Metro
React Native 전용 번들러. JS 파일들을 하나로 묶어 앱에 전달
번들러
수백 개의 JS 파일을 하나(또는 몇 개)의 파일로 합치는 도구
번들
번들러가 만들어낸 결과물. 앱이 실제로 실행하는 JS 파일
4. 네이티브 코드
네이티브 코드 = CPU가 직접 실행하는 기계어(바이너리) 형태의 코드.
JS처럼 런타임이 해석하지 않고, 해당 기기의 CPU에 맞게 미리 컴파일된 코드.
JS vs 네이티브 코드
JS (React Native)
소스 → Metro 번들 → Hermes 엔진이 해석하며 실행
특징: 유연함, 핫리로드 가능, 상대적으로 느림
네이티브 코드 (C/C++)
소스 → NDK r28+ 크로스 컴파일 → CPU가 직접 실행
특징: 빠름, 플랫폼 종속, 카메라/센서 등 OS 직접 접근
네이티브 코드 관련 용어
용어
핵심 설명
네이티브 라이브러리
C/C++로 컴파일된 .so 파일. JS에서 직접 다루기 어려운 기능을 처리
.so 파일
Android의 네이티브 공유 라이브러리. Windows의 .dll과 같은 개념
JNI
Java/Kotlin에서 C/C++ 네이티브 코드를 호출하는 인터페이스
JSI
RN 새 아키텍처에서 JS가 네이티브를 직접 호출하는 방식. 브릿지 불필요
ABI
CPU 아키텍처마다 다른 바이너리 규약. arm64-v8a(기기), x86_64(에뮬레이터)
크로스 컴파일
PC(x86)에서 Android 기기(ARM)용 코드를 만드는 것. NDK가 담당
gRPC
C 기반 고성능 RPC 프레임워크. 네이티브 라이브러리 형태로 포함
.so 파일과 16KB page-size 문제
앱 A ─┐
앱 B ──┼──→ camera.so (공통 기능 파일)
앱 C ─┘
여러 앱이 같은 .so를 공유해 메모리/용량을 절약.
Android 15+에서 페이지(RAM 메모리 데이터 처리 단위) 크기가 4KB → 16KB로 바뀌면서,
4KB 정렬로 컴파일된 구형 .so 파일을 새 Android 기기가 거부하는 문제 발생.
해결: NDK r28+로 16KB 정렬 방식으로 재컴파일 필요.
네이티브 lib 추가 업그레이드 시 체크리스트
확인 항목
이유
NDK 버전 r28+
16KB page-size 지원
ABI 필터 설정
arm64-v8a 등 타겟 아키텍처 명시
16KB page-size 정렬
Android 15+ 호환성
의존 라이브러리 버전 체인
.so 하나 교체 시 연쇄 버전 충돌 가능
빌드 후 스모크 테스트
실제 기기에서 크래시 여부 확인
네이티브 코드가 필요한 상황
상황
이유
카메라, 블루투스, 센서
OS API를 직접 접근해야 함
암호화, 이미지 처리
성능이 중요한 연산
gRPC, SQLite
C 기반 라이브러리 재사용
16KB page-size 대응
.so 파일의 메모리 정렬 규칙
5. RN 아키텍처
구 아키텍처 (Paper) 새 아키텍처 (New Architecture)
JS JS
│ │
│ 비동기 브릿지 │ JSI (직접 호출)
│ (JSON 직렬화/역직렬화) │ (메모리 공유)
│ │
Native Native
느린 통신, 직렬화 비용 빠른 통신, 동기 호출 가능
용어
핵심 설명
Paper 아키텍처
RN 구버전 렌더링 시스템. JS ↔ 네이티브 간 비동기 브릿지 사용. JSON 직렬화 비용 발생
newArchitecture
RN 0.71+의 새 시스템. JSI로 브릿지 없이 직접 통신. reanimated 등이 이 방식을 활용
Flipper
Meta의 모바일 디버거. 네트워크/레이아웃/로그 시각화. RN 0.73+부터 기본 제거
ReactNativeFlipper
Android build.gradle에서 Flipper를 RN에 연결하는 설정 블록. 제거 시 관련 의존성도 함께 정리 필요
템플릿 드리프트
버전 업그레이드를 거치며 공식 템플릿과 실제 프로젝트 설정이 달라진 상태. 빌드 오류의 주요 원인
6. 주요 라이브러리
라이브러리
역할
주의사항
react-native-safe-area-context
노치/홈바 등 안전 영역 인식, UI가 가려지지 않게 처리
RN 버전에 따라 호환 버전 다름
screens
네이티브 수준의 화면 전환 성능 제공
RN/아키텍처 버전에 맞게 고정 필요
svg
벡터 이미지 렌더링
네이티브 모듈 포함, 버전 호환 주의
reanimated
고성능 애니메이션. 새 아키텍처에서 JS 스레드를 타지 않음
newArchitecture 활성화 여부에 따라 동작 방식 다름
image-picker
갤러리/카메라에서 사진 선택하는 네이티브 모듈
iOS/Android 권한 설정 필요
splash-screen
앱 시작 시 스플래시 이미지 표시
네이티브 설정 파일 수정 필요
safe-area, screens, svg 버전: RN 버전과 아키텍처(Paper/New)에 따라 호환되는 버전이 다름. package.json에서 버전을 고정하고, 업그레이드 시 반드시 호환표 확인.
7. 앱 스모크 테스트
빌드 완료 후 핵심 기능이 최소한 동작하는지 빠르게 확인하는 테스트.
스크립트 없이 실제 기기/에뮬레이터에서 수동으로 실행.
빌드 완료 (assembleDebug)
│
▼
adb install app-debug.apk
│
▼
앱 실행 → 크래시 없이 뜨는가?
│
├── 메인 화면 진입되는가?
├── 네트워크 요청 성공하는가?
└── 네이티브 기능(카메라 등) 오류 없는가?
네이티브 lib 추가/업그레이드 후에는 반드시 실제 기기에서 스모크 테스트 필요.
에뮬레이터는 x86_64 ABI를 쓰므로 arm64 관련 문제를 잡지 못할 수 있음.