[React Native] 설정 기록

2021년 7월 24일

이번에 스터디에서 사용할 React Native 설정을 진행하면서 만나게 된 문제를 해결하기 위해서 찾아본 것들에 대해서 나중에 다시 참고하기 위해 간단하게나마 정리해보고자 합니다.

기본 설정

기본적인 설정은 React Native의 공식 문서인 Setting up the development environment를 참조해서 진행하였습니다. 해당 가이드를 따라가면서 정리할 만한 내용은 다음과 같습니다.

Expo CLI vs React Native CLI

환경에 구애받지 않고 간단하게 개발을 시작하기에는 Expo가 매력적이겠지만, 추가적인 기능이 필요하여 Native 파일을 제어하게 되는 상황이 필요하게 된다면 사용할 수 없게 되어 eject를 해야 되는 상황이 오게 됩니다. 필자는 일반적으로 사용하는 경우에 대해서는 Android와 iOS를 모두 빌드할 수 있는 환경이므로 React Native CLI를 사용하였습니다.

Template로 프로젝트 생성

기본 가이드를 따라가다 보면 자연스럽게 아래와 같은 명령으로 프로젝트를 생성하게 됩니다.

npx react-native init AwesomeProject

가이드에서도 잘 나와 있지만 react-native init은 특정 버전으로 생성하는 --version 옵션과 커스텀 템플릿을 바탕으로 생성하는 --template 옵션이 있습니다. TypeScript를 사용하는 경우라면 미리 아래와 같은 명령으로 TypeScript Template를 바탕으로 생성하면, TypeScript 적용을 하기 위해 프로젝트를 추가로 전환하는 시간을 아낄 수 있습니다.

npx react-native init AwesomeTSProject --template react-native-template-typescript

nvm사용 시 Node 버전 충돌

Command PhaseScriptExecution 오류라는 글에서 이미 공유하였지만, 간단하게 다시 언급하자면 Homebrew를 통하여 nvm을 사용하며 추가로 npm이나 yarn을 설치했을 때 Node 버전이 충돌하여 Command PhaseScriptExecution가 발생할 수 있습니다. 다음 명령을 통하여 Node 버전을 충돌을 확인하여 npm이나 yarn 삭제하고 다시 다른 방식으로 설치하여 해결할 수 있었습니다.

/usr/local/bin/node -v
node -v

Java Development Kit

Android로 빌드하기 위해서는 JDK가 필요한데 macOS의 경우는 아래와 같이 Homebrew로 설치하도록 가이드하고 있습니다.

brew install --cask adoptopenjdk/openjdk/adoptopenjdk8

Java로 구성된 Backend 환경에서 개발하거나 다른 이유로 JDK 8 이상이나 혹은 복수의 JDK를 사용해야 하는 경우가 있습니다. 필자는 맥에서 Brew로 자바 설치하기(feat. 자바버전 바꾸기)라는 글을 참조하여 아래와 같이 설정해서 사용하였습니다.

  • JDK 11, 14 설치
brew install --cask adoptopenjdk11
brew install --cask adoptopenjdk14
  • shell 환경 설정
# Java Paths
export JAVA_HOME_11=$(/usr/libexec/java_home -v11)
export JAVA_HOME_14=$(/usr/libexec/java_home -v14)

# Java Home
export JAVA_HOME=$JAVA_HOME_11
# export JAVA_HOME=$JAVA_HOME_14

Mono Repo

Yarn Workspace나 Lerna를 통한 Mono Repo 구성 시 추가적인 설정이 필요합니다. React-Native + CRA MonoRepo 환경 구축하기라는 글을 참조하여 설정하였습니다.

불필요한 파일 삭제

CLI를 통해 생성되는 기본 프로젝트에는 git을 설정하기 위한 .git이 함께 생성됩니다. Mono Repo에서는 불필요하기 때문에 이 파일을 삭제합니다.

rm -rf <rn-project-name>/.git

nohoist 설정 추가

Podfile 등과 같이 React Native 파일 내에 다음과 같이 node_modules를 참조하는 경우가 많습니다. Mono Repo 구성 시 React Native 프로젝트에서 참조하는 react-native 등의 모듈이 root로 hoisting되어 경로가 달라져 해당 모듈을 찾지 못하는 문제가 발생합니다.

require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '12.1'

# ...

아래와 같이 root로 hoisting 되지 않도록 root packagenohoist를 설정합니다.

{
  "name": <project-name>,
  "version": "1.0.0",
  "devDependencies": {
    "lerna": "^3.22.1"
  },
  "workspaces": {
    "packages": [
      "packages/*"
    ],
    "nohoist": [
      "**/<rn-project-name>",
      "**/<rn-project-name>/**"
    ]
}

metro.config.js 내 root 수정

React Native를 생성한 root가 아닌 Mono Repo의 root를 바라보도록 projectRoot를 수정합니다.

const path = require("path");

module.exports = {
  projectRoot: path.resolve(__dirname, "../../"),
  transformer: {
    getTransformOptions: async () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: false,
      },
    }),
  },
};

iOS 설정

  • AppDelegate.m 수정

jsBundleURLForBundleRoot@"index"에서 jsBundleURLForBundleRoot@"packages/<rn-project-name>/index"로 변경합니다.

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"packages/<rn-project-name>/index" fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
  • Bundle React Native code and Images 수정
  1. Explorer에서 <rn-project-name> 클릭
  2. Target의 <rn-project-name> 클릭
  3. Build Phases 에서 Bundle React Native code and Images 클릭
  4. shell에 EXTRA_PACKAGER_ARGS 설정 추가
export NODE_BINARY=node
export EXTRA_PACKAGER_ARGS="--entry-file packages/<rn-project-name>/index.js --reset-cache"
../node_modules/react-native/scripts/react-native-xcode.sh

Android 설정

  • packages/<rn-project-name>/android/app/src/main/java/com/mobile/MainApplication.java 수정

getJSMainModuleName()메서드의 반환 값을 index에서 packages/<rn-project-name>/index로 수정합니다.

@Override
protected String getJSMainModuleName() {
  return "packages/<rn-project-name>/index";
}
  • packages/<rn-project-name>/android/app/build.gradle 수정

android/app 폴더에 있는 build.gradle 파일의 project.ext.react 설정에 cliPathentryFile를 추가합니다.

project.ext.react = [
  enableHermes: false, // clean and rebuild if changing
  cliPath: "../../node_modules/react-native/local-cli/cli.js",
  entryFile: "packages/<rn-project-name>/index.js",
];

Silicon Mac 설정(M1)

Intel 기반의 CPU를 쓰는 Mac에서 설정하고는 Silicon Mac에서 시도해봤지만 우려한 대로 정상적으로 동작하지 않아서 Silicon Mac에서 동작하도록 수정을 한 후 교차로 테스트해서 동작하는지 확인하였습니다. 이때 Silicon Mac에 설정한 부분에 대한 정리입니다.

iOS 설정

다른 모든 방법을 동원해서 설정을 시도해보았지만, 전부 실패하고 react-native 0.64.2 with Apple M1 and Xcode 12.5라는 글을 참조해서 설정하고서야 실행에 성공했습니다. 특히 이 방식을 통하면 Rosetta 없이 실행할 수 있습니다.

Android 설정

Android 빌드하기 위해 Jetbrain Toolbox를 사용하여 Android Studio를 설치하였고, arm64 기반 Image인 Simulator를 준비하였습니다. 하지만 react-native run-android를 실행하였을 시 Simulator가 켜져 있음에도 불구하고 device가 계속 Offline 상태로 잡히는 문제가 있었습니다. 이때 Android Studio가 Intel 프로세서로 뜨고 있는 것을 확인하여 아래 명령으로 Android Studio 깨끗하게 제거한 후 Android 스튜디오 다운로드 자료실에서 Android 스튜디오 Arctic Fox(2020.3.1) 베타 5를 받아 설치하여 사용하였습니다.

rm -Rf /Applications/Android\ Studio.app
rm -Rf ~/Library/Preferences/AndroidStudio*  
rm -Rf ~/Library/Preferences/com.google.android.*  
rm -Rf ~/Library/Preferences/com.android.*  
rm -Rf ~/Library/Application\ Support/AndroidStudio*  
rm -Rf ~/Library/Logs/AndroidStudio*  
rm -Rf ~/Library/Caches/AndroidStudio*  
rm -Rf ~/.AndroidStudio*  
rm -Rf ~/.gradle  
rm -Rf ~/.android  
rm -Rf ~/Library/Android*  
rm -Rf /usr/local/var/lib/android-sdk/
rm -Rf ~/Library/Logs/Google/AndroidStudio*
Recently posts
© 2016-2023 smilecat.dev