TikTok Clone 프로젝트의 멀티 모듈 아키텍처 구조와 Melos 기반 모노레포 관리 가이드
🏗️ 아키텍처 개요
이 프로젝트는 기능 기반 모듈화 아키텍처와 Melos 모노레포 관리를 사용하여 확장 가능하고 유지보수 가능한 구조를 구축합니다.
핵심 원칙
- 독립적인 기능 모듈: 각 기능은 자체
pubspec.yaml을 가진 별도의 Flutter 패키지
- 공유 디자인 시스템: 중앙화된 디자인 토큰으로 일관성 유지
- 명확한 의존성 방향: 기능 → 공통 모듈 (역방향 의존성 없음)
- 모노레포 관리: Melos를 통한 통합 패키지 관리
📁 프로젝트 구조
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| tiktok/ # 루트 모노레포 ├── melos.yaml # Melos 설정 파일 ├── pubspec.yaml # 루트 앱 의존성 ├── lib/ │ └── main.dart # 앱 진입점 (오케스트레이션) │ ├── common/ # 공유 모듈 │ └── design_system/ # 디자인 토큰 패키지 │ ├── pubspec.yaml # publish_to: 'none' │ └── lib/ │ ├── design_system.dart │ ├── sizes.dart # Sizes.size16, size20 등 │ └── gaps.dart # Gaps.v20, h16 등 │ └── features/ # 기능 모듈 ├── authentication/ # 인증 기능 │ ├── pubspec.yaml # feature_authentication │ └── lib/ │ ├── screens/ # SignUpScreen, LoginScreen 등 │ └── widgets/ # AuthButton, FormButton 등 │ └── onboarding/ # 온보딩 기능 ├── pubspec.yaml # feature_onboarding └── lib/ └── screens/ # InterestsScreen 등
|
🔗 의존성 구조
의존성 방향
1 2 3 4 5
| 메인 앱 (tiktok) ↓ 기능 모듈 (features/*) ↓ 공통 모듈 (common/design_system)
|
루트 앱 (pubspec.yaml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| name: tiktok publish_to: 'none'
dependencies: design_system: path: common/design_system
feature_authentication: path: features/authentication feature_onboarding: path: features/onboarding
dev_dependencies: melos: 6.3.3
|
기능 모듈 (features/authentication/pubspec.yaml)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| name: feature_authentication publish_to: 'none'
dependencies: flutter: sdk: flutter
font_awesome_flutter: 10.9.1
design_system: path: ../../common/design_system
feature_onboarding: path: ../onboarding
|
디자인 시스템 (common/design_system/pubspec.yaml)
1 2 3 4 5 6 7
| name: design_system publish_to: 'none'
dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.8
|
중요: 디자인 시스템은 다른 모듈에 의존하지 않음 (최하위 레이어)
🛠️ Melos 설정
melos.yaml
1 2 3 4 5 6 7 8 9
| name: Tiktok
packages: - common/** - features/**
scripts: analyze: exec: dart analyze .
|
Melos 명령어
1 2 3 4 5 6 7 8 9 10
| melos bootstrap
flutter pub get
melos run analyze
melos exec --scope="feature_authentication" -- flutter test
|
📦 디자인 시스템 사용법
Import
1
| import 'package:design_system/design_system.dart';
|
간격 (Gaps)
1 2 3 4 5 6 7 8 9
| Gaps.v5 Gaps.v10 Gaps.v20 Gaps.v32
Gaps.h5 Gaps.h16
|
크기 (Sizes)
1 2 3 4 5 6 7 8 9
| Sizes.size16 Sizes.size20 Sizes.size28
padding: EdgeInsets.all(Sizes.size16) width: Sizes.size48 height: Sizes.size96
|
색상
1 2 3
| Theme.of(context).primaryColor Theme.of(context).scaffoldBackgroundColor
|
절대 금지: 하드코딩된 값 사용
1 2 3 4 5
| ❌ padding: EdgeInsets.all(16) ✅ padding: EdgeInsets.all(Sizes.size16)
❌ SizedBox(height: 20) ✅ Gaps.v20
|
🆕 새로운 기능 모듈 추가하기
1. 기능 모듈 생성
1 2
| cd features flutter create --template=package feature_[name]
|
2. 모듈 구조 설정
1 2 3 4 5
| features/[feature_name]/ ├── lib/ │ ├── screens/ # 전체 페이지 스크린 │ └── widgets/ # 재사용 가능한 컴포넌트 └── pubspec.yaml
|
3. pubspec.yaml 설정
1 2 3 4 5 6 7 8 9 10 11 12
| name: feature_[name] publish_to: 'none'
dependencies: flutter: sdk: flutter
design_system: path: ../../common/design_system
|
4. 루트 pubspec.yaml에 등록
1 2 3
| dependencies: feature_[name]: path: features/[name]
|
5. 의존성 업데이트
🔄 기존 모듈 구조
Authentication 모듈
경로: features/authentication/
화면:
SignUpScreen - 회원가입 진입
LoginScreen - 로그인 진입
UsernameScreen - 사용자명 입력
EmailScreen - 이메일 입력
PasswordScreen - 비밀번호 입력
BirthdayScreen - 생년월일 입력
LoginFormScreen - 로그인 폼
위젯:
AuthButton - 소셜 인증 버튼
FormButton - 폼 제출 버튼
의존성:
design_system (간격, 크기)
font_awesome_flutter (아이콘)
feature_onboarding (회원가입 완료 후 이동)
Onboarding 모듈
경로: features/onboarding/
화면:
의존성:
🎯 네비게이션 패턴
현재 명령형 네비게이션 사용 (Named routes 미설정):
1 2 3 4 5 6 7 8 9 10 11 12
| Navigator.of(context).push( MaterialPageRoute( builder: (_) => const InterestsScreen(), ), );
Navigator.of(context).pushAndRemoveUntil( MaterialPageRoute(builder: (_) => const InterestsScreen()), (route) => false, );
|
Import 예시:
1 2
| import 'package:feature_onboarding/screens/interests_screen.dart';
|
✅ 개발 가이드라인
DO ✅
디자인 시스템 사용
1 2 3
| import 'package:design_system/design_system.dart'; padding: EdgeInsets.all(Sizes.size16) Gaps.v20
|
명확한 모듈 분리
- 각 기능은 독립적인 패키지
screens/, widgets/ 디렉토리 구조 유지
상대 경로 의존성
1 2
| design_system: path: ../../common/design_system
|
publish_to: ‘none’
DON’T ❌
하드코딩된 값 사용 금지
1 2
| ❌ padding: EdgeInsets.all(16) ❌ SizedBox(height: 20)
|
역방향 의존성 생성 금지
1 2
| ❌ design_system → feature_authentication ✅ feature_authentication → design_system
|
기능 간 직접 의존성 최소화
🧪 테스트 및 분석
전체 프로젝트 분석
1 2 3
| melos run analyze
dart analyze .
|
개별 모듈 테스트
1 2
| cd features/authentication flutter test
|
앱 실행
🚀 주요 이점
1. 독립성
- 각 기능 모듈은 독립적으로 개발/테스트 가능
- 다른 기능에 영향 없이 수정 가능
2. 재사용성
- 디자인 시스템을 통한 일관된 UI
- 위젯 재사용으로 중복 코드 최소화
3. 확장성
- 새로운 기능 추가 시 기존 코드 영향 최소화
- 모노레포 구조로 통합 관리 용이
4. 유지보수성
- 명확한 책임 분리
- 의존성 방향이 명확하여 리팩토링 안전
🔍 트러블슈팅
의존성 오류
1 2 3
| flutter clean flutter pub get
|
모듈 인식 안 됨
Import 오류
1 2 3 4 5 6
| import 'package:design_system/design_system.dart'; import 'package:feature_authentication/screens/login_screen.dart';
❌ import '../../common/design_system/lib/gaps.dart';
|
📚 관련 문서
- Melos 공식 문서
- Flutter 패키지 개발:
flutter create --template=package