[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -2,85 +2,202 @@
|
||||
id: wiki-2026-0508-enterprise-scale-monorepo-manage
|
||||
title: Enterprise Scale Monorepo Management
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: []
|
||||
aliases: [Monorepo, Polyrepo vs Monorepo, Bazel, Nx, Turborepo]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.99
|
||||
tags: [DevOps, Monorepo, Scalability, SoftwareEngineering]
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [monorepo, build-system, devops, ci-cd, scaling]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-04-20
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
|
||||
tech_stack:
|
||||
language: unspecified
|
||||
framework: unspecified
|
||||
language: typescript
|
||||
framework: nx-turborepo-bazel
|
||||
---
|
||||
|
||||
# [[Enterprise-Scale-Monorepo-Management|Enterprise-Scale-Monorepo-Management]] (엔터프라이즈 모노레포 관리)
|
||||
# Enterprise Scale Monorepo Management
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
> "하나의 거대한 저장소에서 수많은 서비스를 관리하는 지혜." 수백만 줄의 코드와 수천 개의 의존성을 하나의 레포지토리에서 관리하며 터지는 빌드 속도와 협업 비용 문제를 기술적으로 해결하는 기법이다.
|
||||
## 매 한 줄
|
||||
> **"매 single repo, many projects — 매 build graph 의 일관성"**. 매 monorepo 의 핵심은 모든 코드를 하나의 VCS root 안에 두되, 매 build 시스템이 dependency graph 를 이해해서 affected projects 만 build/test 한다는 점. Google (Piper/Bazel), Meta (Buck2), Microsoft (Rush), 그리고 매 OSS 의 Nx/Turborepo 가 이 패러다임을 driving.
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
- **Shared Codebase**: 패키지 간 코드 공유를 극대화하고 라이브러리 버전 파편화 방지.
|
||||
- **Caching & Parallelization**: 변경되지 않은 부분의 빌드/테스트를 건너뛰는 지능형 캐싱 ([[Turborepo|Turborepo]], Nx, Bazel).
|
||||
- **Code Ownership**: 파일 경로나 패키지별로 접근 권한 및 승인 프로세스 정의.
|
||||
- **Atomic Commits**: 한 번의 커밋으로 여러 개의 상호 연동된 패키지를 동시에 업데이트.
|
||||
## 매 핵심
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
- 모노레포는 만능 해결책이 아니다. 적절한 툴링과 자동화가 없으면 체크아웃 속도 저하와 '의존성 지옥'으로 변질된다. 특히 Git LFS나 Partial Clone 같은 고도화된 Git 전략 없이 몸집만 키우면 개발 생산성이 수직 낙하하므로 초기 인프라 설계가 필수적이다.
|
||||
### 매 Monorepo 가치
|
||||
- **Atomic cross-project changes**: 매 API + caller 의 한 PR 안에서 변경.
|
||||
- **Shared tooling**: 매 lint, format, build, test 의 unified config.
|
||||
- **Visibility**: 매 모든 코드 의 grep-able.
|
||||
- **Refactor confidence**: 매 type-checker 가 모든 caller 를 검증.
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
- Related: Micro-[[Frontend|Frontend]]s , CI-CD-Pipelines
|
||||
- Tools: Nx , Bazel-Build-System
|
||||
### 매 도전 과제
|
||||
- **Build time scaling**: 매 naive build 의 N² growth — affected detection 필수.
|
||||
- **VCS performance**: 매 git 의 100GB+ repo 에서 sparse checkout / VFS 필요.
|
||||
- **Permissions**: 매 single repo + multiple teams = CODEOWNERS / branch protection.
|
||||
- **CI cost**: 매 모든 commit 의 모든 project rebuild 의 X — incremental + cache.
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
### 매 도구 선택
|
||||
1. **Nx** (TypeScript-heavy, mid-large): smart caching + computation graph.
|
||||
2. **Turborepo** (Vercel, JS/TS): Rust-based, simple config, remote cache.
|
||||
3. **Bazel** (polyglot, mega-scale): hermetic builds, network-distributed.
|
||||
4. **Pants** (Python-heavy): similar to Bazel, lighter setup.
|
||||
5. **Rush** (.NET / TS): Microsoft's pnpm-based.
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(TODO)*
|
||||
## 💻 패턴
|
||||
|
||||
**언제 쓰면 안 되는가:**
|
||||
- *(TODO)*
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
|
||||
- **정보 상태:** needs_review
|
||||
- **출처 신뢰도:** A
|
||||
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
|
||||
|
||||
## 🧬 중복 검사 (Duplicate Check)
|
||||
|
||||
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
|
||||
- **처리 방식:** UPDATE (자동 정규화)
|
||||
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
|
||||
|
||||
## 🕓 변경 이력 (Changelog)
|
||||
|
||||
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|
||||
|------|-----------|-----------|--------|
|
||||
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
|
||||
|
||||
## 💻 코드 패턴 (Code Patterns)
|
||||
|
||||
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
|
||||
|
||||
```text
|
||||
# TODO
|
||||
### Nx workspace structure
|
||||
```bash
|
||||
my-org/
|
||||
├── nx.json
|
||||
├── package.json
|
||||
├── tsconfig.base.json
|
||||
├── apps/
|
||||
│ ├── web/ # Next.js app
|
||||
│ └── api/ # NestJS API
|
||||
├── libs/
|
||||
│ ├── ui/ # shared React components
|
||||
│ ├── data-access/# API clients
|
||||
│ └── utils/
|
||||
└── tools/
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준 (Decision Criteria)
|
||||
### nx.json with affected + cache
|
||||
```json
|
||||
{
|
||||
"tasksRunnerOptions": {
|
||||
"default": {
|
||||
"runner": "nx-cloud",
|
||||
"options": {
|
||||
"cacheableOperations": ["build", "test", "lint", "e2e"],
|
||||
"accessToken": "${NX_CLOUD_TOKEN}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"targetDefaults": {
|
||||
"build": { "dependsOn": ["^build"], "inputs": ["production", "^production"] },
|
||||
"test": { "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"] }
|
||||
},
|
||||
"namedInputs": {
|
||||
"default": ["{projectRoot}/**/*", "sharedGlobals"],
|
||||
"production": ["default", "!{projectRoot}/**/*.spec.ts", "!{projectRoot}/jest.config.ts"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**선택 A를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
### Affected detection in CI
|
||||
```yaml
|
||||
# .github/workflows/ci.yml
|
||||
jobs:
|
||||
affected:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with: { fetch-depth: 0 }
|
||||
- uses: nrwl/nx-set-shas@v4
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: npx nx affected -t lint test build --parallel=4
|
||||
- run: npx nx affected -t e2e --parallel=1
|
||||
```
|
||||
|
||||
**선택 B를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
### Turborepo pipeline
|
||||
```json
|
||||
// turbo.json
|
||||
{
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"globalDependencies": ["**/.env.*local"],
|
||||
"tasks": {
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
|
||||
},
|
||||
"test": { "dependsOn": ["build"], "outputs": ["coverage/**"] },
|
||||
"lint": {},
|
||||
"dev": { "cache": false, "persistent": true }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**기본값:**
|
||||
> *(TODO)*
|
||||
### Bazel BUILD file (polyglot)
|
||||
```python
|
||||
# libs/ui/BUILD.bazel
|
||||
load("@npm//:defs.bzl", "npm_link_all_packages")
|
||||
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
|
||||
|
||||
## ❌ 안티패턴 (Anti-Patterns)
|
||||
ts_project(
|
||||
name = "ui",
|
||||
srcs = glob(["src/**/*.ts", "src/**/*.tsx"]),
|
||||
declaration = True,
|
||||
tsconfig = "//:tsconfig",
|
||||
deps = [
|
||||
"//libs/utils",
|
||||
"@npm//react",
|
||||
"@npm//@types/react",
|
||||
],
|
||||
visibility = ["//apps:__subpackages__"],
|
||||
)
|
||||
```
|
||||
|
||||
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
|
||||
### CODEOWNERS for team boundaries
|
||||
```
|
||||
# CODEOWNERS
|
||||
/apps/web/ @org/frontend-team
|
||||
/apps/api/ @org/backend-team
|
||||
/libs/ui/ @org/design-system
|
||||
/libs/data-access/ @org/backend-team @org/frontend-team
|
||||
/.github/ @org/platform-team
|
||||
/tools/ @org/platform-team
|
||||
```
|
||||
|
||||
### Remote cache with Turborepo
|
||||
```bash
|
||||
# Self-hosted with turborepo-remote-cache
|
||||
docker run -p 3000:3000 \
|
||||
-e TURBO_TOKEN=secret \
|
||||
-e STORAGE_PROVIDER=s3 \
|
||||
-e STORAGE_PATH=my-bucket \
|
||||
ducktors/turborepo-remote-cache
|
||||
|
||||
# In repo:
|
||||
echo 'TURBO_API=http://cache.internal:3000' > .turbo/config.json
|
||||
echo 'TURBO_TOKEN=secret' >> .turbo/config.json
|
||||
turbo build --remote-only
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| <50 packages, JS/TS only | Turborepo (simplicity) |
|
||||
| 50-500 packages, type-heavy | Nx (project graph + generators) |
|
||||
| Polyglot (Go+Rust+TS+Python) | Bazel (hermeticity) |
|
||||
| Python ML monorepo | Pants v2 |
|
||||
| <10 packages | pnpm workspaces alone |
|
||||
|
||||
**기본값**: 매 TS/JS team 에게 Turborepo 또는 Nx (size dependent).
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Build Systems]] · [[Version Control]]
|
||||
- 변형: [[Polyrepo]] · [[Multi-Repo Federation]]
|
||||
- 응용: [[CI-CD Pipelines]] · [[Code Ownership]]
|
||||
- Adjacent: [[Bazel]] · [[Nx]] · [[Turborepo]] · [[pnpm Workspaces]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: refactoring across packages, generating new lib boilerplate (Nx generator), CODEOWNERS automation, dependency graph 분석.
|
||||
**언제 X**: 매 build cache invalidation logic 의 직접 결정 — Nx/Bazel hash algorithm 신뢰.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Single CI job for entire repo**: 매 affected detection 없이 매 commit 모든 build — 30분+ pipeline.
|
||||
- **No remote cache**: 매 each developer 가 cold rebuild — wasteful.
|
||||
- **Mixing app-specific and lib code**: 매 libs/ 와 apps/ 의 분리 안 함 — circular deps risk.
|
||||
- **Implicit dependencies**: 매 package.json 에 list 안 된 import — Bazel/Nx 가 catch.
|
||||
- **No CODEOWNERS**: 매 review fatigue + ownership 모호.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Nx Cloud docs 2026, Turborepo 2.0, Bazel 7).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — monorepo tooling matrix + Nx/Turbo/Bazel patterns |
|
||||
|
||||
Reference in New Issue
Block a user