[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -2,209 +2,217 @@
|
||||
id: wiki-2026-0508-turborepo
|
||||
title: Turborepo
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: []
|
||||
aliases: [turbo, Turbo Build]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.92
|
||||
tags: [auto-consolidated, technical-documentation]
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [monorepo, build-tool, vercel, turborepo]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-08
|
||||
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: turborepo-2
|
||||
---
|
||||
|
||||
# [[Turborepo 기반 모노레포 워크플로우|Turborepo 기반 모노레포 워크플로우]]
|
||||
# Turborepo
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
> Turborepo 기반 모노레포 워크플로우는 여러 패키지와 애플리케이션을 단일 저장소에서 효율적으로 관리하기 위해 린팅([[ESLint|ESLint]]) 및 포매팅([[Prettier|Prettier]]) 설정의 중복을 줄이고 실행 속도를 최적화하는 개발 프로세스입니다 [1], [2], [3]. 중앙 집중식 설정 패키지와 루트 오케스트레이션(Root Orchestration) 구성을 활용해 각 패키지의 자율성을 보장하면서도 변경된 파일에 대한 부분 검사와 Turborepo의 캐싱 이점을 극대화합니다 [4], [5], [6].
|
||||
## 매 한 줄
|
||||
> **"매 monorepo 의 incremental task runner — 매 task graph + cache 가 매 핵심"**. 2026 현재 Turborepo 2.x — Rust core, remote cache (Vercel), task pipelining, package-based monorepo. 매 Nx 의 lighter alternative.
|
||||
|
||||
---
|
||||
## 매 핵심
|
||||
|
||||
> Turborepo 모노레포 환경에서 [[ESLint|ESLint]], Prettier, [[lint-staged|lint-staged]]를 효율적으로 관리하기 위한 구성 방법입니다 [1]. 여러 패키지에 분산된 중복 설정과 규칙의 불일치 문제를 해결하기 위해 고안되었습니다 [1, 2]. 중앙 집중식 설정 패키지와 루트 오케스트레이션(Root Orchestration)을 결합하여, 각 패키지의 규칙을 존중하면서도 빠르고 확장 가능한 린팅 환경을 제공합니다 [3, 4].
|
||||
### 매 build blocks
|
||||
- **`turbo.json`**: 매 task pipeline 정의.
|
||||
- **`pnpm` workspaces** (또는 npm/yarn): 매 package graph.
|
||||
- **Local cache**: `.turbo/` — content-addressed.
|
||||
- **Remote cache**: Vercel / 자체 S3 — team 간 share.
|
||||
|
||||
---
|
||||
### 매 task graph
|
||||
- 매 task 는 `^build` (dependencies first) 또는 `build` (current package).
|
||||
- 매 input/output 명시 → cache hash.
|
||||
- 매 변경 없으면 **FULL TURBO** (cache hit) — 0ms.
|
||||
|
||||
> Turborepo는 여러 애플리케이션과 라이브러리 패키지를 하나의 저장소에서 관리하는 모노레포([[Monorepo|Monorepo]]) 환경을 위한 빌드 도구입니다 [1, 2]. 작업 결과를 저장하고 재사용하는 캐싱(Caching) 기능을 지원하여 개발 워크플로우와 커밋 속도를 크게 향상시킵니다 [3, 4]. Nx, Bazel, Lerna 등과 함께 대표적인 모노레포 관리 솔루션 중 하나로 꼽힙니다 [5].
|
||||
### 매 응용
|
||||
1. Next.js + multiple apps 의 monorepo.
|
||||
2. Shared `ui` / `config` / `types` packages.
|
||||
3. CI 의 affected-only build.
|
||||
|
||||
---
|
||||
## 💻 패턴
|
||||
|
||||
> Turborepo를 활용한 모노레포([[Monorepo|Monorepo]]) 환경에서 다중 애플리케이션(Next.js 등) 및 공유 라이브러리의 린팅(ESLint)과 포매팅([[Prettier|Prettier]])을 효율적으로 통합 관리하는 아키텍처에 대한 내용입니다. 중앙 집중식 설정 패키지와 루트 오케스트레이션(Root Orchestration) 기법을 도입함으로써, 패키지별 설정 중복을 방지하고 각 프로젝트의 자율성을 보장하면서도 일관되고 빠른 코드 품질 관리를 달성할 수 있습니다.
|
||||
|
||||
---
|
||||
|
||||
> 대규모 모노레포(Turborepo) 환경에서는 여러 패키지가 혼재하여 린트([[ESLint|ESLint]], Prettier) 설정이 중복되고 일관성이 떨어지며 모노레포 루트에서 `lint-staged`를 실행하기 까다로운 문제가 발생합니다 [1-3]. 이를 해결하기 위해 중앙 집중식 설정 패키지를 구성하고, 모노레포 루트에서 파일 패턴을 기반으로 적절한 프리셋을 매핑하는 오케스트레이션 구성을 도입합니다 [3, 4]. 이 아키텍처는 패키지별 자율성을 유지하면서도 [[Husky|Husky]] 및 lint-staged와 결합하여 변경된 파일만 효율적으로 검사할 수 있도록 지원합니다 [5, 6].
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
- **기존 모노레포 환경의 한계:** 여러 [[Next.js|Next.js]] 애플리케이션과 공유 라이브러리를 포함하는 대규모 모노레포에서는 패키지마다 `.eslintrc.json` 및 관련 설정 파일이 중복되는 유지보수 문제가 발생합니다 [7]. 특히 모노레포 루트(Root) 레벨에서 `[[lint-staged|lint-staged]]`를 실행할 때, 각 패키지에 맞는 린팅 규칙을 개별적으로 존중하도록 구성하는 것이 매우 까다롭습니다 [7].
|
||||
- **중앙 집중식 설정 패키지 도입:** 문제를 해결하기 위해 `@repo/eslint-config`와 같은 공통 내부 패키지를 생성하여 기본(Base), Next.js, 비-React 라이브러리용 프리셋(Preset) 구성을 만듭니다 [8]. 각 패키지는 이 프리셋을 임포트하여 단일 진실 공급원([[Single_Source_of_Truth|Single Source of Truth]])을 따르는 동시에, 필요시 패키지별 자율적인 오버라이드(override)를 적용할 수 있습니다 [4].
|
||||
- **루트 오케스트레이션 설정 (Root Orchestration Config):** 모노레포 루트에 위치한 `eslint.config.mjs` 파일에서 글로브(glob) 파일 패턴을 바탕으로 적절한 패키지 규칙에 매핑합니다 [5]. 이를 통해 전역 규칙을 적용하면서도 비-React 패키지와 Next.js 패키지의 경계를 명확하게 존중할 수 있습니다 [5].
|
||||
- **[[Husky|Husky]]와 Lint-staged의 효율적 연동:** 루트 오케스트레이션 구성이 마련되면 Husky의 pre-commit 훅을 통해 루트의 `lint-staged`가 실행됩니다 [6]. 이 과정에서 오직 변경된 파일만 식별되며, 루트 설정의 매핑에 따라 개별 패키지 룰에 맞게 빠르고 정확하게 린팅됩니다 [6], [9].
|
||||
- **Turborepo 캐싱 통합:** 공통 ESLint 설정 패키지를 `turbo.json`의 전역 의존성(global dependency)으로 추가함으로써 설정이 변경될 때 모든 패키지의 캐시가 적절히 무효화(invalidate) 되도록 구성합니다 [6]. 이는 결과적으로 린트 결과를 효과적으로 캐싱하여 작업 속도를 비약적으로 향상시킵니다 [6], [9].
|
||||
|
||||
---
|
||||
|
||||
- **중앙 집중식 구성 패키지 구축:** 모노레포 내에 별도의 설정 패키지(예: `@repo/eslint-config`)를 생성하여 Base, [[Next.js|Next.js]], Library용으로 조합 가능한 프리셋(preset) 설정을 제공합니다 [5, 6]. 이 패키지는 ESLint 9의 평면 구성(flat config) 형식을 사용하며, 전체 모노레포의 린팅 규칙을 제어하는 단일 진실 공급원([[Single_Source_of_Truth|Single Source of Truth]]) 역할을 합니다 [5, 7].
|
||||
- **패키지별 자율성 보장:** 개별 패키지에는 최소한의 `eslint.config.mjs` 파일만 남겨두고 중앙 패키지의 프리셋을 임포트하여 사용합니다 [7]. 이를 통해 전체 코어 규칙을 일관되게 관리하면서도, 필요한 경우 특정 패키지에서 개별적인 규칙 오버라이드(override)를 수행할 수 있는 자율성을 얻을 수 있습니다 [7, 8].
|
||||
- **루트 오케스트레이션 (Root Orchestration):** 모노레포 루트에 위치한 `eslint.config.mjs`에서 파일 패턴(glob 패턴)을 활용해 각 패키지를 적절한 설정에 매핑합니다 [9]. 이는 `lint-staged`와 [[Husky|Husky]] 같은 도구가 모노레포 루트에서 실행될 때 각 패키지의 경계와 고유 린팅 규칙을 정확하게 준수하도록 보장하는 핵심 설정입니다 [4, 9].
|
||||
- **Husky 및 lint-staged 통합:** 루트 `package.json` 파일과 Husky의 `pre-commit` 훅을 연동하여, 코드가 커밋될 때 루트 설정에 따라 변경된 파일만 효율적으로 린팅하도록 구성합니다 [10].
|
||||
- **Turborepo 캐시 무효화 적용:** `turbo.json` 설정 내 전역 의존성(`globalDependencies`)에 ESLint 설정 패키지를 등록합니다 [10]. 이를 통해 중앙의 린팅 설정이 변경될 때마다 Turborepo가 모든 관련 패키지의 캐시를 정확히 무효화(invalidate)하도록 처리합니다 [10].
|
||||
|
||||
---
|
||||
|
||||
- **복잡한 모노레포 환경 관리**: Turborepo는 다수의 [[Next.js|Next.js]] 애플리케이션, 공유 컴포넌트 및 유틸리티를 포함하는 라이브러리 패키지, API 클라이언트와 같은 공유 코드를 아우르는 대규모 모노레포 구조를 효과적으로 관리할 수 있게 해줍니다 [2, 6].
|
||||
- **캐싱(Caching)을 통한 성능 최적화**: Turborepo의 가장 큰 특징 중 하나는 여러 번의 실행에 걸쳐 린트(Lint) 등의 작업 결과를 캐싱하여 재사용한다는 점입니다 [4]. `turbo.json` 설정 파일에 글로벌 의존성을 추가하면, 해당 설정이 변경될 때만 Turborepo가 전체 패키지의 캐시를 무효화(invalidate)하여 불필요한 반복 작업을 방지합니다 [7].
|
||||
- **개발 도구와의 중앙 집중식 통합**: Turborepo 환경에서 [[ESLint|ESLint]], Prettier, lint-staged, [[Husky|Husky]] 등을 설정할 때, 루트(root) 오케스트레이션과 중앙 집중식 구성 패키지를 활용하면 설정 파일의 중복을 막을 수 있습니다 [1, 8]. 이를 통해 각 패키지의 자율성을 존중하면서도 규칙의 단일 진실 공급원([[Single_Source_of_Truth|Single Source of Truth]])을 유지할 수 있으며, 캐싱 기능과 시너지를 내어 빠르고 유지보수하기 쉬운 환경을 구축할 수 있습니다 [3, 4, 9, 10].
|
||||
|
||||
---
|
||||
|
||||
* **기존 모노레포 관리의 문제점**
|
||||
여러 애플리케이션(Next.js 등)과 공유 라이브러리를 포함하는 대규모 모노레포 구조에서는 `.eslintrc.json` 및 `.eslintignore`와 같은 설정 파일이 각 패키지마다 중복 생성되는 문제가 흔히 발생합니다 [1, 2]. 이로 인해 구성의 일관성이 무너지고 전역적으로 규칙을 업데이트하기가 어려워지며, 특히 모노레포 루트(Root)에서 `[[lint-staged|lint-staged]]`를 실행할 때 각 패키지에 맞는 린팅 규칙을 선별적으로 적용하는 것에 한계가 생깁니다 [2, 3].
|
||||
|
||||
* **중앙 집중식 구성과 루트 오케스트레이션 적용**
|
||||
이러한 문제를 해결하기 위해 3단계로 이루어진 구성 아키텍처를 도입할 수 있습니다.
|
||||
1. **중앙 집중식 ESLint 구성 패키지 생성**: 모노레포 내부에 공통으로 사용할 설정 패키지(예: `@repo/eslint-config`)를 만듭니다. 이 패키지는 Base, Next.js, 외부 라이브러리 전용 등 목적에 맞게 결합 가능한 프리셋(Preset)을 내보냅니다 [4, 5]. 이 공통 패키지에서 Prettier 통합 및 Turborepo 특화 규칙 등을 단일 진실 공급원([[Single_Source_of_Truth|Single Source of Truth]])으로 선언합니다 [3, 5, 6].
|
||||
2. **패키지 레벨 설정의 최소화**: 각 애플리케이션 및 라이브러리 패키지에는 최소한의 `eslint.config.mjs` 파일만 위치시킵니다. 이 파일은 중앙 구성 패키지의 프리셋을 가져와 적용하며, 필요한 경우 특정 패키지만의 예외 규칙을 오버라이드할 수 있어 자율성을 유지합니다 [6].
|
||||
3. **루트 오케스트레이션(Root Orchestration)**: 모노레포 최상위 디렉토리에 파일 패턴을 기반으로 각 패키지에 맞는 구성을 매핑하는 오케스트레이션 파일을 생성합니다. 이를 통해 루트에서 린트를 실행하더라도 파일 경로를 인식하여 올바른 패키지 규칙이 적용됩니다 [7, 8].
|
||||
|
||||
* **Turborepo 캐싱과 [[Husky|Husky]], lint-staged 통합 최적화**
|
||||
루트 오케스트레이션이 완성되면, `Husky`의 pre-commit 훅을 통해 `lint-staged`를 실행할 때 변경된 파일에 대해서만 빠르고 정확한 린팅을 수행할 수 있습니다 [8]. 추가적으로, `turbo.json` 설정 파일에 ESLint 구성 패키지를 글로벌 의존성(global dependency)으로 명시하면, 공통 설정이 변경될 때마다 Turborepo가 모든 패키지의 린트 캐시를 지능적으로 무효화합니다 [8]. 이를 통해 불필요한 중복 검사를 줄이고 린트 캐싱 성능을 극대화하여 전체적인 개발과 커밋 속도를 크게 단축할 수 있습니다 [9-11].
|
||||
|
||||
---
|
||||
|
||||
* **기존 모노레포 린트 관리의 한계:** 대규모 모노레포에는 [[Next.js|Next.js]] 애플리케이션, 라이브러리 패키지, 공유 코드 등이 함께 존재합니다 [2]. 기존에는 패키지마다 `.eslintrc.json` 및 `.eslintignore` 파일이 중복으로 생성되어 유지보수가 어렵고 패키지 간 규칙의 일관성이 떨어지는 문제가 있었습니다 [1, 2]. 특히, 커밋 시 변경된 파일만 검사하기 위해 모노레포 루트에서 `lint-staged`를 실행할 때, 각 패키지의 고유한 린트 규칙을 존중하게 만드는 것이 매우 어려운 과제였습니다 [3].
|
||||
* **중앙 집중식 설정 패키지 도입:** 이 문제를 해결하기 위해 모노레포 내에 전용 설정 패키지(예: `@repo/eslint-config`)를 생성하여 기본(Base), Next.js, 라이브러리용 프리셋 등 조합 가능한 구성(composable preset configurations)을 만듭니다 [3, 7]. 이 중앙 집중식 패키지는 핵심 규칙에 대한 단일 진실 공급원([[Single_Source_of_Truth|Single Source of Truth]]) 역할을 하며, 개별 패키지는 이를 가져와 자율적으로 특정 규칙을 덮어쓸 수 있습니다 [5].
|
||||
* **루트 오케스트레이션 구성(Root Orchestration Config):** 핵심 해결책은 모노레포 루트에 `eslint.config.mjs`를 생성하여 파일 글로브(glob) 패턴을 적절한 린트 구성에 매핑하는 것입니다 [4]. 이 오케스트레이션 파일은 전역적으로 기본 규칙을 적용하면서, 파일 경로에 따라 Next.js 구성이나 라이브러리 구성을 적절히 지휘하여 패키지 경계(package [[Boundaries|Boundaries]])를 존중합니다 [4].
|
||||
* **Husky 및 lint-staged와의 통합:** 커밋을 수행할 때 Husky가 `pre-commit` 훅을 트리거하고 `lint-staged`가 변경된 파일을 식별합니다 [6]. 이때 ESLint는 루트 구성을 기반으로 실행되며, 매핑된 파일 패턴에 따라 각 패키지별 규칙에 맞게 변경된 파일만 린트 검사를 수행합니다 [6].
|
||||
* **Turborepo를 통한 캐싱 최적화:** `turbo.json`에 ESLint 설정 패키지를 전역 종속성으로 추가하여 관리합니다 [6]. 이 설정을 통해 Turborepo는 린트 결과를 실행 간에 캐시하며, 중앙 설정이 변경될 때만 전체 패키지의 캐시를 무효화하므로 검사 속도가 획기적으로 향상됩니다 [6, 8].
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
|
||||
- **정책 변화:** Programming & Language 분야의 자동 자산화 수행.
|
||||
|
||||
---
|
||||
|
||||
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
|
||||
- **정책 변화:** Programming & Language 분야의 자동 자산화 수행.
|
||||
|
||||
---
|
||||
|
||||
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
|
||||
- **정책 변화:** Programming & Language 분야의 자동 자산화 수행.
|
||||
|
||||
---
|
||||
|
||||
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
|
||||
- **정책 변화:** Programming & Language 분야의 자동 자산화 수행.
|
||||
|
||||
---
|
||||
|
||||
- **과거 데이터와의 충돌:** 자동화 엔진에 의해 매핑된 지식으로, 추후 정밀 검증 필요.
|
||||
- **정책 변화:** Programming & Language 분야의 자동 자산화 수행.
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
- **Related Topics:** [[ESLint|ESLint]], Prettier, Husky, [[lint-staged|Lint-staged]]
|
||||
- **Projects/Contexts:** Next.js 애플리케이션, 공유 라이브러리(Library) 환경
|
||||
- **Contradictions/Notes:** 소스에 상충하는 내용이나 관련 정보가 부족합니다. 다만 기존의 중복되고 분산된 설정 방식과, 중앙 집중화 및 루트 오케스트레이션을 도입한 현대적 방식 간의 개발자 경험(DX) 차이가 극적으로 향상됨을 강조합니다 [1], [9].
|
||||
|
||||
---
|
||||
*Last updated: 2026-04-19*
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
- **Related Topics:** [[ESLint|ESLint]], Prettier, lint-staged, [[Husky|Husky]], [[Monorepo|Monorepo]]
|
||||
- **Projects/Contexts:** Turborepo 기반 다중 패키지 프로젝트의 린팅 및 코드 포매팅 자동화 파이프라인 구축
|
||||
- **Contradictions/Notes:** 소스는 ESLint 9의 평면 구성 형식을 기준으로 최적의 환경 구성법을 제안하고 있습니다. 만약 ESLint 8 환경을 이용할 경우에는 `eslint.config.mjs` 대신 `.eslintrc.js`를 사용하고 ES 모듈 대신 CommonJS를 사용해야 하는 등 이전 형식에 맞춘 구조적 조정이 별도로 필요합니다 [11].
|
||||
|
||||
---
|
||||
*Last updated: 2026-04-19*
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
- **Related Topics:** [[Monorepo|Monorepo]], ESLint, [[Prettier|Prettier]]
|
||||
- **Projects/Contexts:** [[Next.js|Next.js]], Husky, [[lint-staged|lint-staged]]
|
||||
- **Contradictions/Notes:** 소스에 관련 정보가 부족합니다.
|
||||
|
||||
---
|
||||
*Last updated: 2026-04-19*
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
- **Related Topics:** 모노레포(Monorepo), ESLint 및 Prettier 통합, lint-staged와 Husky
|
||||
- **Projects/Contexts:** Turborepo 기반의 확장 가능한 프론트엔드 환경 구축 및 중앙 집중형 코드 거버넌스
|
||||
- **Contradictions/Notes:** 모노레포 내 각 패키지마다 독립된 설정과 의존성을 중복해서 유지하는 전통적인 방식에 반대하며, 단일 진실 공급원(Single source of truth) 역할을 하는 전용 설정 패키지를 구축하여 루트에서 일괄 오케스트레이션하는 현대적이고 통합적인 관리 체계를 지향합니다 [2, 6, 10].
|
||||
|
||||
---
|
||||
*Last updated: 2026-04-19*
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
- **Related Topics:** [[ESLint|ESLint]], Prettier, Husky, [[lint-staged|lint-staged]]
|
||||
- **Projects/Contexts:** [[Turborepo를 활용한 다중 애플리케이션 및 라이브러리 통합 관리|Turborepo를 활용한 다중 애플리케이션 및 라이브러리 통합 관리]]
|
||||
- **Contradictions/Notes:** 분산된 린트 구성 방식은 개별 패키지의 제어력을 높여줄 것 같지만 실제로는 심각한 중복과 유지보수 문제를 야기합니다. 소스는 오히려 중앙 집중식 설정과 루트 오케스트레이션을 결합하는 방식이 종속성 중복을 줄이고(package-lock.json 축소), 전체적인 코드 라인 수를 감소시키면서도 패키지별 자율성을 보장할 수 있다고 강조합니다 [5, 8, 9].
|
||||
|
||||
---
|
||||
*Last updated: 2026-04-18*
|
||||
|
||||
---
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(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
|
||||
### `turbo.json` 기본
|
||||
```json
|
||||
{
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"tasks": {
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["src/**", "package.json", "tsconfig.json"],
|
||||
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
|
||||
},
|
||||
"lint": {
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["src/**", ".eslintrc.*"]
|
||||
},
|
||||
"test": {
|
||||
"dependsOn": ["^build"],
|
||||
"inputs": ["src/**", "test/**"],
|
||||
"outputs": ["coverage/**"]
|
||||
},
|
||||
"dev": {
|
||||
"cache": false,
|
||||
"persistent": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준 (Decision Criteria)
|
||||
### Workspace structure
|
||||
```text
|
||||
my-monorepo/
|
||||
├── apps/
|
||||
│ ├── web/ # Next.js
|
||||
│ └── docs/ # Next.js
|
||||
├── packages/
|
||||
│ ├── ui/ # shared components
|
||||
│ ├── config-eslint/
|
||||
│ └── tsconfig/
|
||||
├── package.json
|
||||
├── pnpm-workspace.yaml
|
||||
└── turbo.json
|
||||
```
|
||||
|
||||
**선택 A를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
```yaml
|
||||
# pnpm-workspace.yaml
|
||||
packages:
|
||||
- "apps/*"
|
||||
- "packages/*"
|
||||
```
|
||||
|
||||
**선택 B를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
### Package dependency
|
||||
```json
|
||||
// apps/web/package.json
|
||||
{
|
||||
"name": "web",
|
||||
"dependencies": {
|
||||
"@repo/ui": "workspace:*",
|
||||
"next": "^15.0.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**기본값:**
|
||||
> *(TODO)*
|
||||
### Run tasks
|
||||
```bash
|
||||
# 매 모든 packages 의 build
|
||||
turbo build
|
||||
|
||||
## ❌ 안티패턴 (Anti-Patterns)
|
||||
# 매 specific app + dependencies
|
||||
turbo build --filter=web
|
||||
|
||||
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
|
||||
# 매 affected by changes since main
|
||||
turbo build --filter=...[origin/main]
|
||||
|
||||
# Watch mode (dev)
|
||||
turbo dev
|
||||
```
|
||||
|
||||
### Remote cache (Vercel)
|
||||
```bash
|
||||
turbo login
|
||||
turbo link
|
||||
# 매 이후 매 build 의 cache 가 team 간 share
|
||||
```
|
||||
|
||||
### Self-hosted remote cache
|
||||
```json
|
||||
// turbo.json
|
||||
{
|
||||
"remoteCache": {
|
||||
"signature": true
|
||||
}
|
||||
}
|
||||
```
|
||||
```bash
|
||||
# Env vars
|
||||
TURBO_API=https://my-cache.example.com
|
||||
TURBO_TOKEN=xxx
|
||||
TURBO_TEAM=team_xxx
|
||||
```
|
||||
|
||||
### Generators
|
||||
```bash
|
||||
turbo gen
|
||||
# 매 interactive — new package / new component
|
||||
```
|
||||
|
||||
```typescript
|
||||
// turbo/generators/config.ts
|
||||
import type { PlopTypes } from "@turbo/gen";
|
||||
|
||||
export default function generator(plop: PlopTypes.NodePlopAPI) {
|
||||
plop.setGenerator("package", {
|
||||
description: "New package",
|
||||
prompts: [{ type: "input", name: "name", message: "Package name?" }],
|
||||
actions: [
|
||||
{
|
||||
type: "add",
|
||||
path: "packages/{{name}}/package.json",
|
||||
templateFile: "templates/package.json.hbs",
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### CI optimization
|
||||
```yaml
|
||||
# .github/workflows/ci.yml
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 2 # 매 affected detection
|
||||
- uses: pnpm/action-setup@v3
|
||||
- run: pnpm install
|
||||
- run: pnpm turbo build lint test --filter=...[HEAD^]
|
||||
env:
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 매 JS/TS monorepo + Vercel | Turborepo |
|
||||
| 매 polyglot monorepo | Nx (또는 Bazel) |
|
||||
| 매 small repo (<5 packages) | pnpm workspaces only |
|
||||
| 매 enterprise scale (100+) | Nx 또는 Bazel |
|
||||
|
||||
**기본값**: 매 JS/TS team 은 Turborepo 2 + pnpm.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Monorepo]] · [[Build_Tools]]
|
||||
- 변형: [[Nx]] · [[Bazel]] · [[Lerna]]
|
||||
- 응용: [[Nextjs]] · [[Vercel]] · [[pnpm]]
|
||||
- Adjacent: [[Remote_Cache]] · [[Task_Graph]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: 매 turbo.json scaffold, 매 task pipeline debug, 매 cache miss diagnosis.
|
||||
**언제 X**: 매 enterprise polyglot — Nx / Bazel 의 더 적합.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Missing inputs/outputs**: 매 cache 가 stale.
|
||||
- **`cache: false` everywhere**: 매 turbo 의 가치 상실.
|
||||
- **Circular deps**: 매 task graph 가 broken.
|
||||
- **Large `node_modules` in cache outputs**: 매 cache size 폭발.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Turborepo 2.x docs, Vercel, 2026).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — Turborepo 2 with task graph, remote cache, generators |
|
||||
|
||||
Reference in New Issue
Block a user