배경
XCode에서 iOS SDK 17 이상으로 build 해야만 App Store에 Upload할 수 있다는 경고가 떠서 version up & migrate ticket이 생겼다.
2024년 4월 부터 적용하기 때문에 이번 Sprint에서 해결해야하는데, 아무도 나서서 하지 않길래 솔선수범하여 나섰다.
React Native로 작성한 Application은 2개 였는데, 각각 버전이 0.5x, 0.6x 였다.
3주에 걸쳐 작업한 과정을 간단하게 기록한다.
과정
Upgrade Helper
일단 major change와 pod file, gradle script와 같은 변화를 쉽게 보여준다.
다만 기존 build.gradle 파일이나 android/settings.properties 같이, 이전에 package에서 특정 파일을 가져오거나, ios/AppDelegate.m에서 특정 code를 삽입한 경우가 있기 때문에(e.g. react-native-splash-screen), 직접 파일을 열어서 확인하며 반영하였다.
Package
특히 package를 update한 경우, react native v-0.60 이후 auto-link를 지원하도록 바뀐 경우가 많기 때문에, 일일이 github repo를 방문해서 확인하며 upgrade를 진행했다.
0.74-rc2에서 발생한 문제들
아래 문제들은 0.73.6으로 내림으로 해결했다
Extend NSDictArray
NSDict를 확장한 경우에, 이는 Class Cluster여서 count와 keyEnumerator을 별도로 구현해야하는데, 0.74-rc2는 해당 부분이 구현되지 않아서 추가해주었다.
// RCTUIManager.m:1682
- (NSUInteger)count {
return [_registry count];
}
- (NSEnumerator *)keyEnumerator {
return [_registry keyEnumerator];
}
Hermes : minimumOSVersion not found
0.74-rc2에서 build/hermes/universal/info.plist 중 minimumOSVersion 값이 비어있었다. FastLane을 쓰면 Build 과정에서 수정할 수 있는 모양인데, 우리는 아직 FastLane을 쓰지 않아서 적용할 수 없었다.
0.73.6으로 내리게 된 결정적인 이유.
Deprecated Types on React Native
더 이상 관리하지 않는 package 중에서 더 이상 react native에서 사용하지 않는 type이 있다. react-native/index.js를 수정해서 patch-package react-native로 해결했다.
Package 발생 문제들
아래와 같은 이유로 정상작동 하지 않는 package가 많았다.
- 이관하거나
- dependency version이 안 맞거나
- breaking change가 있는 major update거나
- deprecated했거나
- 예전 resource를 사용하거나
- 문제가 됐던 package들의 예시 중 일부이다.
- redux-persist : maintainer가 없는 상태, async-storage 이전으로 인한 getStorage 변경, deviceState
- react-native-reanimated :
- lottie-react-native : UNSET → -1
- native-base@2 : picker package 변경으로 인한 종속성 설정
- @react-native-picker/picker → @react-native-community/picker
- react-native-onesignal : migration을 진행할 수 없어서, 같은 버전 중 최근 버전으로 수정, 일부 migration [0.12.0] → [0.14.0…0.99.0]
- react-native-splash-screen : 설정 및 MainActivity.kt/Application.kt, ios/[PRODUCT]/AppDelegate.mm 변경
- react-native-print : minSDK 설정
- react-native-device-info : registerReceiver 등록 시 receiver type 정의 (PR)
- react-native-vector-icons : ionicons.ttf font 변경으로 인한 깨짐 현상
- ...
react-native → @react-community
async storage, netinfo, picker 등 다양한 패키지가 편입되었다.
Android
큰 문제는 없었다. 다만 Gradle version 4→8로 upgrade하는 과정이 쉽지 않았다. JDK 설정을 맞춰도 실패하는 경우가 많았고, kotlin을 사용하거나, 예시 중 build.gradle.kt를 사용하거나, buildscript를 사용하지 않아서 헷갈리거나 수정하고 확신 없이 build로 실패 요인을 확인하는 것이 어려웠다.
특히 implemtation, classpath 등, gradle 변경에서 수반하는 변화를 update하지 않은 package가 있어 골치가 아팠다.
iOS
Duplicated Symbols
build tab > timeline > Show Collapse를 선택하면 log에 어떤 symbol이 duplicated 했는지 알 수 있다.
rn-fetch-blob + react-native-blob-util 충돌
위와 마찬가지로 duplicated symbol이 발생한다
No More Flipper
0.73.6에서는 react-native.config.js의 예시 파일이 없기 때문에 기본적으로 Flipper를 pod에 설치하려고 함. 이 경우 duplicated에러가 발생한다
두 가지 선택지가 있다. :
- ios/Podfile에서 flipper-installer를 지우거나
- react-native.config.js에 아래 코드를 넣어 설정하거나
module.exports = {
dependencies: {
...(process.env.NO_FLIPPER
? {'react-native-flipper': {platforms: {ios: null}}}
: {})
},
};
후기
React Native 단점을 꼽으라면, native SDK 보다 생리적으로 느리게 반영할 수 밖에 없는 이유를 꼽을 수 있겠다. 예를 들면, Firebase SDK BOM을 react-native-firebase에서 아직은 지원하지 않는다.
그럼에도 불구하고, JavaScipt base 개발자가, 손 쉽게 화면을 만들고, 생태계에서 제공하는 native module을 잘 활용해서 높은 완성도를 가진 Mobile Application을 만들 수 있다는 점에서 부정할 수 없는 강점을 가지고 있다고 생각한다.
다만 이런 version update마다 change log를 뒤져서 break changes를 살피거나 , 특히 Package가 자주 바뀌거나 편입하거나 이동할 때 마다 일일이 따라가는 것이 번거롭다. Upagrade Helper가 정리해주긴 하지만, Package마다 변경하는 부분은 직접 알아보아야한다.
개인적인 욕심이 있다면, Flutter를 쓰든, React Native를 쓰든 2개 프로젝트를 하나로 합쳐서 monorepo 형식으로 만들고, Web과 통합한 Design System을 구축하고 싶다. 또한 FastLane을 써서 배포 관리를 하고 싶다.
Flipper를 버리고 Hermes를 사용한 것도 괄목할만한 부분인 것 같다. 이 부분은 나중에 자료를 조금 더 정리해서 공유할 예정이다. (예를 들어, Flipper를 사용하지 않기 때문에 debugger를 연결할 때 손 봐주어야하는 부분)
'Front-End' 카테고리의 다른 글
이직 회사 적응 안내서 -2- Front-End 분석 (0) | 2024.03.26 |
---|---|
[AngularJS] Bootstrap 부터 개념 대강 살펴보기 (0) | 2024.02.19 |