--- id: devops-monorepo-patterns title: Monorepo — Turborepo / Nx / pnpm workspaces category: Coding status: draft source_trust_level: B verification_status: conceptual created_at: 2026-05-09 updated_at: 2026-05-09 tags: [devops, monorepo, turborepo, pnpm, vibe-coding] tech_stack: { language: "Node.js / pnpm / Turborepo", applicable_to: ["Web", "Backend"] } applied_in: [] aliases: [workspace, packages, pnpm, turborepo, nx] --- # Monorepo > 한 repo 에 여러 패키지. **공유 코드 + 원자적 변경 + 통합 CI** 의 장점, **빌드 캐시 / 부분 build 가 핵심**. pnpm workspaces + Turborepo / Nx 가 2026 스택. ## 📖 핵심 개념 - Workspace: package.json 의 `workspaces` 또는 pnpm-workspace.yaml. - Task graph: turbo.json 또는 nx.json — 패키지 간 의존성 + 캐시. - 변경 감지: `--filter ...[HEAD~1]` 으로 영향 받는 패키지만. ## 💻 코드 패턴 ### pnpm workspaces ```yaml # pnpm-workspace.yaml packages: - "apps/*" - "packages/*" ``` ``` . ├── apps/ │ ├── web/ # Next.js │ └── mobile/ # React Native ├── packages/ │ ├── ui/ # 공유 UI 컴포넌트 │ ├── shared/ # 공유 로직 │ └── eslint-config/ └── pnpm-workspace.yaml ``` ### 패키지 간 의존 ```json // apps/web/package.json { "dependencies": { "@scope/ui": "workspace:*", "@scope/shared": "workspace:*" } } ``` ### Turborepo task graph ```json // turbo.json { "$schema": "https://turbo.build/schema.json", "tasks": { "build": { "dependsOn": ["^build"], // 의존 패키지 build 먼저 "outputs": ["dist/**", ".next/**"], "inputs": ["src/**", "package.json"] }, "test": { "dependsOn": ["^build"], "outputs": ["coverage/**"] }, "lint": { "dependsOn": [] }, "dev": { "cache": false, "persistent": true } } } ``` ```bash turbo run build # 모든 패키지 build (의존 순서 + 캐시) turbo run test --filter=@scope/ui turbo run build --filter=...[HEAD~1] # 변경 영향만 ``` ### CI — 변경 영향만 build ```yaml - name: Build affected run: pnpm turbo run build --filter=...[origin/main] ``` ### Remote cache — 팀 공유 ```bash turbo login turbo link # 이후 모든 빌드가 Vercel / 자체 cache 와 공유 ``` ### Versioning — Changesets ```bash pnpm changeset # 변경 영향 + 노트 작성 pnpm changeset version # version bump pnpm changeset publish # npm publish (필요시) ``` ## 🤔 의사결정 기준 | 상황 | 도구 | |---|---| | Node.js 다수 패키지 | pnpm + Turborepo | | 다언어 (Go + TS + Python) | Bazel / Nx | | 작은 팀, 2-3 패키지 | pnpm workspaces 만, Turbo 없이 | | Mobile + Web 공유 코드 | Yarn Berry + workspace 또는 pnpm | | OSS 라이브러리 + example | Turborepo example template | | 큰 팀 + 다양 언어 | Nx (graph 시각화 강함) | ## ❌ 안티패턴 - **`npm install` 모든 곳 별도**: deps 중복. workspace 사용. - **버전 hoisting 가정**: pnpm 은 strict — peer dep 명시 필수. - **package 간 circular dep**: 빌드 끝없이 회전. Turbo 가 fail. - **task output 정의 안 함**: 캐시 안 됨. outputs 필드. - **dev 와 build 캐시 같이**: dev 는 `"cache": false`. - **monorepo + git submodule 혼용**: 복잡. 한 모델. - **패키지 이름 namespace 없음**: 충돌. @scope/* 권장. - **CI 가 항상 모든 패키지 build**: 시간 폭증. --filter 로 affected 만. ## 🤖 LLM 활용 힌트 - pnpm workspaces + Turborepo + Changesets 가 표준 스택. - task 마다 inputs / outputs 정확히 → 캐시 효력. ## 🔗 관련 문서 - [[DevOps_Build_Performance]] - [[Android_Modularization]]