[프로젝트 구조] React Native 디렉터리 구조 설계하기

UGangg·4일 전

tryna

목록 보기
8/12

1. React Native 폴더 구조

React Native는 프로젝트의 디렉터리 구조를 강제하지 않음
프로젝트 규모 / 기능 / 팀 협업 방식에 따라 자유롭게 설계 가능

But) Expo Router를 사용하는 경우, 파일 기반 라우팅을 위해 특정 디렉터리 규칙을 따라야 함.

React 웹 vs React Native

구분React (Vite)React Native (Expo)
UI 구성HTML / CSSView / Text / StyleSheet
화면 이동React Router 등Expo Router / React Navigation 등
스타일CSS / TailwindStyleSheet 등
정적 파일public / src/assetsassets 등
폴더 구조자유롭게 구성기본적으로 자유롭게 구성
플랫폼 코드주로 웹iOS / Android 구분 가능

▶ React Native도 React와 동일하게 컴포넌트·기능 중심 구조 사용 가능


2. 폴더 구조 설계 방식

1) Type-based Structure

: 파일의 역할 또는 종류를 기준으로 분리하는 방식

src/
├── components/
├── screens/
├── hooks/
├── services/
├── types/
└── utils/
  • components: UI 컴포넌트
  • screens: 화면 단위 컴포넌트
  • hooks: 커스텀 훅
  • services: API 및 외부 서비스
  • types: TypeScript 타입
  • utils: 공용 유틸리티

장점

  • 구조가 단순하고 이해하기 쉬움
  • 작은 프로젝트에서 파일 탐색 용이

단점

  • 기능이 많아질수록 관련 파일이 여러 폴더에 분산
  • 기능 단위 수정 시 여러 디렉터리를 이동해야 함

2) Feature-based Structure

: 기능을 기준으로 관련 컴포넌트·로직·타입 등을 함께 관리하는 방식

src/
├── features/
│   ├── calendar/
│   │   ├── components/
│   │   ├── hooks/
│   │   └── types/
│   ├── event/
│   │   ├── components/
│   │   ├── hooks/
│   │   └── types/
│   └── settings/
│       ├── components/
│       └── hooks/
└── shared/
    ├── components/
    ├── hooks/
    └── utils/
  • features: 기능별 코드
  • shared: 여러 기능에서 재사용하는 공통 코드

장점

  • 기능 관련 파일을 한곳에서 관리
  • 기능 단위 유지보수 및 확장에 유리
  • 협업 시 담당 영역 구분 용이

단점

  • 초기 디렉터리 설계 필요
  • 공용 코드와 기능 전용 코드의 구분 기준 필요

비교

구분Type-basedFeature-based
분리 기준파일 종류기능
초기 구조단순상대적으로 복잡
기능 확장파일 분산 가능기능별 관리 용이
공용 코드최상위 폴더shared 등 별도 관리
적합한 프로젝트소규모 / 프로토타입기능이 많은 앱 / 협업

▶ Tryna는 기능별 화면이 구분되므로 Feature-based 구조를 우선 검토


3. Expo Router와 폴더 구조

Expo Router: Expo에서 제공하는 파일 기반 라우팅(File-based Routing) 라이브러리
파일과 디렉터리 구조를 기반으로 앱의 화면 경로를 정의

예를 들어:

src/
├── app/
│   ├── _layout.tsx
│   ├── index.tsx
│   ├── calendar.tsx
│   └── settings.tsx
  • index.tsx: 기본 경로 /
  • calendar.tsx: /calendar
  • settings.tsx: /settings
  • _layout.tsx: 공통 레이아웃 및 네비게이션 구성

Expo Router 주요 규칙

  • app/: 화면 경로를 정의하는 디렉터리
  • index.tsx: 해당 디렉터리의 기본 화면 (App.tsx의 역할)
  • _layout.tsx: 화면을 감싸는 레이아웃 및 네비게이터
  • [id].tsx: 동적 경로
  • (tabs)/: URL 경로에 포함되지 않는 Route Group

예시:

src/
└── app/
    ├── _layout.tsx
    ├── index.tsx
    ├── (tabs)/
    │   ├── _layout.tsx
    │   ├── calendar.tsx
    │   └── daily.tsx
    └── event/
        └── [id].tsx

event/[id].tsx → /event/123과 같은 동적 경로 표현 가능

주의) app/ 내부의 파일은 라우팅 대상으로 해석될 수 있으므로, 일반적인 공용 컴포넌트나 유틸리티는 외부에서 관리하는 것이 좋음.

→ app은 라우팅 / features는 기능 구현 / shared는 공용 코드

※ Expo Router를 사용하지 않고 React Navigation을 직접 구성하는 경우에는 app/ 파일 기반 라우팅 규칙이 필요하지 않음.


4. React Native에서 자주 사용하는 디렉터리

폴더역할
app/Expo Router 화면 및 레이아웃
features/기능별 컴포넌트 및 비즈니스 로직
components/공용 UI 컴포넌트
hooks/공용 커스텀 훅
theme/색상·간격·타이포그래피 등 디자인 토큰
assets/이미지·폰트 등 정적 리소스
services/ 또는 apis/API 통신 및 외부 서비스
types/공용 TypeScript 타입
utils/공용 유틸리티 함수
constants/공용 상수

모든 폴더를 처음부터 생성할 필요는 없음.

→ 실제로 사용하는 기능에 맞춰 점진적으로 추가


5. React Native 플랫폼별 파일 관리

React Native는 파일명에 플랫폼 확장자를 사용하여 코드를 구분할 수 있음.

components/
├── DatePicker.ios.tsx
├── DatePicker.android.tsx
└── DatePicker.tsx
  • .ios.tsx: iOS 전용 구현
  • .android.tsx: Android 전용 구현
  • .tsx: 플랫폼별 파일이 없는 경우 사용하는 공통 구현

장점

  • 플랫폼별 UI 또는 네이티브 동작 분리
  • 공통 컴포넌트 인터페이스 유지 가능

But) 플랫폼별 차이가 없는 경우에는 파일을 분리할 필요 없음.

→ 공통 구현을 우선하고, 실제 플랫폼 차이가 발생할 때 분리


6. Tryna 폴더 구조 설계 방향

Tryna는 일정·할 일·설정 등 여러 기능을 제공하며, 공용 UI 컴포넌트를 재사용하는 구조

또한 기존 React 프로젝트에서 구현한 공용 컴포넌트를 React Native로 이식할 예정

→ Feature-based + Shared 구조 채택 검토

구조 예시

tryna/
├── assets/
│   ├── fonts/
│   └── images/
├── src/
│   ├── app/
│   │   ├── _layout.tsx
│   │   ├── index.tsx
│   │   ├── calendar/
│   │   ├── daily/
│   │   └── event/
│   ├── components/
│   │   ├── Todo/
│   │   ├── Button/
│   │   └── BottomSheet/
│   ├── features/
│   │   ├── calendar/
│   │   ├── daily/
│   │   └── event/
│   ├── theme/
│   │   ├── colors.ts
│   │   ├── spacing.ts
│   │   └── typography.ts
│   ├── hooks/
│   ├── apis/
│   ├── types/
│   └── utils/
├── app.json
├── eas.json
├── package.json
└── tsconfig.json

※ Expo Router 사용을 가정한 예시이며, 최종 디렉터리 구조는 아님.

설계 기준

1. 라우팅과 화면 구현 분리

  • app/: 경로 및 화면 연결
  • features/: 실제 기능 및 화면 구현

2. 공용 컴포넌트 관리

  • 여러 기능에서 사용 → components/
  • 특정 기능에서만 사용 → features/{기능}/components/

3. TDS 디자인 토큰 관리

  • theme/: React Native용 TDS 토큰
  • StyleSheet.create()에서 공통으로 참조
  • 기존 CSS 변수 및 Tailwind 클래스는 React Native용 값으로 변환 필요

4. 플랫폼별 코드 최소화

  • 공통 React Native 코드 우선
  • iOS / Android 차이가 발생할 때만 플랫폼별 파일 분리

7. 정리

React Native는 단일 폴더 구조를 강제하지 않으며, 프로젝트 특성에 맞춰 설계 가능

  • Type-based: 파일 종류별 분리 / 구조 단순
  • Feature-based: 기능별 분리 / 확장 및 유지보수에 유리
  • Expo Router: 파일 기반 라우팅 규칙 적용
  • Platform-specific: 필요 시 iOS / Android 코드 분리

▶ Tryna는 Feature-based 구조를 기반으로 공용 컴포넌트와 디자인 토큰을 별도 관리하는 방향 검토

▶ 폴더 구조 확정 → TDS 연결 → 폰트 및 에셋 설정 → 공용 컴포넌트 구현 순서로 진행 예정

참고 자료

profile
프론트 성장기

2개의 댓글

Expo Router를 쓰면 app 폴더가 라우팅 전용이 되니까, 화면 로직은 features 쪽에 두고 app 안의 파일은 해당 화면 컴포넌트를 re-export만 하도록 얇게 유지하면 구조가 덜 섞여요. 그리고 tsconfig paths에 @/features 같은 별칭을 잡아 두면 폴더를 옮길 때 import 수정이 훨씬 줄어들어요.

1개의 답글