[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
---
|
||||
id: ts-tsconfig-strategy
|
||||
title: tsconfig 전략 — strict / paths / project references
|
||||
category: Coding
|
||||
status: draft
|
||||
source_trust_level: B
|
||||
verification_status: conceptual
|
||||
created_at: 2026-05-09
|
||||
updated_at: 2026-05-09
|
||||
tags: [typescript, tsconfig, build, vibe-coding]
|
||||
tech_stack: { language: "TypeScript", applicable_to: ["Backend", "Frontend"] }
|
||||
applied_in: []
|
||||
aliases: [tsconfig.json, strict, isolatedModules, project references, paths]
|
||||
---
|
||||
|
||||
# tsconfig 전략
|
||||
|
||||
> 디폴트로 켜야 할 것: **strict / noUncheckedIndexedAccess / exactOptionalPropertyTypes**. 모노레포면 project references. 빌드 도구가 type-check 안 해줌 → `tsc --noEmit` CI 필수.
|
||||
|
||||
## 📖 핵심 개념
|
||||
- `strict`: 7개 옵션 묶음.
|
||||
- Compiler vs type-checker: bundler (esbuild/swc) 가 컴파일, tsc 는 검사 전담.
|
||||
- Project references: 큰 monorepo 의 점진 빌드.
|
||||
- Module 모드: `node16`/`nodenext` 가 ESM/CJS 정확.
|
||||
|
||||
## 💻 코드 패턴
|
||||
|
||||
### 시작 base
|
||||
```jsonc
|
||||
// tsconfig.base.json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"lib": ["ES2023", "DOM"],
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"noImplicitOverride": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"isolatedModules": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"resolveJsonModule": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### App 별 override
|
||||
```jsonc
|
||||
// apps/api/tsconfig.json
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["dist", "**/*.test.ts"]
|
||||
}
|
||||
```
|
||||
|
||||
### Path alias
|
||||
```jsonc
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"],
|
||||
"@shared/*": ["../shared/src/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
런타임 호환: tsx / vite / Next.js 자동. Node 직접 실행 시 `tsx` 또는 `tsconfig-paths/register`.
|
||||
|
||||
### Project references (monorepo)
|
||||
```jsonc
|
||||
// root tsconfig.json
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "packages/shared" },
|
||||
{ "path": "apps/api" },
|
||||
{ "path": "apps/web" }
|
||||
]
|
||||
}
|
||||
|
||||
// packages/shared/tsconfig.json
|
||||
{
|
||||
"compilerOptions": { "composite": true, "declaration": true, "outDir": "dist" },
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
|
||||
// apps/api/tsconfig.json (참조)
|
||||
{
|
||||
"references": [{ "path": "../../packages/shared" }]
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
tsc --build # 모두 점진
|
||||
tsc --build --watch # watch
|
||||
tsc --build --clean # 정리
|
||||
```
|
||||
|
||||
### Type-only import (verbatimModuleSyntax)
|
||||
```ts
|
||||
import { type User, getUser } from './user';
|
||||
// 컴파일 결과: type User 는 erased, 안전
|
||||
```
|
||||
|
||||
### CI type-check (bundle 따로)
|
||||
```yaml
|
||||
- run: tsc --noEmit # type 만 검사
|
||||
- run: vite build # bundle (esbuild/swc)
|
||||
```
|
||||
|
||||
bundler 가 type 무시 — 별도 step.
|
||||
|
||||
### Browser vs Node 분리
|
||||
```jsonc
|
||||
// web tsconfig
|
||||
"lib": ["ES2023", "DOM", "DOM.Iterable"]
|
||||
"types": [] // node types 빼기
|
||||
|
||||
// node tsconfig
|
||||
"lib": ["ES2023"]
|
||||
"types": ["node"]
|
||||
```
|
||||
|
||||
### Decorator (Nest 등)
|
||||
```jsonc
|
||||
"experimentalDecorators": true,
|
||||
"emitDecoratorMetadata": true
|
||||
```
|
||||
|
||||
또는 TS 5.0+ stage-3 decorators.
|
||||
|
||||
## 🤔 의사결정 기준
|
||||
| 상황 | 옵션 |
|
||||
|---|---|
|
||||
| 새 프로젝트 | strict + noUncheckedIndexedAccess |
|
||||
| 점진 마이그레이션 | strict 부분 켜기 (`strictNullChecks` 부터) |
|
||||
| ESM Node 18+ | `module: nodenext` |
|
||||
| Vite/Next | `moduleResolution: bundler` |
|
||||
| Monorepo 큰 | project references |
|
||||
| Library 배포 | `composite: true`, `declaration: true` |
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **strict false 그대로**: 의미 절반 잃음.
|
||||
- **`@ts-ignore` 남발**: 차라리 `as` + 주석.
|
||||
- **`any` 도배**: `unknown` + 좁히기.
|
||||
- **path alias 만 — runtime resolver X**: import 깨짐.
|
||||
- **`tsc` 빌드 + bundler 빌드 둘 다**: 한쪽 only. tsc=check, bundler=build.
|
||||
- **`skipLibCheck: false` 항상**: node_modules 타입 깨지면 빌드 fail. 기본 true.
|
||||
- **`isolatedModules: false`**: esbuild/swc 가 일부 패턴 못 컴파일.
|
||||
|
||||
## 🤖 LLM 활용 힌트
|
||||
- strict + noUncheckedIndexedAccess + exactOptionalPropertyTypes 항상.
|
||||
- bundler 컴파일 + tsc 검사 분리.
|
||||
- monorepo = project references.
|
||||
|
||||
## 🔗 관련 문서
|
||||
- [[TS_Build_Bundler_Patterns]]
|
||||
- [[TS_Monorepo_Patterns]]
|
||||
- [[JS_Module_System_ESM_CJS]]
|
||||
Reference in New Issue
Block a user