모두 모이면 즐겁다. 같은 목표를 가진 사람들이 챌린지를 만들고 함께 인증하는 자기계발 서비스입니다. 화면은 Next.js 웹으로 만들고, Expo 앱이 이 웹을 WebView로 띄워 스토어에 배포합니다.
pnpm 워크스페이스 + Turborepo 모노레포입니다.
apps/
├── web/ # @morak/web — Next.js 웹 (모든 화면, BFF)
└── app/ # @morak/app — Expo 앱 껍데기 (WebView + 네이티브 기능)
packages/
└── bridge/ # @morak/bridge — 웹 ↔ 앱 브릿지 메시지 타입 (양쪽이 함께 import)
docs/ # 설계·가이드 문서
| 영역 | 기술 |
|---|---|
| 웹 | Next.js (App Router) + TypeScript |
| 앱 | Expo + react-native-webview |
| 서버 상태 / 클라이언트 상태 | TanStack Query / Zustand |
| API 연동 | Orval (Swagger → 타입·Query 훅·MSW 목 생성) |
| 목 서버 | MSW |
| 폼 | React Hook Form + Zod |
| 디자인 시스템 / 스타일 | JDS (@jects/jds) + Tailwind CSS |
| 모노레포 | pnpm workspace + Turborepo |
| 코드 품질 | ESLint, Prettier, Husky, lint-staged, commitlint |
| 커밋 작성 | commitizen + cz-git (pnpm commit) |
Node.js 22.13 이상(.nvmrc 기준 24)과 pnpm이 필요합니다. pnpm 버전은 루트 package.json의 packageManager를 따릅니다.
corepack enable # pnpm 사용 준비 (최초 1회)
pnpm install
cp apps/web/.env.example apps/web/.env.local
pnpm dev:web # 웹 개발 서버 (localhost:3000)앱 껍데기를 실기기에서 띄우려면:
cp apps/app/.env.example apps/app/.env.local # EXPO_PUBLIC_WEB_URL에 PC의 LAN IP 입력
pnpm dev:app| 명령 | 설명 |
|---|---|
pnpm dev:web / pnpm dev:app |
웹 개발 서버 / Expo 개발 서버 |
pnpm build |
웹 프로덕션 빌드 |
pnpm lint |
전체 패키지 ESLint |
pnpm typecheck |
전체 패키지 타입 검사 |
pnpm format / pnpm format:check |
Prettier 적용 / 검사 |
pnpm api:generate |
OPENAPI_URL의 명세로 웹 API 코드 생성 |
pnpm commit |
커밋 메시지를 선택형으로 작성 |
패키지를 추가할 때는 대상 앱을 지정합니다. 앱(Expo)에는 SDK와 맞는 버전을 고르는 expo install을 씁니다.
pnpm --filter @morak/web add <패키지>
cd apps/app && npx expo install <패키지>app/ # 라우트, 레이아웃, Providers
mocks/ # MSW 핸들러와 워커
shared/
├── api/
│ ├── fetcher.ts # 모든 API 호출이 거치는 fetch 래퍼 (Next /api BFF로 요청)
│ ├── query-client.ts
│ └── generated/ # Orval 생성 코드 (직접 수정 금지)
└── native/ # 앱 껍데기와 통신하는 브릿지 (isApp, sendToApp, onAppMessage)
- 백엔드 Swagger가 나오면
apps/web/.env.local의OPENAPI_URL을 설정합니다. pnpm api:generate로 타입, TanStack Query 훅, MSW 목을 생성합니다.- 백엔드 구현 전에는
NEXT_PUBLIC_API_MOCKING=enabled로 두고, 생성된 목 핸들러를src/mocks/handlers.ts에 등록해 화면을 개발합니다.
- 웹뷰 앱 가이드: 앱 껍데기(Expo) 구조, 웹뷰 주의사항, 브릿지, 딥링크
Conventional Commits를 따르며, 커밋할 때 commitlint가 자동으로 검사합니다.
형식을 외울 필요 없이 git commit 대신 아래 명령을 쓰면 종류·범위·제목·연결 이슈를 차례로 골라 작성할 수 있습니다.
git add .
pnpm commit<type>(<scope>): <제목>
feat(auth): 로그인 BFF 라우트 추가
fix(feed): 인증 사진 업로드 실패 시 재시도 버튼 표시
| type | 용도 |
|---|---|
feat |
새 기능 |
fix |
버그 수정 |
design |
UI·스타일 변경 |
refactor |
동작 변화 없는 코드 개선 |
perf |
성능 개선 |
test |
테스트 |
docs |
문서 |
style |
포맷팅 등 의미 변화 없는 수정 |
chore |
빌드·설정·패키지 |
ci |
CI 설정 |
revert |
되돌리기 |
main: 배포 브랜치- 작업 브랜치:
<type>/<이슈번호>-<요약>예)feat/12-verification-upload - 작업은 이슈 생성 → 브랜치 → PR 순서로 진행하고, PR 제목도 커밋 규칙을 따릅니다.
- 커밋 전: 변경된 파일에 ESLint(웹), Prettier 자동 적용 (lint-staged)
- 커밋 메시지: commitlint 검사
- PR: GitHub Actions에서 포맷, 린트, 타입(웹·앱·브릿지), 웹 빌드, 커밋 메시지, PR 제목 검사. 통과해야 main에 머지됩니다.