이번에 참여하게 된 프로젝트에서 react native로 앱 개발을 하게 됐고, 이번 목표는 정식 출시다.
저번에도 react native로 앱 개발을 3개월 정도 했었고, 배포까진 이어지지 못했어서 아쉬움이 남았었지만, 이번에 다시 기회가 생겨서 제대로 개발해보려고 한다.
또한 이번에도 손쉬운 세팅을 위해 expo
를 사용하기로 했다. 이전에도 expo
를 사용했었는데 무작정 사용하고, 제대로 된 원리는 이해하지 못했었다.
그래서 이번에 앱을 세팅하며 내가 헷갈렸던 부분들, 지피티에게 물어보거나 구글링했던 부분들을 정리했다.
먼저 React
에 대해 짚고 넘어가야 React Native
에 대한 이해가 가능하다.
리액트는 인터페이스 구축을 위한 javascript 라이브러리이다.
react-dom
이라는 라이브러리가 웹 지원을 돕는다. react-dom
은 React 컴포넌트를 실제 DOM에 렌더링하는 역할을 한다. 즉, 실제 HTML 문서에 App 컴포넌트(최상위 컴포넌트)를 렌더링하는 역할을 한다.
앞서 살펴본 react-dom
의 대안이 React Native
이다.
웹에서는 렌더링을 react-dom
이 해줬다면,
앱에서 react-dom
의 역할을 react-native
가 맡게 되는 것이다.
사실 React
자체는 상태(state)를 관리하고 가상의 컴포넌트 트리를 구축하는 틀일뿐, 플랫폼에 상관없이 이용 가능하다. (=agnostic하다.) 이 트리를 렌더링하는 도구에 따라서 웹에서 사용될지, 앱에서 사용될지,.. 등이 결정되는 거다!
특히 React Native의 특징은 iOS/Android의 native한 UI 컴포넌트로 렌더링해준다. 그래서 각 모바일 OS에서 사용 가능한 앱 형태가 되는 거다.
*CLI: Command line Interface
Expo CLI
: 써드 파티/ 무료/ 편리/ 언제든지 Native CLI로 전환 가능
Expo Prebuild
가 추가되며 네이티브 코드를 생성할 수 있게 됨.Expo Go
앱을 통해 빠르게 테스트할 수 있지만, 모든 native module을 포함하고 있지 않다.React Native CLI
: react native가 만듦/ 기본적인 설정을 제공하나, 덜 편리하다.
이따가 자세히 서술하겠지만, 이 두 가지의 중간 지점이 Expo + EAS Prebuild
이다.
prebuild를 하게 되면 ios/
,android/
폴더가 생성되어 제한적이지만 네이티브 수정이 가능하다.
dev client를 만들기 위해서는 prebuild가 필요하다.
내가 React를 사용하여 만든 가상의 DOM을 ios, android에 대해 각각 네이티브한 코드를 만들어내는 과정이다.
즉, expo 프로젝트를 네이티브 프로젝트로 변환하는 거다. 이렇게 생성된 ios/
, android/
폴더를 빌드하고 실행하려면 Xcode나 android studio가 필요하다.
(그만큼 오래걸린다.)
eas build는 배포 목적
으로 클라우드에서 정식 빌드하는 거라고 생각하면 된다.
사실 prebuild하고 run하는 건 로컬 테스트용이다.
위에서 설명한 Expo Go
의 한계를 극복하기 위한 도구이다.
React Native + Expo 앱에서 native module을 사용하기 위해서는 꼭 필요한 환경이며, 쉽게 말해서 native module이 포함된 자신만의 Expo Go(실행 환경)을 만드는 것이라고 생각하면 된다.
Expo Go는 expo-camera
, expo-location
등 Expo에서 제공하는 표준 모듈만 내장되어 사용 가능하다. 따라서 네이티브 모듈을 사용한 코드를 테스트할 수가 없다.
이를 위해 네이티브 모듈이 포함된 개발 앱(dev client)를 빌드하여 실행하면 테스트가 가능하다.
app.config.js + expo prebuild
↓
ios/, android/ 폴더 생성
↓
expo-dev-client 설치
↓
네이티브 모듈 포함된 개발 앱 (dev client) 빌드됨
↓
npx expo run:android 또는 eas build로 실행
npx expo install expo-dev-client // dev client를 만들기 위한 패키지 설치
npx expo prebuild // 네이티브 코드 준비 (이때 비로소 ios, android 폴더 생성)
npx expo run // dev client 앱을 실행 (로컬 빌드)
시뮬레이터에서 실행하는 것: Expo Go 앱.
명령어: npx expo start
그래서 모듈이 Expo SDK로 제한적이다. 또한 수정할 때 JS 번들만 바뀌기 때문에 속도가 빠르다.
dev client를 빌드 후 실행하는 것: 내가 직접 빌드한 Dev Client 앱.
명령어: npx expo run:ios
, npx expo run:android
모듈은 네이티브 모듈까지 사용할 수 있다. 네이티브 모듈 변경시 앱을 다시 빌드해야 된다.
나도 처음에 공부할 때 그래야 하는 줄 알고 놀랐는데, 항상 방법은 있는 것 같다.
Dev Client를 초기에 한 번만 빌드해서 설치하고, 이후엔
expo start --dev-client
로 빠르게 개발하면 된다.
과정은 다음과 같다.
1. Dev Client를 한 번만 빌드해서 기기에 설치
npx eas build -p ios --profile development
npx expo start --dev-client
//혹은 그냥
npx expo start
위의 명령어를 사용하면 JS 번들 서버(Metro: 쉽게 말해 JS 번들을 제공)
이때에는 JS 코드만 hot reload된다.
하지만 네이티브 코드 변경이나 네이티브 모듈 추가 등이 발생하면 Dev Client 재빌드가 필요하다는 점은 알아둬야 한다.
JS 번들을 제공한다 == Expo/ React Native에서 JavaScript 코드를 하나의 실행 가능한 파일 (bundle) 로 압축하고, 이를 앱이 받아 실행할 수 있도록 한다는 것.
번들링 작업
1. 앱의 App.js
또는 index.js
에서 시작해서
2. 모든 import, require된 JS 모듈들을 재귀적으로 분석하고
3. 하나의 큰 Javascript 파일(bundle
)로 변환+압축
이렇게 번들이 완성되면, React Native 앱에는 JS interpreter(JSC/ Hermes)
가 내장되어 있어 이를 실행할 수 있다.
이때, expo start
명령어를 실행하면 로컬에서 JS 번들 서버를 열고, Dev client나 Expo Go 앱이 이 서버에 접속하여 번들을 다운로드해 실행한다. ( 💡 마치 웹사이트가 JS 파일을 서버에서 받아 실행하듯.,..)
명령어를 외워서 치기 이전에 원리를 이해해야 제대로 된 개발이 가능한 것 같다. 다시 한번 반성했다.
앞으로 험난하겠지만.. 파이팅 ㅎㅎ
다운로드했던 dev client 앱이 서버를 실행해도 검정색 화면만 떠서 재설치를 감행했다.
삭제 후 다시 빌드하고 실행해보니 무결성 에러
가 떴다 😇
이번에도 이전과 같이 xCode에서 애플 개발자 계정으로 로그인해주고 다시 빌드했음에도 계속 에러가 생겼다.
이전과 같이 애플 사이트에서 provisioning profile을 직접 주입해도 터미널에선 뜨지 않길래 다른 방법을 찾아보았다.
- 이미 존재하는 프로비저닝 프로파일에 내 기기(실제 기기)를 추가한다.
- 해당 프로비저닝 프로파일을 다운로드 후 더블클릭하면 자동으로 Xcode가 인식할 수 있는 디렉터리에 설치된다.
- xcode 실행 후 팀원의 애플 디벨로퍼 계정이 알맞게 들어가있고, 밑의 provisioning profile 드롭다운을 클릭하면 내 기기의 UDID가 뜨는 것을 확인한다.
- xcode에서 빌드 후 실행해본다.
이렇게 하고 npx expo start --dev-client
했을 때도 오류가 생겼다. xcode에서 에러 메시지를 확인할 수 있었는데 connection 문제가 생긴 것 같았다.
이를 위해 tunnel 옵션을 사용하여 연결하기로 했다.
기기가 localhost를 볼 수 없기 때문에 tunnel 옵션을 사용하면 안전한 HTTPS로 연결이 가능하다.
npx expo start --dev-client --tunnel
expo는 ngrok을 통해 HTTPS로 번들을 전달한다. 따라서 tunnel 옵션을 사용하기 위해 @expo/ngrok@^4.1.0
을 설치해줘야 했는데, expo-cli
는 이를 local dependecy로 기대하기 때문에 전역 설치하면 안되고 로컬 설치해줘야 한다.
npm install @expo/ngrok --save-dev
이렇게 실행하니 다시 되었다. 앱도 문제없이 깔렸고, 서버도 열었는데 앱 실행이 안되면(까만 화면만 뜨거나 로딩만 계속 되면) 이렇게 시도해보시길..