create-react-native-app (crna) 사용하기

들어가며

회사에서 약 6개월간 React Native를 이용한 게임 앱(eyePoker - 화상채팅과 함께하는 포커게임) 개발을 마무리하였습니다. 후에 React Native를 사용해 새로운 앱을 개발할때 사용할 수 있도록 그간 React Native로 개발하면서 익힌 것들을 boilerplate로 만들려고 했습니다.

약 6개월전 처음 React Native를 접했을때 당시 v0.39 였으나 최근 확인해보니 stable 버전이 v0.46 까지 나와있었습니다. v0.46을 이용해 React Native 프로젝트를 생성하고자 하니 **Create React Native App**이 추가되어 있었습니다. (앞으로 Create React Native App을 **CRNA**라고 부르겠습니다.)

CRNA는 기존의 React Native CLI를 이용하지 않고 프로젝트를 생성하는 방법입니다. 지금부터 CRNA에 대해 알아보고 기존의 React Native CLI를 사용해서 프로젝트를 생성할때와 어떤 다른점이 있는지 알아보도록 하겠습니다.

create-react-native-app (crna)란?

먼저 아래의 영상을 통해 CRNA를 통해 프로젝트를 생성하고 실행하는 과정을 볼 수 있습니다. 약 6분정도의 짧은 영상입니다. 간단하게 한번 보시면 뒤의 내용을 좀 더 쉽게 이해할 수 있습니다.

React Native Document에서도 확인할 수 있듯이, CRNA는 React Native 프로젝트를 시작하기 훨씬 쉽게 해주는 도구입니다. React를 접해보신분은 한번쯤 들어보셨을 React Create App에서 영감을 받은 것이고, Expo라는 회사와 협업을 통해 만들어진 결과물 입니다.

Android나 iOS를 개발해본 경험 없이 React Native를 통해 앱 개발을 시작함에 있어서 네이티브 빌드에 필요한 도구를 설치하고 환경을 구성하는 것은 쉽지 않은 작업 입니다. 그러나 CRNA를 사용하면 Xcode 또는 Android Studio가 필요없으며 Linux 또는 Windows를 사용하여 iOS 장치 용으로도 개발할 수 있습니다. (이제 Mac이 필수가 아닙니다…)

CRNA는 네이티브 코드를 컴파일하지 않고 순수 JavaScript로 작성된 CRNA 프로젝트를 로드하고 Expo 앱을 사용하여 실행합니다. 그렇기 때문에 CRNA를 사용해 프로젝트를 생성할 경우 기존 CLI를 사용해서 생성한 결과물과는 다르게 프로젝트 폴더에 android와 ios 폴더가 없습니다.

그러나 아직 대부분의 React Native 라이브러리들을 사용하기 위해서는 android와 ios 폴더 아래 있는 네이티브 프로젝트 파일(Java, Objective-C, Swift)을 직접 수정하고 컴파일 해야하는 하는데 이러한 경우는 어떻게 할까요?

먼저, Expo는 이러한 경우를 대비해 카메라, 비디오, 연락처등 자주 사용되는 인기있는 라이브러리들을 번들로 제공하고 있습니다. 그렇기 때문에 대부분의 간단한 앱들은 따로 외부 라이브러리를 추가하지 않아도 만들 수 있습니다. 그러나 번들로 제공되지 않는 기능이 필요해 라이브러리를 추가해야하는 경우, 네이티브 코드 추가 및 빌드가 필요하기 때문에 CRNA를 사용해 생성한 프로젝트를 그대로 사용할 수가 없습니다. 이러한 경우를 대비해 Create React App에서 제공하는것과 마찬가지로 CRNA에서도 ejecting 기능을 제공하고 있습니다.

npm run eject 명령어를 통해 CLI를 통해 프로젝트를 생성한 것과 유사한 프로젝트를 얻을 수 있습니다. android와 ios 프로젝트 폴더가 생성됩니다. 그렇기 때문에 네이티브 빌드를 하기 위해서는 Xcode 또는 Android Studio가 필요합니다.

CRNA 프로젝트 생성

저는 nvm을 통해서 node v8.1.4, npm v4.6.1을 사용하고 있습니다. (npm은 v5.x대의 경우 에러가 발생하기 때문에 v4.x로 재설치를 하고 진행하셔야 합니다.)

이제 CRNA를 사용해서 프로젝트를 생성해보겠습니다.

1
2
3
4
$ npm i -g create-react-native-app
$ create-react-native-app crna-project
$ cd crna-project
$ npm install

**CRNA**를 사용해 프로젝트를 생성한 결과 구조는 다음과 같습니다.

1
2
3
4
5
6
7
8
crna-project
├── App.js
├── App.test.js
├── app.json
├── node_modules/
├── package.json
├── yarn.lock
└── README.md

참고) **CLI**를 생성해 프로젝트를 생성한 결과는 다음과 같습니다.

1
2
3
4
5
6
7
8
9
10
11
cli-project
├── index.android.js
├── index.ios.js
├── android/
├── ios/
├── node_modules/
├── __tests__/
├── app.json
├── package-lock.json
├── package.json
└── yarn.lock

기존 CLI를 사용했을때와 다르게 index.android.js와 index.ios.js는 App.js로 변경되었으며, 네이티브 빌드에 사용되는 android, ios 폴더는 사라졌습니다. 또한 app.json 파일은 그대로 존재하지만 파일 내용에는 차이가 있습니다.

**CRNA**를 사용해 생성한 프로젝트의 app.json

1
2
3
4
5
{
"expo": {
"sdkVersion": "18.0.0"
}
}

**CLI**를 사용해 생성한 프로젝트의 app.json

1
2
3
4
{
"name": "cli-project",
"displayName": "cli-project"
}

CRNA를 사용해 생성한 프로젝트의 app.json은 expo의 sdkVersion을 표시하고 있습니다.

CRNA 프로젝트 실행 - 1 (With 모바일 Expo 앱)

이제 생성한 CRNA 프로젝트를 실행해 보겠습니다. 기존 CLI를 통해 프로젝트를 생성했을 때는 실행을 위해 Android SDK와 Xcode가 필요하였고 다음의 명령어로 네이티브 빌드를 하여 실행했습니다.

1
2
$ react-native run-android
$ react-native run-ios

그러나 CRNA를 사용해 생성한 프로젝트는 다음의 명령어로 실행합니다. 명령어를 실행하면 다음과 같은 QR코드가 출력됩니다.

1
$ npm start

crna 프로젝트를 실행한 결과

QR코드가 출력되어 당황할 수 있지만 이 QR코드를 통해서 방금 생성한 프로젝트를 실행할 수 있습니다. 처음에 말씀드렸다시피 CRNA는 네이티브 코드를 컴파일하지 않고 순수 JavaScript로 작성된 CRNA 프로젝트를 로드하고 Expo 앱을 사용하여 실행한다고 했습니다. 그렇기 때문에 저희가 실행 결과를 확인하기 위해서는 Expo 앱을 추가로 설치해야합니다.

Expo앱은 JavaScript를 작성하여 기본 iOS 및 Android 앱을 제작할 수있게 해주는 도구, 라이브러리 및 서비스 세트이며 Expo앱 다운로드를 통해서 다운로드 후 설치 합니다.

다운로드 후 Expo앱을 실행하고 QR코드를 입력하면 다음과 같이 앱이 실행됩니다.

Expo 앱을 통한 CRNA 프로젝트 실행 - 1
Expo 앱을 통한 CRNA 프로젝트 실행 - 2

CLI를 통해 생성한 프로젝트를 실행하여 가상머신을 통해 결과를 확인했을 때와 같이 동일한 결과를 얻을 수 있습니다.

CRNA 프로젝트 실행 - 2 (With 데스크탑 Expo Tool (Expo XDE))

조금 전에는 Expo 앱과 CRNA를 실행한 후 QR코드를 통해 자신의 모바일에서 결과를 확인했습니다. 이번에는 모바일 앱이 아닌 Expo XDE를 설치한 후 가상머신을 통해 실행해 보도록 하겠습니다. Expo XDE를 실행한 후 조금전 생성한 CRNA 프로젝트를 로드합니다.
(Expo XDE를 설치하면서 에러가 발생하시는 분은 Expo Installation을 참고해서 Expo XDE에 필요한 다른 도구들을 설치해야합니다.)

Expo XDE로 CRNA 프로젝트 로드

프로젝트가 로드되면 우측 상단의 Share 버튼을 통해 조금전 npm start에서 제공했던것과 동일하게 QR코드를 제공받아 모바일 Expo 앱에서 프로젝트를 실행할 수 있고, Device 버튼은 현재 데스크탑에 설치되어 있는 iOS, Android 가상머신을 통해 실행할 수 있습니다.

이외에도 Expo XDE의 기능은 여러가지가 있습니다. 이외의 기능들은 Expo Documentation & Guides에서 확인할 수 있습니다.

CRNA 프로젝트 ejecting

지금까지 CRNA를 통해 프로젝트를 생성하고 실행해 보았습니다. 마지막으로 ejecting 기능에 대해서 알아보겠습니다. CRNA의 ejecting 기능은 번들로 제공되지 않는 기능이 필요해 라이브러리를 추가해야하는 경우 네이티브 코드 추가 및 빌드가 필요하기 때문에 CRNA를 사용해 생성한 프로젝트를 그대로 사용할 수가 없으므로 사용하게됩니다.

1
$ npm run eject

CRNA - eject 옵션 선택

eject 기능을 실행하면 2가지 옵션중 하나를 선택하게 됩니다. 1) CLI로 생성한 프로젝트와 같은 모양을 같는 프로젝트로 변경할 것인지, 2) 인기있는 라이브러리이 포함된 ExpoKit을 그대로 사용하며 android, ios 와 같은 네이티브 폴더를 eject 할 것인지 선택하게 됩니다.

ExpoKit 옵션을 선택하여 ExpoKit은 그대로 사용할 수 있도록 유지합니다. Expokit 옵션을 선택하게 되면 iOS bundle identifier등 Android의 package name을 설정하게 되는데, 이때 주의해야할 점은 package name을 올바르지 않게 설정하게 되면 후에 네이티브 컴파일에서 오류가 생기게 됩니다. 이를 다시 수정하는건 번거로운 일이니 처음 설정시 신중하게 설정해야합니다. (‘-‘나 ‘_’와 같은 문자 대신 ‘.’을 이용해 패키지 명을 작성합니다.)

CRNA - eject 설정 사항

crna 프로젝트를 eject하고 난 후에는 다음과 같이 폴더 구조가 변경됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
crna-project (eject with ExpoKit)
├── App.js
├── App.test.js
├── app.json
├── android/
├── ios/
├── node_modules/
├── .expo
├── .expo-source/
├── package.json
├── yarn.lock
└── README.md

이제 네이티브 관련 코드가 생성되었기 때문에 react-native-cli 명령어들을 사용할 수 있습니다. 그러나 react-native run-ios 명령어를 통해 실행을 하게되면 에러가 발생합니다. 이는 eject후 expo관련 모듈을 네이티브(ios) 폴더 아래에서 다시 설치해줘야하기 때문입니다. ios 폴더 아래에서 다음의 명령어를 실행합니다. (CocoaPods이 없으신 분들은 CocoaPods 홈페이지를 참고하여 설치합니다.) 또한 node_module도 다시 설치해야 하기때문에 프로젝트 폴더 아래에서 npm install을 실행합니다.

1
2
$ npm install // 프로젝트 폴더 아래에서
$ pod install // 프로젝트폴더-ios 폴더 아래에서

eject 후 Expo - ios 모듈 설치

이제 react-native run-ios 명령어를 실행하면 가상머신을 통해 실행할 수 있습니다. 그러나 기존 CLI를 통해 생성한 프로젝트와 다르게 CRNA로 프로젝트를 생성한 후 eject 하여도 최초 CRNA로 프로젝트를 생성한 것이라면 Expo 혹은 exp(Expo Cli Tool)의 도구가 필요합니다. (React Native 프로젝트 실행시 Packager라는게 필요한데 CRNA로 프로젝트를 셍성했다면 Expo혹은 exp가 이 packager를 대신 실행하게 됩니다.)

그렇기 때문에 Expo를 실행하여 프로젝트를 로드하거나 새로운 터미널을 실행하여 exp start를 실행한 후 react-native run-ios를 실행하면 가상머신에서 프로젝트가 실행됩니다.

Expo 라이브러리 사용해보기

Expo SDK는 다양한 라이브러리를 제공하고 있습니다. 기본적으로 자주 쓰이고 필요한 라이브러리들은 다 있고, 관리가 잘 되고 있기 때문에 믿고 쓸 수 있습니다. 아직 그 수가 많지는 않지만 Feature-Request에서 사용자와의 소통을 통해 지속적으로 라이브러리를 추가해가고 있습니다.

지금부터는 Expo SDK에 Lottie 라이브러리를 사용해 보겠습니다. Lottie는 Airbnb에서 만들어 제공하는 라이브러리로 iOS, Android, React Native에서 After Effects로 만든 애니메이션을 실시간으로 앱에서 정적 이미지를 사용하는 것처럼 쉽게 애니메이션을 사용할 수 있도록 도와줍니다.

Expo Lottie Document를 참고해서 Lottie 라이브러리를 사용하면 다음과 같은 간단히 테스트가 가능합니다.

Expo lottie 테스트

기존의 CLI를 통해 프로젝트를 생성하고 Lottie를 사용해보신분들은 정말 과정이 간편해졌다는걸 느낄 수 있습니다. Expo SDK를 사용하지 않고 React Native 프로젝트에서 Lottie를 사용하기 위해서는 네이티브 코드에 Lottie관련 코드들을 추가하고 컴파일 과정에서 생기는 문제를 해결하기 위해서 많은 시간이 필요했습니다. (React Native Lottie - Github을 참고해보세요) 그러나 Expo SDK를 사용하면 정말 간단한게 사용할 수 있게 되었습니다.

마치며

새롭게 추가된 CRNA는 React Native에 있어서 큰 변화라고 생각합니다. 아직은 Expo SDK에서 제공하는 라이브러리가 많지 않기 때문에 ejecting이 불가피하지만 Expo의 지속적인 관리로 앞으로 더 많은 라이브러리들과 기능들이 추가되고 점점 사용하기 쉽고 편하게 바뀔것이라 생각됩니다.

앞으로 새롭게 시작하는 React Native 프로젝트는 CLI보다는 CRNA를 통해서 프로젝트를 시작한 후 ejecting 기능을 사용해 Expo SDK를 그대로 가져가며 프로젝트는 진행하는것이 좋을것 같습니다.

추가적으로 Expo에 대해서 더 궁금한게 있으신분은 Expo-Frequently Asked Questions를 참고하시면 될것 같습니다.

참고