San Francisco Meetup Recap
지난주에 Zynga의 샌프란시스코 사무실에서 열린 React Native Meetup에 참석할 기회가 있었다. 약 200명이 참석한 이 행사는 React Native에 관심이 있는 주변 개발자들을 만나기 좋은 자리였다.
나는 특히 Zynga, Netflix, Airbnb와 같은 회사에서 React와 React Native를 어떻게 사용하는지 더 깊이 알아보는 데 관심이 있었다. 그날 밤의 주제는 다음과 같았다:
- React를 활용한 빠른 프로토타이핑
- React Native를 위한 API 설계
- 기존 코드베이스에서 React Native 사용하기: 차이를 좁히는 방법
하지만 먼저, 행사는 간단한 소개와 최근 소식으로 시작되었다:
- React Native가 이제 GitHub에서 가장 인기 있는 Java 저장소라는 사실을 알고 있었나?
- rnpm이 이제 React Native 코어에 포함되었다! 이제
rnpm link
대신react-native link
를 사용해 네이티브 의존성을 가진 라이브러리를 설치할 수 있다. - React Native Meetup 커뮤니티가 빠르게 성장하고 있다! 전 세계 다양한 React Native 모임에 4,800명 이상의 개발자가 참여하고 있다.
만약 이런 모임이 여러분 근처에서 열린다면, 꼭 참석해 보길 추천한다!
Zynga에서 React를 활용한 빠른 프로토타이핑
첫 번째 소식에 이어 저녁 행사의 주최사인 Zynga가 간단한 소개를 진행했다. 아비쉐크 차다는 모바일에서 새로운 경험을 빠르게 프로토타이핑하기 위해 React를 어떻게 사용하는지 설명했다. Draw Something와 유사한 앱의 빠른 프로토타입을 시연했다. 그들은 React Native와 유사한 접근 방식을 사용해 브리지를 통해 네이티브 API에 접근한다. 아비쉐크가 기기의 카메라를 사용해 관객의 사진을 찍은 다음, 누군가의 머리에 모자를 그리는 것으로 이를 시연했다.
Netflix에서 React Native API 설계하기
다음은 오늘 밤 첫 번째 주요 발표다. Netflix의 수석 소프트웨어 엔지니어 Clarence Leung이 React Native를 위한 API 설계에 대해 발표했다. 그는 먼저 작업할 수 있는 두 가지 주요 라이브러리 타입을 언급했다. 탭 바와 날짜 선택기 같은 컴포넌트와 카메라 롤이나 인앱 결제 같은 네이티브 서비스에 접근을 제공하는 라이브러리다. React Native에서 사용할 라이브러리를 구축할 때 두 가지 접근 방식이 있다:
- 플랫폼별로 특화된 컴포넌트 제공
- Android와 iOS 모두에 대해 유사한 API를 가진 크로스 플랫폼 라이브러리
각 접근 방식에는 고려할 사항이 있으며, 어떤 방식이 필요에 가장 적합한지는 독자가 결정해야 한다.
접근 방식 #1
플랫폼별로 특화된 컴포넌트의 예로 Clarence는 React Native 코어의 DatePickerIOS와 DatePickerAndroid를 언급했다. iOS에서는 날짜 선택기가 UI의 일부로 렌더링되며 기존 뷰에 쉽게 포함할 수 있지만, Android에서는 모달로 표시된다. 이런 경우에는 별도의 컴포넌트를 제공하는 것이 합리적이다.
접근 방식 #2
반면, 사진 선택기는 Android와 iOS에서 비슷하게 처리된다. Android는 iOS의 Selfies처럼 사진을 폴더로 그룹화하지 않는 등 약간의 차이가 있지만, if
문과 Platform
컴포넌트를 사용해 쉽게 처리할 수 있다.
어떤 접근 방식을 선택하든, API 표면을 최소화하고 앱 특화 라이브러리를 구축하는 것이 좋다. 예를 들어, iOS의 인앱 구매 프레임워크는 일회성 소모성 구매와 갱신 가능한 구독을 모두 지원한다. 앱이 소모성 구매만 지원할 예정이라면 크로스 플랫폼 라이브러리에서 구독 지원을 제외할 수 있다.
Clarence의 발표가 끝나고 짧은 Q&A 세션이 진행됐다. 흥미로운 점 중 하나는 Netflix에서 이러한 라이브러리를 위해 작성된 React Native 코드의 약 80%가 Android와 iOS 모두에서 공유된다는 사실이었다.
기존 코드베이스에 React Native 통합하기
이번 밤의 마지막 발표는 Airbnb의 Leland Richardson가 맡았다. 그의 발표는 기존 코드베이스에 React Native를 도입한 Airbnb의 경험에 초점을 맞췄다. React Native로 새 앱을 만드는 것이 얼마나 쉬운지 이미 알고 있었기에, 기존 네이티브 앱에 React Native를 도입한 Airbnb의 경험에 큰 관심이 생겼다.
Leland은 먼저 그린필드(greenfield) 앱과 브라운필드(brownfield) 앱의 차이점을 설명했다. 그린필드는 기존 작업을 고려하지 않고 새 프로젝트를 시작하는 것을 의미한다. 반면 브라운필드는 기존 프로젝트의 요구사항, 개발 프로세스, 그리고 각 팀의 다양한 필요를 고려해야 한다.
그린필드 앱을 개발할 때는 React Native CLI가 Android와 iOS를 위한 단일 저장소를 설정하고 모든 것이 잘 작동한다. Airbnb에서 React Native를 도입할 때 첫 번째로 마주한 문제는 Android와 iOS 앱이 각각 별도의 저장소를 가지고 있다는 점이었다. 다중 저장소를 사용하는 회사는 React Native를 도입하기 전에 몇 가지 장벽을 넘어야 한다.
이 문제를 해결하기 위해 Airbnb는 먼저 React Native 코드베이스를 위한 새 저장소를 설정했다. 그들은 지속적 통합(CI) 서버를 사용해 Android와 iOS 저장소를 이 새 저장소에 미러링했다. 테스트가 실행되고 번들이 빌드된 후, 빌드 아티팩트는 다시 Android와 iOS 저장소로 동기화된다. 이렇게 하면 모바일 엔지니어들이 개발 환경을 변경하지 않고도 네이티브 코드를 작업할 수 있다. 모바일 엔지니어들은 npm을 설치하거나 패키저를 실행하거나 JavaScript 번들을 빌드할 필요가 없다. React Native 코드를 작성하는 엔지니어들도 Android와 iOS 간 코드를 동기화할 걱정 없이 React Native 저장소에서 직접 작업할 수 있다.
하지만 이 방법에는 단점도 있다. 가장 큰 문제는 원자적 업데이트를 배포할 수 없다는 점이다. 네이티브 코드와 JavaScript 코드가 모두 필요한 변경 사항은 세 개의 별도 풀 리퀘스트가 필요하며, 이 모든 것을 신중하게 적용해야 한다. 충돌을 피하기 위해 빌드가 시작된 이후 master 브랜치에 변경 사항이 생기면 CI는 Android와 iOS 저장소에 변경 사항을 적용하지 못한다. 이는 새로운 릴리즈가 나오는 날과 같이 커밋 빈도가 높은 날에는 긴 지연을 초래할 수 있다.
Airbnb는 이후 모노레포(mono repo) 방식으로 전환했다. 다행히 이 전환은 이미 고려 중이었고, Android와 iOS 팀이 React Native 사용에 익숙해지자 모노레포로의 전환을 가속화했다.
이 전환은 분리된 저장소 방식에서 발생했던 대부분의 문제를 해결했다. Leland은 이 방식이 버전 관리 서버에 더 큰 부하를 준다는 점도 언급했는데, 이는 규모가 작은 회사에서는 문제가 될 수 있다.
네비게이션 문제
Leland의 발표 후반부는 내게도 관심 있는 주제인 React Native의 네비게이션 문제에 초점을 맞췄다. 그는 React Native에서 사용할 수 있는 다양한 네비게이션 라이브러리, 퍼스트파티와 서드파티 모두를 언급했다. NavigationExperimental은 처음에는 유망해 보였지만, 결국 그들의 사용 사례에는 적합하지 않았다.
실제로 기존의 어떤 네비게이션 라이브러리도 브라운필드 앱에 잘 맞지 않았다. 브라운필드 앱은 네비게이션 상태가 네이티브 앱에 완전히 소유되어야 한다. 예를 들어, React Native 뷰가 표시되는 동안 사용자 세션이 만료되면 네이티브 앱이 이를 인지하고 필요한 경우 로그인 화면을 표시할 수 있어야 한다.
Airbnb는 또한 전환 과정에서 네이티브 네비게이션 바를 자바스크립트 버전으로 대체하는 것을 피하고 싶었다. 그렇게 하면 사용자 경험이 어색해질 수 있기 때문이다. 초기에는 모달로 표시되는 뷰로 제한했지만, 이는 앱 전체에 React Native를 더 광범위하게 도입하는 데 문제가 되었다.
그들은 자체 라이브러리가 필요하다고 판단했다. 이 라이브러리의 이름은 airbnb-navigation
이다. 이 라이브러리는 Airbnb의 코드베이스와 강하게 연결되어 있어 아직 오픈소스로 공개되지 않았지만, 연말까지 공개할 계획이다.
라이브러리의 API에 대해 자세히 설명하지는 않겠지만, 주요 내용은 다음과 같다:
- 각 씬(scene)을 미리 등록해야 한다.
- 각 씬은 자체
RCTRootView
내에서 표시된다. 각 플랫폼에서 네이티브로 표시된다(예: iOS에서는UINavigationController
를 사용). - 씬의 주요
ScrollView
는ScrollScene
컴포넌트로 감싸야 한다. 이렇게 하면 iOS에서 상태 바를 탭해 상단으로 스크롤하는 것과 같은 네이티브 동작을 활용할 수 있다. - 씬 간 전환은 네이티브로 처리되므로 성능에 대해 걱정할 필요가 없다.
- Android 뒤로 가기 버튼이 자동으로 지원된다.
- Navigator.Config UI-less 컴포넌트를 통해 뷰 컨트롤러 기반 네비게이션 바 스타일링을 활용할 수 있다.
또한 주의해야 할 몇 가지 사항이 있다:
- 네비게이션 바는 네이티브 컴포넌트이므로 자바스크립트에서 쉽게 커스터마이즈할 수 없다. 이는 의도된 설계로, 네이티브 네비게이션 바를 사용하는 것이 이 라이브러리의 핵심 요구사항이다.
- ScreenProps는 브리지를 통해 전송될 때 직렬화/역직렬화되므로, 너무 많은 데이터를 전송할 때 주의해야 한다.
- 네비게이션 상태는 네이티브 앱이 소유하므로(이 역시 라이브러리의 핵심 요구사항), Redux와 같은 도구로 네비게이션 상태를 조작할 수 없다.
Leland의 발표 후에는 Q&A 세션이 이어졌다. 전반적으로 Airbnb는 React Native에 만족하고 있다. 그들은 App Store를 거치지 않고 Code Push를 사용해 문제를 해결하는 데 관심이 있으며, 엔지니어들은 Live Reload를 좋아한다. 사소한 변경 후에도 네이티브 앱을 다시 빌드할 필요가 없기 때문이다.
마무리
이번 행사는 몇 가지 React Native 관련 소식으로 마무리했다:
- Deco는 React Native Showcase를 발표하고, 모두가 자신의 앱을 목록에 추가하도록 초대했다.
- 최근에 진행된 문서 개편이 소개됐다!
- Deco IDE의 창시자 중 한 명인 Devin Abbott가 React Native 강좌를 진행할 예정이다.
미트업은 커뮤니티의 다른 개발자들을 만나고 배울 수 있는 좋은 기회다. 앞으로 더 많은 React Native 미트업에 참석할 생각이다. 여러분도 미트업에 참여한다면, 저를 찾아 React Native를 더 잘 활용할 수 있는 방법에 대해 이야기해보자!