expo 47 -> 48 빌드 에러 해결

해결 방법

package.json 에서 expo-cli 를 삭제

문제 상황

회사에서 인력이 부족해서 한 두 달정도 다른 프로젝트를 하고 다시 앱 개발하려 돌아오니 expo 48 버전이 릴리즈 되어있었다. 가능하면 최대한 최신 버전을 사용하려고 하기 때문에 큰 걱정 없이 업데이트하고 테스트하고 안드로이드 apk 생성을 위한 빌드를 진행하였다. 그런데 코드는 달라진게 없는데 빌드 에러가 발생하였다.

Alt text

해결 과정

원인 파악

막연하게 떠오른 이유는 아래와 같다.

  1. expo 48 버전의 문제
  2. expo 48 버전으로 업데이트함과 동시에 다른 라이브러리를 업데이트하면서 문제 발생
  3. 일시적 expo 빌드 시스템의 문제

1번의 경우를 확인하기 위해 github expo issue 에 들어가 확인해보니 다른 사용자는 잘 사용하고 있었다. 그리고 배포된지 대략 한 달정도 되었기 때문에 expo 48 버전의 문제는 아닌 것으로 판단하였다.

2번의 경우를 확인하기 위해 기존 버전으로 돌려놓고 expo 만 48 버전으로 변경하여 빌드해보았다. 그런데 똑같이 빌드 에러가 발생하였다. 즉 expo 48 자체만으로도 에러가 발생하는 것을 확인하였다.

3번의 경우를 확인하기 위해 시간 텀을 두고 대략 3번정도 re-build 를 시도하였는데 에러가 발생하였다. 그래서 expo 빌드 시스템의 문제는 아닌 것으로 판단하였다.

이로써 큰 범주의 문제는 아닌 것으로 판단되었다. 즉 세밀히 들여다볼 필요가 있다. 우선 에러의 문구를 확인해보았다.

Alt text

[stderr] /home/expo/workingdir/build/app/mymemory/android/app/src/main/java/kr/co/mymemory/MainActivity.java:19: error: package R does not exist
[stderr] setTheme(R.style.AppTheme);
[stderr] ^
[stderr] /home/expo/workingdir/build/app/mymemory/android/app/src/main/java/kr/co/mymemory/MainActivity.java:39: error: cannot find symbol
[stderr] return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, new DefaultReactActivityDelegate(
[stderr]                                          ^
[stderr] symbol:   variable BuildConfig
[stderr] location: class MainActivity
[stderr] /home/expo/workingdir/build/app/mymemory/android/app/src/main/java/kr/co/mymemory/MainApplication.java:26: error: cannot find symbol
[stderr] return BuildConfig.DEBUG;
[stderr]       ^
[stderr] symbol: variable BuildConfig
[stderr] /home/expo/workingdir/build/app/mymemory/android/app/src/main/java/kr/co/mymemory/MainApplication.java:45: error: cannot find symbol
[stderr] return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
[stderr]       ^
[stderr] symbol: variable BuildConfig
[stderr] /home/expo/workingdir/build/app/mymemory/android/app/src/main/java/kr/co/mymemory/MainApplication.java:50: error: cannot find symbol
[stderr] return BuildConfig.IS_HERMES_ENABLED;
[stderr]       ^
[stderr] symbol: variable BuildConfig
[stderr] /home/expo/workingdir/build/app/mymemory/android/app/src/main/java/kr/co/mymemory/MainApplication.java:63: error: cannot find symbol
[stderr] if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
[stderr] ^
[stderr] symbol:   variable BuildConfig
[stderr] location: class MainApplication
[stderr] /home/expo/workingdir/build/app/mymemory/android/app/src/main/java/kr/co/mymemory/MainApplication.java:63: error: illegal parenthesized expression
[stderr] if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
[stderr] ^
[stderr] /home/expo/workingdir/build/app/mymemory/android/app/src/main/java/kr/co/mymemory/MainApplication.java:67: error: cannot find symbol
[stderr] ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
[stderr] ^
[stderr] symbol:   variable ReactNativeFlipper
[stderr] location: class MainApplication
[stderr] 8 errors

에러 스택에서 가장 하단을 보니 ReactNativeFlipper 에서 에러가 시작되었다. 그렇기에 ReactNativeFlipper 를 토픽으로 검색을 하였는데 대체로는 android 파일을 수정하라는 것이였는데 필자의 경우는 expo managed 를 사용하여 안드로이드 파일이 없다. 그렇기에 다른 해결 방법을 더 찾다보니 눈에 들어온 것은 중복 클래스가 있으면 에러를 발생한다는 것이였다.

alt text

그래서 생각한 원인은 package 가 꼬였다는 것이다.

expo 의 경우는 expo doctor를 통해 프로젝트 진단을 제공한다. expo doctor 실행하였더니 문제가 여럿 보고되었다.

alt text

기대하는 패키지 버전과 다른 것들이 목록으로 출력해주었다. 이를 통해 우선 expo-modules-autolinking 의 문제를 더 들여다보기 위해 npm why expo-modules-autolinking 을 실행하였다.

alt text

alt text

alt text

expo-modules-autolinking 을 사용하고 있는 부분을 찾아보니 아래와 같이 정리할 수 있다.

  • expo 안에 expo-modules-autolinking
  • @expo/prebuild-config 안에 expo-modules-autolinking
  • expo-cli 안에 @expo/prebuild-config

이를 트리로 나타내면 아래와 같다.

  • expo
    • expo-modules-autolinking
  • expo-cli
    • @expo/prebuild-config
      • expo-modules-autolinking

해결 작업

expo-modules-autolinking 가 충돌나고 있는 것은 expoexpo-cli 두 개의 패키지 때문이라는 것을 알 수 있다. 만약 둘 다 필수적이라면 해결 방법이 더 복잡해질 수 있으나 사실 expo-cli 는 전역 패키지로 package.json 에서 관리될 필요 없다. 그렇기에 expo-cli 를 삭제하고 다시금 패키지를 설치하였다. 그 후 다시 expo doctor 를 실행하였다.

alt text

그 결과 리포트의 결과가 6개에서 1개로 줄었다. 그래서 다시 expo apk 빌드를 진행하였다. alt text

결과는 성공적으로 expo 버전이 업그레이드 되었다.

결과론적으로 어떤 부분을 놓치고 의식하지 못해 이런 문제가 발생하게 되었는지 돌아보았다. 그 결과 프로답지 못한 부분이 있었는데 빌드 process 에는 expo doctor 를 실행하는 단계가 있다. 이미 빌드 시스템은 문제가 있다고 누차 이야기하고 있었다. 이를 무시하고 진행한 이유는 사실 이전부터 이러한 출력이 있었기 때문이다. 그런데 빌드가 성공적으로 되고 앱 실행이 되니 중요하지 않다고 넘기고 있다가 이제서야 수면 위로 올라오게 된 것이다.

항상 느끼지만 의식하지 못할 때 문제가 생긴다. 지금 당장 넘어가고 불편함이 익숙해질 때 이미 병은 점점 악화되어가고 있다가 큰 문제로 다가온다. 제일 큰 문제는 문제가 생기기 전까지 의식하지 못한다는 것이다. 이럴 때마다 다짐하지만 반복된다. 그렇지만 긍정적인 것은 점점 성장하고 이러한 경험을 잘 정리해서 다음에는 방지하기 위한 토대로 쌓기 때문이다.

alt text

문제가 되었던 expo-cli 를 지우니 빌드 시스템에서는 이제 문제가 없다고 알려준다.

alt text

결론

에러만 고쳐야할 것이 아니라 warning 도 신경 쓰고 원인 파악을 해야한다. 이 작업이 건강검진이라고 볼 수 있다.


실용주의 프로그래머 Topic 43

Topic 43 바깥에서는 안전에 주의하라

Sunsetting “expo publish” and Classic Updates 번역

이 글은 expo 공식 블로그의 글을 번역한 글입니다.

NCloud LB & SourcePipeline 구축하기
tech collection 서비스 성능 개선하기
Selenium 복권 구매 자동화 만들어보기
디자인 패턴
책 리뷰
블로그 챌린지