Post

Expo Docs

Expo 공식 문서를 정리

Expo Docs

소개


Expo는 Android와 iOS 애플리케이션을 쉽게 개발할 수 있는 프레임워크이다. 파일 기반의 라우팅, 네이티브 모듈의 표준 라이브러리 등을 제공한다.


프로젝트 생성


Expo는 Node.js 가 필요하며, create-expo-app 으로 생성된 프로젝트로 시작하는 것을 권장한다.

새로운 프로젝트를 만들려면 다음 명령어를 실행하면 된다.

1
npx create-expo-app@latest
  • --template 옵션을 추가할 수 있다

그 다음으로 개발 환경을 설정해보자.


개발 환경 설정


로컬 개발 환경을 설정해보자. 사용자에게 어떻게 보이는지 직접 보기 위해 실제 디바이스를 사용하는 것을 권장한다.


Xcode와 Watchman 설정


1. Xcode 설치

App Store에서 Xcode를 설치한다.


2. Xcode Command Line Tools 설치

Xcode를 열고, 설정(cmd + ,)으로 이동한다. Locations 로 이동한 후에 Command Line Tools에서 가장 최신 버전을 설치한다.


3. iOS Simulator 설치

Xcode > Settings > Components > Platform Support 에서 iOS Simulator를 설치한다.


4. Watchman 설치

Watchman은 파일 시스템의 변화를 감지하는 도구이다. 다음과 같이 설치할 수 있다.

1
2
brew update && \
brew install watchman


5. 프로젝트 설정

1. expo-dev-client 설치

프로젝트 루트 위치에서 다음 명령어를 실행한다.

1
npx expo install expo-dev-client

2. 디바이스에 USB 연결 후 개발자 모드 활성화

  1. iOS 디바이스에 USB를 연결한다. 디바이스의 잠금을 푼 후 신뢰가 뜰 경우 클릭한다.
  2. Xcode를 열고, 메뉴바에 Window > Device and Simulators 를 선택한다.
  3. iOS 디바이스에서 Settings > Privacy & Security를 열고, Developer Mode에 접근한다.
  4. Developer Mode를 클릭 한 후 Restart 버튼을 클릭한다.
  5. 디바이스가 재시작한 후 Xcode를 확인해보면 iPhone에 연결된 것을 볼 수 있다.

3. 프로젝트를 디바이스에 실행

  1. Xcode에서 ios/<yourproject>.xcworkspace 을 연다. 만약 ios 폴더가 존재하지 않을 경우 npx expo prebuild -p ios 를 실행한다.
  2. Xcode에서 첫 번째로 선택한 프로젝트에서 TARGETS의 Signing & Capabilities로 이동한다.
  3. Automatically manage signing 을 선택하고 Add Account 를 클릭하여 Apple Developer 계정을 연동한다.
  4. Team을 등록한 계정의 팀으로 설정한다.
  5. 프로젝트 루트에 있는 app.jsonios.bundleIdentifier 를 추가하여 Xcode가 앱 서명 단계에 대한 프로비저닝 프로필을 생성하도록 한다.
  6. 프로젝트 루트에서 다음 명령을 실행한 후, 연결한 iPhone Device를 선택한다.
    1
    
    npx expo run:ios --device
    


개발 시작하기


1. 개발 서버 시작

다음 명령어로 개발 서버를 시작한다.

1
npx expo start

2. 디바이스에서 앱 열기

위 명령어를 실행하면 터미널에서 QR 코드를 확인할 수 있다. 디바이스에서 QR 코드를 스캔하여 앱을 열 수 있다.


파일 구조


  • 기본 프로젝트 파일 구조
    • app : 파일 기반의 앱 네비게이션을 포함한다. app의 파일 구조는 앱의 네비게이션을 결정한다.
    • assets : Android 와 iOS의 앱 아이콘으로 사용되는 adaptive-icon.png 파일이 포함된다. 또한 프로젝트의 스플래시 스크린인 splash.png 와 앱이 브라우저에서 실행되는 경우 favicon.png 가 존재한다.
    • components : 앱의 라이트와 다크 모드의 색상 스키마에서 사용하는 텍스트 요소를 만드는 ThemedText.tsx 와 같은 React Native 컴포넌트들이 존재한다.
    • constants : 앱 전체의 색상 값 목록을 포함하는 Color.ts가 포함되어 있다.
    • hooks : 컴포넌트 간에 공통적인 동작을 공유할 수 있는 React Hooks 가 존재한다. 예를 들어, useThemeColor() 는 현재 테마 기반의 색상을 반환하는 훅이다.
    • scripts : appapp-example 로 이동시키는 rest-project.js 가 포함된다.
    • app.json : 프로젝트 설정이나 앱 설정이 포함된다.
    • package.json : 프로젝트의 의존, 스크립트, 메타데이터를 포함한다.
    • tsconfig.json : TypeScript 규칙을 포함한다.


프로젝트 초기화


다음 명령어로 보일플레이트 코드를 제거할 수 있다.

1
npm run reset-project


개발 도구


Expo CLI


Expo CLI는 개발 도구이며 새로운 프로젝트를 만들면 expo 패키지와 함께 자동으로 설치된다. npx 를 활용하여 사용할 수 있다. 이는 개발을 빠르게 할 수 있도록 설계됐다. 다음 명령어들은 개발하는 동안 사용되는 Expo CLI 이다.

명령어설명
npx expo start개발 서버를 시작한다
npx expo prebuildAndroid와 iOS 빌드
npx expo run:androidAndroid 컴파일
npx expo run:iosiOS 컴파일
npx expo install package-name새로운 라이브러리를 설치하거나 --fix 옵션으로 라이브러리를 검증하고 수정
npx expo lintESLint를 구성하고 설정


EAS CLI


EAS CLI는 Expo 회원으로 로그인하고 빌드, 업데이트, 배포 등 다양한 EAS 서비스로 애플리케이션을 컴파일하는데 사용된다. 또한, 다음 도구들을 사용할 수 있다.

  • 앱스토어에 애플리케이션 배포
  • 개발, 프리뷰, 운영 애플리케이션 생성
  • OTA 업데이트
  • 애플리케이션 인증 정보 관리
  • iOS 기기에 대한 임시 프로비저닝 프로필 생성


Expo Doctor


Expo Doctor는 Expo 프로젝트의 이슈를 진단하는데 사용되는 CLI이다. 다음 명령어를 통해 사용할 수 있다.

1
npx expo-doctor

이 명령은 앱 설정, package.json, 의존 호환성, 설정 파일, 프로젝트의 전반적인 상태 등의 일반적인 문제에 대한 것을 프로젝트 코드베이스로부터 확인하고 분석한다.


Orbit


Orbit은 다음 기능들을 제공한다.

  • 디바이스와 애뮬레이터에 EAS 빌드를 설치하고 실행한다.
  • Android 나 iOS에서 EAS를 통해 설치하고 실행한다.
  • Android 나 iOS에 snake 프로젝트를 실행한다
  • Orbit은 Android .apk 나 iOS .app 등을 지원한다


네비게이션: 파일 기반 라우팅


Expo Router


Expo Router는 React Native와 웹 애플리케이션을 위한 라우팅 프레임워크이다. 이를 통해 앱의 화면 간 탐색을 관리하고 여러 플랫폼(Android, iOS 및 웹)에서 동일한 구성 요소를 사용할 수 있다. 앱에서 라우팅 하기 위해 파일 기반의 방식을 사용한다. 또한 네이티브 네비게이션 기능을 제공하며 React Navigation을 기반으로 구축되었다.


app directory


app 디렉터리에 추가한 파일은 네이티브 앱에 라우팅되고, 웹에서도 동일한 경로의 URL에 반영된다.


route 생성


app 디렉터리에 index.tsx 파일을 포함하는 파일이나 중첩 디렉토리를 추가하여 경로를 생성한다.

앱의 초기 경로를 만들려면 다음과 같이 index.tsx를 앱 디렉터리에 추가하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import {View, Text, StyleSheet} from 'react-native';  
  
export default function HomeScreen() {  
  return (  
    <View style={styles.container}>  
      <Text>Home Screen</Text>
    </View>
    )
}  
  
const styles = StyleSheet.create({  
  container: {  
    flex: 1,  
    justifyContent: 'center',  
    alignItems: 'center',  
  }  
});
  • app/index.tsx 파일은 / 경로에 라우팅된다.


파일명 컨벤션


파일 기반 인덱스는 상위 디렉터리에 라우팅되고 경로 세그먼트를 추가하지 않는다. app/settings/index.tsx 로 파일 구조를 구성할 경우, 해당 파일은 /settings 로 라우팅된다.

  • app
    • index.tsx(matches ‘/’)
    • settings
      • index.tsx (matches ‘/settings’)


_layout 파일


레이아웃 파일들은 헤더, 탭 바와 같은 공유 UI 요소를 서로 다른 경로 간에 유지되도록 하는데 사용된다.

프로젝트를 생성하면 기본적으로 app 디렉터리에 루트 레이아웃 파일이 포함된다(app/_layout).

  • app
    • index.tsx (matches ‘/’)
    • _layout (Root layout)


Root layout


React Native 프로젝트는 싱글 루트 컴포넌트(App.js 나 index.js)로 구성된다. 마찬가지로 app 디렉터리의 레이아웃 파일(_layout.tsx)은 싱글 루트 컴포넌트로 간주된다.

다중 라우팅에서는 Expo Router인 루트 레이아웃 파일은 global providers, themes, styles을 주입하거나, assets와 fonts가 로드될 때 까지 splash screen 렌더링을 지연하거나, 앱의 루트 네비게이션 구조를 정의하는 등 여러 경로 간에 UI를 공유하는 데 사용된다.

다음 코드는 RootLayout 이라는 기본 React 구성 요소로 구성된다.

1
2
3
4
5
export default function RootLayout() {  
  return (
	  // ...
  )  
};

Expo Router를 사용하면 app/_layout.tsx 내부에 정의된 React providers에 앱의 모든 경로에서 접근할 수 있다. 성능을 개선하고 렌더링 횟수를 줄이려면 필요한 경로에만 사용되도록 해야 한다.


Stack navigator


Stack navigator는 앱에서 다른 경로들을 탐색하는 패턴이다. 화면 간 전환 및 탐색 기록 관리가 가능하다. 이는 웹 브라우저에서 탐색 상태를 처리하는 방식과 개념적으로 유사하다.

/details 경로는 추가하려면, details.tsx 파일을 생성하면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { View, Text, StyleSheet } from 'react-native';

export default function DetailsScreen() {
  return (
    <View style={styles.container}>
      <Text>Details</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

파일을 생성한 후에 다음과 같이 파일을 구성한다.

  • app
    • index.tsx
    • details.tsx
    • _layout


//details 경로를 탐색할 수 있도록 다음과 같이 레이아웃 파일을 수정한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Stack } from 'expo-router';

export default function RootLayout() {
  return (
    <Stack
      screenOptions={{
        headerStyle: {
          backgroundColor: '#f4511e',
        },
        headerTintColor: '#fff',
        headerTitleStyle: {
          fontWeight: 'bold',
        },
      }}>
      <Stack.Screen name="index" />
      <Stack.Screen name="details" />
    </Stack>
  );
}


This post is licensed under CC BY 4.0 by the author.