[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -2,123 +2,184 @@
|
||||
id: wiki-2026-0508-large-frontend-projects
|
||||
title: Large Frontend Projects
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: []
|
||||
aliases: [Frontend at Scale, Monorepo Frontend, Micro-frontends]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.92
|
||||
tags: [auto-consolidated, technical-documentation]
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [frontend, monorepo, micro-frontends, design-system, turborepo, nx]
|
||||
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
|
||||
tech_stack: { language: ts, framework: turborepo/nx/module-federation }
|
||||
---
|
||||
|
||||
# [[Large Frontend Projects|Large Frontend Projects]]
|
||||
# Large Frontend Projects
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
대규모 프론트엔드 프로젝트는 수백 개의 컴포넌트, 다수의 협업 팀, 동적 상태 관리, 재사용 가능한 디자인 시스템 등이 결합된 엔터프라이즈급 웹 애플리케이션을 의미합니다 [1]. 이러한 프로젝트가 확장됨에 따라 CSS는 단순한 시각적 장식이 아닌 아키텍처의 무결성과 장기적인 유지보수성을 요구하는 엄격한 엔지니어링 영역으로 전환되었습니다 [2]. 전역 네임스페이스 충돌이나 'CSS 비대화(Bloat)'를 방지하기 위해 BEM, [[CSS Modules|CSS Modules]], [[Tailwind CSS|Tailwind CSS]]와 같은 구조화된 스타일링 방법론과 기능 중심(Feature-Driven)의 폴더 구조 도입이 필수적입니다 [1-4].
|
||||
## 매 한 줄
|
||||
> **"매 코드보다 경계 (boundary) 가 먼저"**. Monorepo + design system + 빌드 캐시 + 명확한 ownership, micro-frontend 는 마지막 수단.
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
* **대규모 프로젝트에서의 CSS 엔지니어링 문제**
|
||||
대규모 시스템에서는 CSS가 전역적으로 적용된다는 특성 때문에 예기치 않은 스타일 덮어쓰기(Overrides), 선택자 특이성(Specificity) 충돌, 중복 스타일, 그리고 새로운 개발자의 온보딩 지연 등의 문제가 발생합니다 [1, 5]. 이는 개발 생산성과 장기적인 확장성에 직접적인 악영향을 미치므로, CSS를 단순한 데코레이션 레이어가 아닌 엄격한 엔지니어링 규율로 접근해야 합니다 [2, 5].
|
||||
## 매 핵심
|
||||
### 매 4 축
|
||||
- **Code organization**: monorepo (Turborepo/Nx/pnpm)
|
||||
- **Runtime composition**: SPA / module federation / iframe / SSR composition
|
||||
- **Shared layer**: design system, type, utility, eslint config
|
||||
- **Build / CI**: incremental, remote cache, affected-only test
|
||||
|
||||
* **확장 가능한 폴더 구조 및 아키텍처 ([[Feature-Sliced Design|Feature-Sliced Design]])**
|
||||
대규모 프로젝트가 통제 불능 상태가 되는 것을 막기 위해 명확한 폴더 구조(예: API, Components, Context, Hooks, Pages, Services 등 역할별 분리)가 요구됩니다 [6-11]. 더 나아가 **[[Feature-Sliced Design (FSD)|Feature-Sliced Design (FSD]]** 같은 아키텍처를 도입하여 애플리케이션을 여러 계층으로 나누고 각 계층에 엄격한 의존성 규칙을 적용해 모듈 간 경계를 명확히 설정합니다 [12]. 관련 로직과 CSS 컴포넌트를 기능(Feature) 기반 디렉토리에 함께 배치하면, 특정 기능을 제거할 때 관련 스타일도 자동으로 제거되어 레거시 코드(Ghost styles)가 쌓이는 것을 막을 수 있습니다 [13].
|
||||
### 매 monorepo vs polyrepo
|
||||
| | Monorepo | Polyrepo |
|
||||
|---|---|---|
|
||||
| 공유 코드 | trivial (workspace) | publish/version 지옥 |
|
||||
| 일관성 | 강제 (lint/CI 한곳) | 어려움 |
|
||||
| 빌드 시간 | tooling 필요 | 단순 |
|
||||
| 권한 분리 | CODEOWNERS | repo level |
|
||||
| 권장 | 공유 많음 | 완전 독립 product |
|
||||
|
||||
* **유지보수성을 위한 CSS 구조 설계 방식**
|
||||
대규모 프로젝트에서는 스타일에 캡슐화를 제공하여 전역 네임스페이스 충돌을 방지하는 전략이 필수적입니다 [2].
|
||||
* **[[BEM (Block Element Modifier)|BEM (Block Element Modifier]]:** 컴포넌트를 독립적인 블록(Block), 하위 요소(Element), 상태(Modifier)로 나누어 직관적이고 평면적인(Flat) 클래스 명명 규칙을 적용합니다 [5, 14-16]. 깊은 DOM 중첩에 의존하지 않으므로 결합도가 낮고 컴포넌트 응집도를 높여주지만, 사람의 수동 관리에 의존하므로 실수로 인한 충돌 위험이 존재합니다 [17, 18].
|
||||
* **CSS Modules:** 빌드 타임에 고유한 해시(Hashed) 클래스명을 자동으로 생성하여 완전한 로컬 스코핑(Local scoping)을 보장합니다 [19-22]. 표준 CSS 문법의 장점을 그대로 유지하면서도 개발자의 명명 규칙 기억 부담을 덜어주어 대규모 협업에 유리합니다 [19, 21].
|
||||
* **Tailwind CSS (Utility-First):** 유틸리티 클래스를 사용하여 일관된 디자인 시스템을 강제하고, 사용된 클래스만 빌드에 포함시켜 대규모 프로젝트에서도 CSS 파일 크기가 일정 수준에서 유지되도록(Plateau) 돕습니다 [23, 24]. 다만 HTML 코드가 길어지는 단점이 있어, 최근 엔터프라이즈 팀들은 **레이아웃과 간격에는 Tailwind를 사용하고 복잡한 개별 컴포넌트에는 CSS Modules나 [[SCSS|SCSS]]를 결합하는 하이브리드 전략**을 많이 채택합니다 [25-27].
|
||||
### 매 micro-frontend 트리거
|
||||
- 팀 자율성 > 일관성
|
||||
- 다른 release cadence
|
||||
- 다른 tech stack 강제 (드물어야 함)
|
||||
- 그 외엔 monorepo 가 거의 항상 정답
|
||||
|
||||
* **성능 최적화 및 레이아웃 관리 (Performance & Layout)**
|
||||
대규모 시스템에서는 렌더링 파이프라인 최적화가 필수입니다. 레이아웃 리플로우(Reflows)와 리페인트(Repaints)를 최소화하기 위해 DOM 조작을 일괄 처리하거나 위치/크기 변경 대신 GPU 가속이 가능한 `transform`이나 `opacity` 위주로 애니메이션을 구성해야 합니다 [28-32]. 또한 예측 가능한 UI 구조를 잡기 위해 컴포넌트 내부 정렬에는 **[[Flexbox|Flexbox]](1차원)**를, 전체 페이지 뼈대 및 구조에는 **[[CSS Grid|CSS Grid]](2차원)**를 조합하여 불필요한 래퍼(Wrapper) 요소 중첩을 줄입니다 [33-35].
|
||||
### 매 응용
|
||||
1. Design system 패키지화
|
||||
2. Module federation 으로 런타임 합성
|
||||
3. Turborepo 로 빌드 80% 단축
|
||||
4. Affected-only CI
|
||||
5. Ownership 자동화 (CODEOWNERS + bot)
|
||||
|
||||
---
|
||||
## 💻 패턴
|
||||
|
||||
* **대규모 프로젝트에서의 CSS 아키텍처의 중요성:** 모던 애플리케이션이 엔터프라이즈급으로 확장되면서, 견고한 CSS 아키텍처를 구현하지 못하면 'CSS 비대화(CSS bloat)', 전역 네임스페이스 충돌, 그리고 끝없는 특수성(specificity) 경쟁이 발생합니다 [2]. 이는 애플리케이션의 성능과 개발자의 작업 속도를 심각하게 저하시키므로 예측 가능한 구조 설계가 필수적입니다 [1, 2].
|
||||
* **모듈화 및 캡슐화 전략의 진화:**
|
||||
* **[[BEM (Block Element Modifier)|BEM (Block Element Modifier]]:** 컴포넌트를 독립적이고 재사용 가능한 블록으로 캡슐화하여 평면적인 선택자 계층을 유지하게 합니다 [5, 6]. 하지만 프로젝트가 커질수록 개발자의 수동 관리에 의존하므로 인적 오류나 네이밍 충돌로 인해 코드베이스가 파편화될 취약성이 존재합니다 [7].
|
||||
* **CSS Modules:** 빌드 시점에 고유한 해시 클래스명을 생성하여 스타일을 자동으로 캡슐화합니다 [8-10]. 개발자가 기억에 의존해야 하는 유지보수 부담을 빌드 파이프라인으로 전환시켜 대규모 프로젝트에서 전역 충돌 위험을 제거합니다 [9].
|
||||
* **Tailwind CSS (Utility-first):** 단일 목적의 유틸리티 클래스를 사용하여 인터페이스를 구성합니다 [11]. 프로젝트의 복잡성이 증가하더라도 사용된 클래스만 빌드에 포함되므로 전체 CSS 파일 크기가 일정 수준에서 안정화(plateau)되어 장기적인 번들 크기 최적화에 유리합니다 [11].
|
||||
* **대규모 팀의 하이브리드 전략:** 2025~2026년의 많은 엔터프라이즈 엔지니어링 팀은 레이아웃 및 간격 지정 등 속도와 일관성이 필요한 곳에는 Tailwind CSS를, 복잡한 애니메이션이나 정교한 선택자가 필요한 특정 컴포넌트에는 CSS Modules나 [[SCSS|SCSS]]를 결합하여 사용하는 하이브리드 접근법을 채택하고 있습니다 [12].
|
||||
* **확장 가능한 폴더 구조 및 아키텍처:** [[Next.js|Next.js]]와 같은 대규모 환경을 장기적으로 유지보수하기 위해서는 파일의 유형(컴포넌트, 훅 등)별로 코드를 분리하는 대신 실제 도메인에 기반한 '기능 중심(Feature-Driven 또는 Domain-Driven) 아키텍처'를 채택해야 합니다 [3, 13]. 특정 기능 디렉토리 내에 컴포넌트와 연관된 스타일을 함께 배치(co-locate)하면, 기능이 제거될 때 스타일도 자동 폐기되어 레거시 코드베이스에 '유령 스타일(ghost styles)'이 축적되는 것을 방지할 수 있습니다 [4, 14].
|
||||
* **디자인 시스템과 디자인 토큰 적용:** 다수의 제품 팀과 여러 플랫폼(Web, iOS, Android)에 걸쳐 일관성을 유지하기 위해 디자인 토큰(Global, Alias, Component 계층) 관리가 필요합니다 [15-18]. JSON 포맷 등으로 저장된 토큰 데이터를 변환 도구를 통해 각 플랫폼의 코드로 자동 배포함으로써 '단일 진실 공급원([[Single_Source_of_Truth|Single Source of Truth]])'을 구축하고 인적 오류를 차단할 수 있습니다 [17, 19].
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
No trade-offs available.
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
- **Related Topics:** [[CSS 구조 설계 방식|CSS 구조 설계 방식]], BEM, CSS Modules, Tailwind 전략, [[디자인 시스템 개념|디자인 시스템 개념]], [[Feature-Sliced Design|Feature-Sliced Design]]
|
||||
- **Projects/Contexts:** 대규모 엔터프라이즈 플랫폼 개발, 컴포넌트 기반 프레임워크(React, Vue 등) 환경의 협업
|
||||
- **Contradictions/Notes:** Tailwind CSS의 유틸리티 클래스 방식은 빌드 크기를 최적화하고 일관된 디자인 시스템 적용에 뛰어나 대규모 프로젝트에 이상적이라는 주장이 있습니다 [23, 24]. 그러나 과도하게 길어지는 클래스명으로 인해 HTML 가독성이 떨어지고 컴포넌트 유지보수가 힘들어질 수 있다는 반론도 존재합니다 [36, 37]. 이 때문에 대규모 환경에서는 전역 레이아웃 및 디자인 토큰에는 Tailwind를, 세밀하고 복잡한 스타일 제어에는 CSS Modules 또는 SCSS를 결합하는 하이브리드 방식이 실무적 타협안으로 제시되고 있습니다 [26, 27, 38]. BEM 역시 유용하나 인적 오류로 인한 한계 때문에 점차 CSS Modules나 Zero-runtime [[CSS-in-JS|CSS-in-JS]] 같은 자동화 캡슐화 툴로 대체되는 경향을 보입니다 [18, 21, 39].
|
||||
|
||||
---
|
||||
*Last updated: 2026-04-26*
|
||||
|
||||
---
|
||||
|
||||
- **Related Topics:** [[CSS 구조 설계 방식|CSS 구조 설계 방식]], BEM, CSS Modules, [[Tailwind CSS|Tailwind CSS]], 디자인 시스템(DesignSystem), [[디자인 토큰 (Design Tokens)|디자인 토큰(Design Tokens]], [[기능 중심 아키텍처(Feature-Driven Architecture)|기능 중심 아키텍처(Feature-Driven Architecture]]
|
||||
- **Projects/Contexts:** [[엔터프라이즈급 플랫폼 개발|엔터프라이즈급 플랫폼 개발]], 다수 팀 협업 환경, [[Next.js 기반 대규모 웹 애플리케이션|Next.js 기반 대규모 웹 애플리케이션]]
|
||||
- **Contradictions/Notes:** Tailwind CSS는 재사용성 및 파일 크기 억제에는 훌륭하지만 복잡한 컴포넌트에서 마크업이 매우 장황해지고 클래스 이름이 길어지는 단점이 있습니다 [20, 21]. 반면 CSS Modules는 마크업을 깔끔하게 유지할 수 있지만 스타일을 변경할 때마다 두 개의 파일(컴포넌트와 스타일 파일) 사이를 오가야 하는 문맥 전환(Context switching) 비용이 발생한다는 트레이드오프가 존재합니다 [22].
|
||||
|
||||
---
|
||||
*Last updated: 2026-04-26*
|
||||
|
||||
|
||||
## 📌Brief 대요
|
||||
대규모 프론트엔드 프로젝트(Large Frontend Projects)란 수백 개의 컴포넌트, 동적인 상태 관리, 재사용 가능한 디자인 시스템을 포함하며 다수의 개발 팀이 동시에 참여하는 복잡한 규모의 애플리케이션을 의미합니다 [1]. 이러한 프로젝트에서는 UI를 단순히 "예쁘게" 렌더링하는 것을 넘어, 다수 개발자의 협업과 지속적인 반복 작업, 기술 부채의 축적을 견뎌낼 수 있는 견고한 아키텍처적 무결성과 유지보수성이 핵심 목표가 됩니다 [2]. 따라서 전역 네임스페이스 충돌이나 '스파게티 스타일(spaghetti styles)'과 같은 CSS 비대화(CSS bloat) 현상을 방지하기 위해 BEM, [[CSS Modules|CSS Modules]], [[Tailwind CSS|Tailwind CSS]] 등과 같은 체계적인 CSS 아키텍처와 명확한 폴더 구조 설계가 필수적입니다 [1-4].
|
||||
|
||||
## 🤖 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
|
||||
### Pattern 1: pnpm workspace + Turborepo
|
||||
```yaml
|
||||
# pnpm-workspace.yaml
|
||||
packages:
|
||||
- "apps/*"
|
||||
- "packages/*"
|
||||
```
|
||||
```jsonc
|
||||
// turbo.json
|
||||
{
|
||||
"tasks": {
|
||||
"build": { "dependsOn": ["^build"], "outputs": ["dist/**", ".next/**"] },
|
||||
"test": { "dependsOn": ["^build"], "outputs": [] },
|
||||
"lint": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준 (Decision Criteria)
|
||||
### Pattern 2: Shared package
|
||||
```jsonc
|
||||
// packages/ui/package.json
|
||||
{
|
||||
"name": "@acme/ui",
|
||||
"exports": { ".": "./src/index.ts" },
|
||||
"peerDependencies": { "react": "^18 || ^19" }
|
||||
}
|
||||
```
|
||||
```ts
|
||||
// apps/web uses workspace dep
|
||||
// package.json: "@acme/ui": "workspace:*"
|
||||
import { Button } from "@acme/ui";
|
||||
```
|
||||
|
||||
**선택 A를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
### Pattern 3: Module Federation (Webpack/Rspack)
|
||||
```js
|
||||
new ModuleFederationPlugin({
|
||||
name: "shell",
|
||||
remotes: { checkout: "checkout@https://cdn/checkout/remoteEntry.js" },
|
||||
shared: { react: { singleton: true }, "react-dom": { singleton: true } },
|
||||
});
|
||||
// 런타임에 다른 팀 빌드 import
|
||||
```
|
||||
|
||||
**선택 B를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
### Pattern 4: Affected-only CI (Nx)
|
||||
```yaml
|
||||
- run: npx nx affected -t build test lint --base=origin/main
|
||||
# 변경된 프로젝트와 의존하는 프로젝트만 실행
|
||||
```
|
||||
|
||||
**기본값:**
|
||||
> *(TODO)*
|
||||
### Pattern 5: Remote cache
|
||||
```bash
|
||||
# Turborepo Vercel remote cache
|
||||
turbo login && turbo link
|
||||
# 또는 self-hosted (Cloudflare R2)
|
||||
TURBO_API=... TURBO_TOKEN=... turbo build
|
||||
```
|
||||
|
||||
## ❌ 안티패턴 (Anti-Patterns)
|
||||
### Pattern 6: Design system token boundary
|
||||
```ts
|
||||
// packages/tokens
|
||||
export const tokens = {
|
||||
color: { brand: { 500: "#5B21B6" } },
|
||||
space: { 1: "4px", 2: "8px" },
|
||||
} as const;
|
||||
|
||||
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
|
||||
// packages/ui consumes tokens — never hard-coded values
|
||||
```
|
||||
|
||||
### Pattern 7: CODEOWNERS automation
|
||||
```
|
||||
# .github/CODEOWNERS
|
||||
/apps/checkout/ @acme/payments-team
|
||||
/packages/ui/ @acme/design-system
|
||||
/packages/api-client/ @acme/platform
|
||||
```
|
||||
|
||||
### Pattern 8: ESLint boundary rule (Nx tags)
|
||||
```jsonc
|
||||
// .eslintrc — apps 가 다른 app 을 직접 import 못하도록
|
||||
"@nx/enforce-module-boundaries": ["error", {
|
||||
"depConstraints": [
|
||||
{ "sourceTag": "scope:web", "onlyDependOnLibsWithTags": ["scope:shared", "scope:web"] },
|
||||
{ "sourceTag": "type:app", "onlyDependOnLibsWithTags": ["type:lib"] }
|
||||
]
|
||||
}]
|
||||
```
|
||||
|
||||
### Pattern 9: Per-package versioning (Changesets)
|
||||
```bash
|
||||
pnpm changeset # 변경 기록
|
||||
pnpm changeset version # version bump
|
||||
pnpm publish -r # publish 변경된 package 만
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 공유 코드 많음, 같은 release | Monorepo + Turborepo |
|
||||
| 거대 + 그래프 분석 필요 | Nx (affected, codegen, plugin) |
|
||||
| 진짜 독립 팀 + 별 cadence | Module Federation |
|
||||
| Iframe 격리 필요 (legacy) | Iframe 합성 |
|
||||
| Design 일관성 | Design system + tokens |
|
||||
|
||||
**기본값**: pnpm + Turborepo + design system + Changesets, MFE 는 마지막 수단.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[Software_Architecture]], [[Frontend_Architecture]]
|
||||
- 변형: [[Turborepo]], [[Nx]], [[Module_Federation]]
|
||||
- 응용: [[Design_System]], [[CI_CD]]
|
||||
- Adjacent: [[Build_Performance]], [[Monorepo]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: dependency graph 분석, 큰 PR review, codemod 생성 (Babel/jscodeshift).
|
||||
**언제 X**: deterministic refactor (codemod 직접 작성이 더 안전), 보안 boundary 검증.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- 처음부터 micro-frontend → 분산의 모든 비용, 이점 0
|
||||
- Cache 없이 monorepo → CI 30분+ 폭발
|
||||
- Design system 없이 1000개 button → 일관성 0
|
||||
- 모든 변경 시 전체 빌드 → affected only 미사용
|
||||
- 패키지 간 circular dep → boundary 망함
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Turborepo docs, Nx docs, Module Federation docs, Changesets). 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — 4 축, monorepo/MFE/boundary patterns |
|
||||
|
||||
Reference in New Issue
Block a user