React Native 빌드 에러 해결기록

이진경·2024년 10월 14일

React native

목록 보기
1/4
post-thumbnail

3. CMake Error

✅ 문제 현상

React Native android 빌드 중 Cmake관련 오류가 잔뜩 발생.

🔍 원인 분석

  • React Native가 0.71 이후 버전에서 JSI, Hermes, TurboModules 등 C++ 기반의 네이티브 기능을 도입하면서 CMake 설정이 필수적으로 요구되는 경우가 많아짐.
  • 에러 로그를 보면 ".../node_modules/react-native-gesture-handler/android/build/generated/source/codegen/jni/" which is not an existing directory. 라고 하는 것을 보아하니 해당 경로에 jni폴더가 없어서 나는 에러였다.
  • 결과적으로 npm install을 해서 자동적으로 source/codegen/jni/ 이 경로까지 만들어져야하는데 그러지 못했던 것임.

🛠️ 해결 방법

node_modules 및 설정 관련된 폴더들 초기화 및 generateCodegenArtifactsFromSchema 실행

$ rm -rf node_modules
$ npm install
$ cd android
$ ./gradlew clean
$ ./gradlew generateCodegenArtifactsFromSchema
$ npx react-native run-android

✅ 결과


warning은 많지만 일단 성공 😬

💡 참고 팁

  • 결과적으로 ./gradlew generateCodegenArtifactsFromSchema 이 명령어를 통해서 해결하였는데, 이 명령은 React Native 프로젝트의 GraphQL 또는 TypeScript schema 등을 기반으로 자동 생성되는 코드/헤더 파일과 jni 폴더 구조를 만들어 줍니다.
    https://reactnative.dev/docs/the-new-architecture/using-codegen
    위 공식문서를 보면 일단 1차적으로 codegen에 대해서 나옵니다. 쉽게 얘기해서 네이티브 모듈과 컴포넌트를 자동으로 연결해주는 코드 생성도구입니다. 수동으로 작성하면 번거로운 C++, Java, Objective-C 코드를 Flow나 TypeScript 기반의 JS 사양(spec) 파일만 작성하면 자동으로 생성해 주는 것 입니다. 쉽게 말해, "JS로 네이티브 연동 구조를 선언하면, 나머지 연결 코드는 자동 생성된다" 는 개념입니다. 내부적으로 TurboModules와 연동되는 코드, CMakeLists.txt 등이 이 명령을 통해 생성됩니다.


    jni하위에 CMakeLists.txt를 포함한 폴더 및 파일들의 구조가 doc에 있으니 한번 훑어보시길 바랍니다. 😎

2. Duplicate Class Error

✅ 문제 현상

React Native 프로젝트 빌드 중 다음과 같은 에러가 발생했다

Execution failed for task ':app:checkDebugDuplicateClasses'.
A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
Duplicate class android.support.v4.app.INotificationSideChannel found in modules core-1.9.0.aar -> core-1.9.0-runtime (androidx.core:core:1.9.0) and support-compat-26.1.0.aar -> support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)
Duplicate class android.support.v4.app.INotificationSideChannel$Stub found in modules core-1.9.0.aar -> core-1.9.0-runtime (androidx.core:core:1.9.0) and support-compat-26.1.0.aar -> support-compat-26.1.0-runtime (com.android.support:support-compat:26.1.0)
...

🔍 원인 분석

에러 메시지를 보면 두 가지 라이브러리 간의 클래스 충돌이 원인이다

androidx.core:core:1.9.0
com.android.support:support-compat:26.1.0

이 두 라이브러리는 각각 androidx와 android.support 계열이다.
AndroidX로 마이그레이션한 프로젝트에서 여전히 일부 종속 라이브러리나 코드가 android.support를 참조하고 있다면 이러한 충돌이 발생한다.

즉, AndroidX와 android.support 라이브러리를 동시에 사용할 수 없기 때문에 충돌이 발생한다.

🛠️ 해결 방법

React Native 프로젝트를 완전히 AndroidX로 전환하기 위한 설정을 android/gradle.properties 파일에 추가한다

android.useAndroidX=true
android.enableJetifier=true

android.useAndroidX=true AndroidX 라이브러리를 사용하도록 설정
android.enableJetifier=true 기존 android.support 기반 라이브러리를 AndroidX로 자동 변환해줌 (Jetifier)

추가로 build.gradle에서 혹시 com.android.support 계열 라이브러리가 명시적으로 추가되어 있다면 제거하거나 androidx 버전으로 교체해주어야 한다.

✅ 결과

위 설정을 적용한 후 ./gradlew clean 후 다시 빌드를 실행하니,
충돌 없이 정상적으로 앱이 빌드되었다.

💡 참고 팁

Jetifier는 마이그레이션 호환성을 위해 존재하지만, 이후 사용하는 라이브러리가 모두 AndroidX를 지원한다면 enableJetifier는 false로 설정해도 된다.

가능하면 외부 라이브러리도 최신 AndroidX 지원 버전으로 유지하는 것이 좋다.

1. hermes-engine error

message: Command PhaseScriptExecution failed with a nonzero exit code

보통 빌드할때 react-native start CLI로 실행하는데, building... 이후로 아무 동작하지 않을때는 xcode로 빌드하게 된다.

빌드할때 hermes-engine error가 뜨면서 아무 동작하지 않을때는 xcode 의 env파일을 지워보자.. (이걸로는 해결했지만 다른 해결법이 있다면 그 해결법도 포스팅해보겠음.)

root디렉토리 터미널에서 아래 커맨드 실행하기

$ rm ./ios/.xcode.env.local

이걸로도 안된다면 로그를 확인하기

Showing Recent Messages

/Users/jklee/myreactproj/myapp/ios/Pods/../../node_modules/react-native/scripts/react-native-xcode.sh: line 175: /Users/jklee/myreactproj/myapp/ios/Pods/hermes-engine/destroot/bin/hermesc: No such file or directory

필자는 계속 Pods/hermes-engine/destroot/bin/hermesc 파일을 찾지 못한다는 에러와 함께 Command PhaseScriptExecution failed with a nonzero exit code 에러가 떴기때문에...

targets > myapp > Build Settings > User-Defined 에서
Use_HERMES = false로 바꿔서 빌드해보았더니 거짓말처럼 빌드가 잘되서
다시 true로 바꿨더니 거짓말처럼 또 폴더를 잘찾아서 빌드가 되었다

👾 기타 명령어 모음

Xcode의 캐시 데이터(빌드 캐시)를 완전히 삭제하는 명령어

rm -rf ~/Library/Developer/Xcode/DerivedData

profile
기록남기기

0개의 댓글