Next.js 웹 앱을 모바일로 전환하기 위해 Expo 공식 튜토리얼(StickerSmash)을 완주했습니다.
웹 개발 경험 기준으로 차이점 위주로 정리합니다.
| 항목 | 값 |
|---|---|
| 기존 스택 | Next.js 14 + TypeScript + Supabase |
| 전환 대상 | iOS 앱 (Expo + React Native) |
| 튜토리얼 | Expo 공식 StickerSmash |
| 챕터 수 | 9개 |
| 소요 시간 | 약 2일 |
npx create-expo-app@latest my-app
cd my-app
npm run reset-project
npx expo start
create-next-app과 거의 동일한 경험입니다. TypeScript, Expo Router, 멀티플랫폼 설정이 한 줄로 완료됩니다.
| 챕터 | 핵심 내용 | 사용 라이브러리 |
|---|---|---|
| 1 | 프로젝트 생성, Expo Go 연결, StyleSheet 기초 | react-native |
| 2 | 파일 기반 라우팅, Stack/Tabs 네비게이션 | expo-router |
| 3 | Image 컴포넌트, Pressable 버튼, 컴포넌트 분리 | expo-image |
| 4 | 기기 갤러리에서 이미지 선택, useState로 상태 관리 | expo-image-picker |
| 5 | Modal로 이모지 피커 구현, FlatList 가로 리스트 | react-native (Modal, FlatList) |
| 6 | 더블탭(크기 변경) + 팬(드래그) 제스처, 스프링 애니메이션 | react-native-gesture-handler, react-native-reanimated |
| 7 | View 캡처 → 기기 갤러리 저장, 권한 요청 | react-native-view-shot, expo-media-library |
| 8 | Platform.OS로 네이티브/웹 분기 처리 | dom-to-image (웹 전용) |
| 9 | StatusBar 테마, 앱 아이콘(1024×1024), 스플래시 스크린 | expo-status-bar, expo-splash-screen |
| 웹 (Next.js) | Expo | 비고 |
|---|---|---|
app/page.tsx → / | app/index.tsx → / | 파일 기반 라우팅 거의 동일 |
app/layout.tsx | app/_layout.tsx | 공통 레이아웃 동일 개념 |
app/not-found.tsx | app/+not-found.tsx | 404 처리 |
| useState, useEffect, useRef | 동일 | React 훅 100% 호환 |
| TypeScript | 동일 | 타입 시스템 그대로 |
onClick | onPress | 이름만 다름 |
| 항목 | 웹 | Expo/RN |
|---|---|---|
| 스타일링 | CSS 파일, className | StyleSheet.create() JS 객체 |
| 기본 태그 | <div>, <span>, <img> | <View>, <Text>, <Image> |
| 리스트 | array.map() | <FlatList> (가상화 내장) |
| 버튼 | <button> | <Pressable> |
| 갤러리 접근 | <input type="file"> | expo-image-picker + 권한 요청 |
| 애니메이션 | CSS transition/animation | Reanimated (useSharedValue + withSpring) |
| 제스처 | mouse/touch 이벤트 직접 처리 | Gesture Handler (Gesture.Tap(), Gesture.Pan()) |
| 플랫폼 분기 | 없음 | Platform.OS로 네이티브/웹 조건부 처리 |
| 파일 저장 | 다운로드 링크 | MediaLibrary.saveToLibraryAsync() + 권한 |
| 패키지 설치 | npm install | npx expo install (SDK 호환 버전 자동 선택) |
| 항목 | 설명 |
|---|---|
| Expo Go 제한 | 네이티브 모듈이 필요한 기능(Google Sign-In 등)은 Expo Go에서 불가. Dev Client 빌드 필요 |
app/ 디렉토리 규칙 | 라우트/레이아웃 파일만 허용. 커스텀 컴포넌트는 components/에 분리 |
collapsable={false} | View 캡처 시 Android에서 최적화로 View가 합쳐지는 것 방지용 |
GestureHandlerRootView | 제스처 사용 시 최상위에 반드시 감싸야 동작 |
| 스플래시 스크린 테스트 | Expo Go에서 불가. 프리뷰/프로덕션 빌드 필요 |
| 순서 | 작업 |
|---|---|
| 1 | 모바일 Google 로그인 검증 (Supabase + @react-native-google-signin/google-signin) |
| 2 | 기존 웹 코드 재사용 범위 판단 (순수 로직 vs UI 레이어) |
| 3 | EAS Build로 실기기 배포 테스트 |