1. 모노레포 전체 구조
projects/
├── apps/
│ ├── fe/ # 프론트엔드 (React + Vite)
│ └── be/ # 백엔드 (NestJS)
├── packages/
│ └── shared/ # 공통 로직 (타입, 유틸, 상수)
├── package.json
└── turbo.json
역할:
apps/: 실행 가능한 애플리케이션
packages/: 앱 간 공유하는 코드
2. 프론트엔드 디렉토리 구조
src/
├── assets/ # 이미지, 폰트 등 정적 파일
├── apis/ # API 통신 로직
├── features/[domain]/ # 도메인별 기능 모듈
│ ├── pages/
│ │ ├── my-page.tsx
│ │ └── follow.tsx
│ ├── components/
│ │ ├── common/ # 해당 도메인 내 공통 컴포넌트
│ │ └── [page]/ # 특정 페이지 전용 컴포넌트
│ ├── lib/
│ │ ├── hooks/
│ │ └── utils/
│ └── types/
├── lib/ # 전역 유틸리티
│ ├── hooks/
│ ├── utils/
│ └── stores/
├── constants/ # 상수 정의 (env, site-url 등)
├── types/ # 전역 타입 정의
├── app.tsx
└── main.tsx
__test__/ # src 구조를 따름
2.1 디렉토리 역할
| 디렉토리 |
역할 |
예시 |
assets/ |
정적 파일 |
이미지, 폰트, 아이콘 |
apis/ |
API 호출 함수 |
getUserProfile() |
features/ |
도메인별 기능 모듈 |
my-page, battle, learning |
lib/ |
전역 유틸리티 |
공통 hooks, utils, stores |
constants/ |
상수 |
환경변수, URL, 매직넘버 |
types/ |
전역 타입 |
앱 전체에서 사용하는 타입 |
2.2 features 내부 구조
| 디렉토리 |
역할 |
pages/ |
라우트와 1:1 매칭되는 페이지 컴포넌트 |
components/common/ |
해당 도메인 여러 페이지에서 사용하는 컴포넌트 |
components/[page]/ |
특정 페이지에서만 사용하는 컴포넌트 |
lib/hooks/ |
해당 도메인 전용 커스텀 훅 |
lib/utils/ |
해당 도메인 전용 유틸 함수 |
types/ |
해당 도메인 전용 타입 |
2.3 전역 vs 도메인별 배치 기준
| 사용 범위 |
배치 위치 |
| 2개 이상 도메인에서 사용 |
src/lib/, src/types/, src/constants/ |
| 단일 도메인에서만 사용 |
features/[domain]/lib/, features/[domain]/types/ |
3. 백엔드 디렉토리 구조
src/
├── main.ts
├── app.module.ts
├── [domain]/ # 도메인별 모듈 (auth, users, speech 등)
│ ├── [domain].module.ts
│ ├── [domain].service.ts
│ ├── [domain].controller.ts
│ ├── [domain].repository.ts
│ ├── types/ # 외부 API 응답 타입 등
│ └── dto/
└── common/ # 공통 인프라
├── filters/
├── interceptors/
├── guards/
└── decorators/
__tests__/ # src 구조를 따름
├── [domain]/
│ ├── domain.service.spec.ts
│ └── domain.controller.spec.ts
├── common/
└── e2e/
3.1 디렉토리 역할