@kood/claude-code 0.6.5 → 0.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +255 -149
- package/package.json +1 -1
- package/templates/.claude/agents/researcher.md +8 -1
- package/templates/.claude/instructions/sourcing/reliable-search.md +49 -2
- package/templates/.claude/scripts/deploy/build-run.sh +36 -0
- package/templates/.claude/scripts/deploy/deploy-check.sh +38 -0
- package/templates/.claude/scripts/git/git-all.sh +57 -0
- package/templates/.claude/scripts/git/git-clean-check.sh +31 -0
- package/templates/.claude/scripts/git/git-commit.sh +51 -0
- package/templates/.claude/scripts/git/git-info.sh +34 -0
- package/templates/.claude/scripts/git/git-push.sh +50 -0
- package/templates/.claude/scripts/lint/lint-check.sh +56 -0
- package/templates/.claude/scripts/lint/lint-file.sh +41 -0
- package/templates/.claude/scripts/pm/pm-detect.sh +25 -0
- package/templates/.claude/scripts/pm/pm-run.sh +41 -0
- package/templates/.claude/scripts/version/version-bump.sh +54 -0
- package/templates/.claude/scripts/version/version-find.sh +49 -0
- package/templates/.claude/skills/docs-fetch/SKILL.md +5 -4
- package/templates/.claude/skills/project-optimizer/AGENTS.md +275 -0
- package/templates/.claude/skills/project-optimizer/SKILL.md +374 -0
- package/templates/.claude/skills/project-optimizer/rules/arch-config-centralize.md +66 -0
- package/templates/.claude/skills/project-optimizer/rules/arch-hot-path.md +35 -0
- package/templates/.claude/skills/project-optimizer/rules/arch-interface-segregation.md +51 -0
- package/templates/.claude/skills/project-optimizer/rules/arch-module-boundary.md +42 -0
- package/templates/.claude/skills/project-optimizer/rules/build-cache.md +57 -0
- package/templates/.claude/skills/project-optimizer/rules/build-code-split.md +56 -0
- package/templates/.claude/skills/project-optimizer/rules/build-incremental.md +65 -0
- package/templates/.claude/skills/project-optimizer/rules/build-minify.md +61 -0
- package/templates/.claude/skills/project-optimizer/rules/build-tree-shake.md +60 -0
- package/templates/.claude/skills/project-optimizer/rules/code-complexity.md +65 -0
- package/templates/.claude/skills/project-optimizer/rules/code-dead-elimination.md +32 -0
- package/templates/.claude/skills/project-optimizer/rules/code-duplication.md +54 -0
- package/templates/.claude/skills/project-optimizer/rules/code-error-handling.md +75 -0
- package/templates/.claude/skills/project-optimizer/rules/code-naming.md +52 -0
- package/templates/.claude/skills/project-optimizer/rules/concurrency-defer-await.md +54 -0
- package/templates/.claude/skills/project-optimizer/rules/concurrency-parallel.md +90 -0
- package/templates/.claude/skills/project-optimizer/rules/concurrency-pipeline.md +68 -0
- package/templates/.claude/skills/project-optimizer/rules/concurrency-pool.md +68 -0
- package/templates/.claude/skills/project-optimizer/rules/deps-lightweight-alt.md +37 -0
- package/templates/.claude/skills/project-optimizer/rules/deps-peer-align.md +44 -0
- package/templates/.claude/skills/project-optimizer/rules/deps-security-audit.md +45 -0
- package/templates/.claude/skills/project-optimizer/rules/deps-unused-removal.md +25 -0
- package/templates/.claude/skills/project-optimizer/rules/deps-version-pin.md +40 -0
- package/templates/.claude/skills/project-optimizer/rules/dx-ci-speed.md +47 -0
- package/templates/.claude/skills/project-optimizer/rules/dx-dev-server.md +35 -0
- package/templates/.claude/skills/project-optimizer/rules/dx-lint-config.md +36 -0
- package/templates/.claude/skills/project-optimizer/rules/dx-test-coverage.md +34 -0
- package/templates/.claude/skills/project-optimizer/rules/dx-type-safety.md +49 -0
- package/templates/.claude/skills/project-optimizer/rules/io-batch-queries.md +67 -0
- package/templates/.claude/skills/project-optimizer/rules/io-cache-layer.md +67 -0
- package/templates/.claude/skills/project-optimizer/rules/io-connection-reuse.md +67 -0
- package/templates/.claude/skills/project-optimizer/rules/io-serialize-minimal.md +61 -0
- package/templates/.claude/skills/project-optimizer/rules/io-stream.md +75 -0
- package/templates/.claude/skills/project-optimizer/rules/memory-bounded-cache.md +65 -0
- package/templates/.claude/skills/project-optimizer/rules/memory-large-data.md +64 -0
- package/templates/.claude/skills/project-optimizer/rules/memory-lazy-init.md +78 -0
- package/templates/.claude/skills/project-optimizer/rules/memory-leak-prevention.md +79 -0
- package/templates/.claude/skills/project-optimizer/rules/memory-pool-reuse.md +70 -0
- package/templates/.claude/skills/sql-optimizer/SKILL.md +437 -0
- package/templates/.claude/skills/sql-optimizer/orm-patterns.md +218 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/AGENTS.md +53 -14
- package/templates/.claude/skills/tanstack-start-react-best-practices/SKILL.md +93 -27
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/bundle-defer-third-party.md +42 -19
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-optimistic-updates.md +109 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-suspense-query.md +74 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/client-use-hook.md +81 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/rerender-react-compiler.md +81 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-beforeload-auth.md +121 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-file-conventions.md +104 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-link-navigation.md +119 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-nested-layouts.md +155 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-path-params.md +89 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-pending-component.md +110 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-preload-strategy.md +91 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-router-context.md +120 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/routing-search-params.md +114 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-deferred-data.md +1 -1
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-error-boundaries.md +79 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-middleware.md +85 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-serialization.md +56 -21
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-streaming.md +84 -0
- package/templates/.claude/skills/tanstack-start-react-best-practices/rules/server-validator.md +71 -0
- package/templates/.claude/skills/tauri-react-best-practices/AGENTS.md +527 -0
- package/templates/.claude/skills/tauri-react-best-practices/SKILL.md +570 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-barrel-imports.md +140 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-cargo-profile.md +96 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-frontend-treeshake.md +242 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-lazy-components.md +255 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/bundle-remove-unused-commands.md +160 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-ci-pipeline.md +269 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-signing.md +207 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/deploy-updater.md +226 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-async-commands.md +172 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-batch-commands.md +133 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-binary-response.md +198 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-channel-streaming.md +186 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-error-handling.md +250 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/ipc-type-safe.md +227 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/perf-derived-state.md +231 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/perf-functional-setstate.md +191 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/perf-index-maps.md +276 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/perf-lazy-state-init.md +196 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-lifecycle.md +265 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-mobile-compat.md +199 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/plugin-permission-scope.md +193 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/react-error-boundary.md +239 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/react-event-listener.md +151 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/react-file-src.md +155 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/react-invoke-hook.md +139 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/react-optimistic-update.md +211 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/security-capability-split.md +205 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/security-csp.md +207 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/security-least-privilege.md +106 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/security-no-wildcard.md +253 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/security-scope-paths.md +160 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/state-async-mutex.md +270 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/state-mutex-pattern.md +265 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/state-react-sync.md +375 -0
- package/templates/.claude/skills/tauri-react-best-practices/rules/state-single-container.md +275 -0
- package/templates/tanstack-start/docs/architecture.md +238 -167
- package/templates/tanstack-start/docs/library/tanstack-router/error-handling.md +777 -38
- package/templates/tanstack-start/docs/library/tanstack-router/hooks.md +549 -37
- package/templates/tanstack-start/docs/library/tanstack-router/index.md +895 -111
- package/templates/tanstack-start/docs/library/tanstack-router/navigation.md +641 -43
- package/templates/tanstack-start/docs/library/tanstack-router/route-context.md +889 -38
- package/templates/tanstack-start/docs/library/tanstack-router/search-params.md +891 -29
- package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +972 -36
- package/templates/tanstack-start/docs/library/tanstack-start/index.md +1525 -881
- package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +1099 -20
- package/templates/tanstack-start/docs/library/tanstack-start/routing.md +796 -30
- package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +953 -35
- package/templates/tanstack-start/docs/library/tanstack-start/setup.md +371 -15
- package/templates/tauri/CLAUDE.md +189 -0
- package/templates/tauri/docs/guides/distribution.md +261 -0
- package/templates/tauri/docs/guides/getting-started.md +302 -0
- package/templates/tauri/docs/guides/mobile.md +288 -0
- package/templates/tauri/docs/library/tauri/index.md +510 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Consistent Error Handling Pattern
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Predictable error flow, easier debugging
|
|
5
|
+
tags: code, error, exception, result, handling
|
|
6
|
+
languages: all
|
|
7
|
+
related: [code-complexity, memory-leak-prevention]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 일관된 에러 처리 패턴
|
|
11
|
+
|
|
12
|
+
프로젝트 전체에서 하나의 에러 처리 패턴을 일관되게 사용합니다.
|
|
13
|
+
|
|
14
|
+
**언어별 권장 패턴:**
|
|
15
|
+
|
|
16
|
+
| 언어 | 패턴 | 핵심 |
|
|
17
|
+
|------|------|------|
|
|
18
|
+
| **Go** | `(value, error)` | 항상 err 체크, sentinel errors |
|
|
19
|
+
| **Rust** | `Result<T, E>` | `?` 연산자, 커스텀 Error enum |
|
|
20
|
+
| **Python** | Exception 계층 | 커스텀 Exception, `raise from` |
|
|
21
|
+
| **JS/TS** | 커스텀 Error / Result | Error 서브클래스 또는 Result 타입 |
|
|
22
|
+
| **Java** | Unchecked 선호 | RuntimeException 서브클래스 |
|
|
23
|
+
|
|
24
|
+
**✅ 올바른 예시:**
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
// JS/TS - 커스텀 Error 클래스
|
|
28
|
+
class AppError extends Error {
|
|
29
|
+
constructor(
|
|
30
|
+
message: string,
|
|
31
|
+
public code: string,
|
|
32
|
+
public statusCode: number = 500
|
|
33
|
+
) {
|
|
34
|
+
super(message)
|
|
35
|
+
this.name = 'AppError'
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
class NotFoundError extends AppError {
|
|
39
|
+
constructor(resource: string) {
|
|
40
|
+
super(`${resource} not found`, 'NOT_FOUND', 404)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```go
|
|
46
|
+
// Go - sentinel errors + wrapping
|
|
47
|
+
var ErrNotFound = errors.New("not found")
|
|
48
|
+
var ErrUnauthorized = errors.New("unauthorized")
|
|
49
|
+
|
|
50
|
+
func getUser(id string) (*User, error) {
|
|
51
|
+
user, err := db.Find(id)
|
|
52
|
+
if err != nil {
|
|
53
|
+
return nil, fmt.Errorf("getUser(%s): %w", id, err)
|
|
54
|
+
}
|
|
55
|
+
if user == nil {
|
|
56
|
+
return nil, ErrNotFound
|
|
57
|
+
}
|
|
58
|
+
return user, nil
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```rust
|
|
63
|
+
// Rust - thiserror
|
|
64
|
+
#[derive(Debug, thiserror::Error)]
|
|
65
|
+
enum AppError {
|
|
66
|
+
#[error("not found: {0}")]
|
|
67
|
+
NotFound(String),
|
|
68
|
+
#[error("unauthorized")]
|
|
69
|
+
Unauthorized,
|
|
70
|
+
#[error(transparent)]
|
|
71
|
+
Database(#[from] sqlx::Error),
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**원칙:** 에러는 발생 지점에서 컨텍스트를 추가하고, 처리 지점에서 변환/로깅합니다.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Use Intent-Revealing Names
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Self-documenting code, reduced cognitive load
|
|
5
|
+
tags: code, naming, readability, maintainability
|
|
6
|
+
languages: all
|
|
7
|
+
related: [code-complexity, dx-type-safety]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 의도를 드러내는 이름 사용
|
|
11
|
+
|
|
12
|
+
변수/함수/클래스 이름만으로 역할과 의도를 파악할 수 있게 합니다.
|
|
13
|
+
|
|
14
|
+
**❌ 잘못된 예시:**
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
d = {} # 무엇의 딕셔너리?
|
|
18
|
+
tmp = get() # 임시? 무엇을 가져옴?
|
|
19
|
+
flag = True # 어떤 플래그?
|
|
20
|
+
def proc(x): # 무엇을 처리?
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
for i in lst: # i와 lst가 무엇?
|
|
24
|
+
if i.s == 1: # s가 무엇? 1이 무엇?
|
|
25
|
+
do(i)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**✅ 올바른 예시:**
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
user_scores = {}
|
|
32
|
+
active_user = get_current_user()
|
|
33
|
+
is_premium = True
|
|
34
|
+
def calculate_shipping_cost(order):
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
STATUS_ACTIVE = 1
|
|
38
|
+
for user in users:
|
|
39
|
+
if user.status == STATUS_ACTIVE:
|
|
40
|
+
send_notification(user)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**명명 패턴:**
|
|
44
|
+
|
|
45
|
+
| 유형 | 패턴 | 예시 |
|
|
46
|
+
|------|------|------|
|
|
47
|
+
| **Boolean** | `is_`, `has_`, `can_`, `should_` | `is_valid`, `has_permission` |
|
|
48
|
+
| **함수** | 동사 + 목적어 | `calculate_total`, `send_email` |
|
|
49
|
+
| **컬렉션** | 복수형 | `users`, `order_items` |
|
|
50
|
+
| **맵/딕셔너리** | `x_by_y` | `user_by_id`, `orders_by_date` |
|
|
51
|
+
| **상수** | `UPPER_SNAKE` | `MAX_RETRY_COUNT` |
|
|
52
|
+
| **축약 금지** | 풀네임 사용 | `transaction` (not `txn`) |
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Defer Await to Point of Use
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: Eliminates unnecessary blocking, enables overlap
|
|
5
|
+
tags: concurrency, async, await, deferred
|
|
6
|
+
languages: all
|
|
7
|
+
related: [concurrency-parallel, memory-lazy-init]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## await/블로킹을 사용 지점으로 이동
|
|
11
|
+
|
|
12
|
+
비동기 작업의 결과를 기다리는 시점을 실제 사용 지점으로 미뤄서, 그 사이에 다른 작업이 실행될 수 있게 합니다.
|
|
13
|
+
|
|
14
|
+
**❌ 잘못된 예시 (즉시 대기):**
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// 결과가 10줄 뒤에서 필요한데 즉시 await
|
|
18
|
+
const data = await fetchData()
|
|
19
|
+
// ... 다른 동기 작업 10줄 ...
|
|
20
|
+
processData(data)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
data = await fetch_data() # 여기서 블로킹
|
|
25
|
+
# ... 다른 동기 작업 ...
|
|
26
|
+
process_data(data)
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**✅ 올바른 예시 (사용 시점에서 대기):**
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
// Promise를 먼저 시작, 나중에 await
|
|
33
|
+
const dataPromise = fetchData() // 시작만 함
|
|
34
|
+
// ... 다른 동기 작업 (이 동안 fetch 진행) ...
|
|
35
|
+
const data = await dataPromise // 실제 필요 시점에 await
|
|
36
|
+
processData(data)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
import asyncio
|
|
41
|
+
task = asyncio.create_task(fetch_data()) # 시작만 함
|
|
42
|
+
# ... 다른 동기 작업 ...
|
|
43
|
+
data = await task # 실제 필요 시점에 await
|
|
44
|
+
process_data(data)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```go
|
|
48
|
+
ch := make(chan *Data, 1)
|
|
49
|
+
go func() { ch <- fetchData(ctx) }() // 시작
|
|
50
|
+
// ... 다른 작업 ...
|
|
51
|
+
data := <-ch // 실제 필요 시점에 수신
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**핵심:** 작업 시작과 결과 소비 사이에 다른 유용한 작업이 있으면 defer 적용.
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Parallelize Independent Operations
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: 2-10x improvement on I/O-bound workloads
|
|
5
|
+
tags: concurrency, parallelization, async, performance
|
|
6
|
+
languages: all
|
|
7
|
+
related: [concurrency-defer-await, concurrency-pool, io-batch-queries]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 독립 작업 병렬 실행
|
|
11
|
+
|
|
12
|
+
서로 의존성이 없는 I/O 작업은 동시에 실행하여 총 대기 시간을 최장 작업 1개 수준으로 줄입니다.
|
|
13
|
+
|
|
14
|
+
**❌ 잘못된 예시 (순차 실행, 3번 왕복):**
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// JS/TS
|
|
18
|
+
const user = await fetchUser()
|
|
19
|
+
const posts = await fetchPosts()
|
|
20
|
+
const comments = await fetchComments()
|
|
21
|
+
// 총 시간: T(user) + T(posts) + T(comments)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
# Python
|
|
26
|
+
user = await fetch_user()
|
|
27
|
+
posts = await fetch_posts()
|
|
28
|
+
comments = await fetch_comments()
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```go
|
|
32
|
+
// Go
|
|
33
|
+
user, _ := fetchUser(ctx)
|
|
34
|
+
posts, _ := fetchPosts(ctx)
|
|
35
|
+
comments, _ := fetchComments(ctx)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**✅ 올바른 예시 (병렬 실행, 1번 왕복):**
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// JS/TS
|
|
42
|
+
const [user, posts, comments] = await Promise.all([
|
|
43
|
+
fetchUser(), fetchPosts(), fetchComments()
|
|
44
|
+
])
|
|
45
|
+
// 총 시간: max(T(user), T(posts), T(comments))
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
# Python
|
|
50
|
+
user, posts, comments = await asyncio.gather(
|
|
51
|
+
fetch_user(), fetch_posts(), fetch_comments()
|
|
52
|
+
)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```go
|
|
56
|
+
// Go (errgroup)
|
|
57
|
+
g, ctx := errgroup.WithContext(ctx)
|
|
58
|
+
var user *User; var posts []Post; var comments []Comment
|
|
59
|
+
g.Go(func() error { var err error; user, err = fetchUser(ctx); return err })
|
|
60
|
+
g.Go(func() error { var err error; posts, err = fetchPosts(ctx); return err })
|
|
61
|
+
g.Go(func() error { var err error; comments, err = fetchComments(ctx); return err })
|
|
62
|
+
if err := g.Wait(); err != nil { return err }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```rust
|
|
66
|
+
// Rust (tokio)
|
|
67
|
+
let (user, posts, comments) = tokio::try_join!(
|
|
68
|
+
fetch_user(), fetch_posts(), fetch_comments()
|
|
69
|
+
)?;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```java
|
|
73
|
+
// Java
|
|
74
|
+
var userFuture = CompletableFuture.supplyAsync(() -> fetchUser());
|
|
75
|
+
var postsFuture = CompletableFuture.supplyAsync(() -> fetchPosts());
|
|
76
|
+
CompletableFuture.allOf(userFuture, postsFuture).join();
|
|
77
|
+
var user = userFuture.get();
|
|
78
|
+
var posts = postsFuture.get();
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```csharp
|
|
82
|
+
// C#
|
|
83
|
+
var userTask = FetchUserAsync();
|
|
84
|
+
var postsTask = FetchPostsAsync();
|
|
85
|
+
await Task.WhenAll(userTask, postsTask);
|
|
86
|
+
var user = userTask.Result;
|
|
87
|
+
var posts = postsTask.Result;
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**적용 기준:** 두 작업이 서로의 결과를 필요로 하지 않으면 병렬화 대상.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Pipeline Parallelization
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: Continuous throughput for multi-stage processing
|
|
5
|
+
tags: concurrency, pipeline, streaming, producer-consumer
|
|
6
|
+
languages: all
|
|
7
|
+
related: [concurrency-parallel, io-stream, memory-large-data]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 파이프라인 병렬화
|
|
11
|
+
|
|
12
|
+
다단계 처리에서 각 단계를 동시에 실행하여 처리량을 극대화합니다. 한 단계의 출력이 다음 단계의 입력이 되는 스트리밍 방식.
|
|
13
|
+
|
|
14
|
+
**❌ 잘못된 예시 (단계별 전체 처리):**
|
|
15
|
+
|
|
16
|
+
```python
|
|
17
|
+
# 모든 데이터를 한 단계 완료 후 다음 단계
|
|
18
|
+
items = fetch_all() # 10초 대기
|
|
19
|
+
processed = [process(i) for i in items] # 10초 대기
|
|
20
|
+
results = [save(p) for p in processed] # 10초 대기
|
|
21
|
+
# 총 30초, 메모리에 전체 데이터 적재
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**✅ 올바른 예시 (스트리밍 파이프라인):**
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
# Python (async generator)
|
|
28
|
+
async def fetch_stream():
|
|
29
|
+
async for item in db.stream_query("SELECT ..."):
|
|
30
|
+
yield item
|
|
31
|
+
|
|
32
|
+
async def process_stream(items):
|
|
33
|
+
async for item in items:
|
|
34
|
+
yield transform(item)
|
|
35
|
+
|
|
36
|
+
async def save_stream(items):
|
|
37
|
+
batch = []
|
|
38
|
+
async for item in items:
|
|
39
|
+
batch.append(item)
|
|
40
|
+
if len(batch) >= 100:
|
|
41
|
+
await db.bulk_insert(batch)
|
|
42
|
+
batch.clear()
|
|
43
|
+
if batch:
|
|
44
|
+
await db.bulk_insert(batch)
|
|
45
|
+
|
|
46
|
+
# 파이프라인 연결
|
|
47
|
+
await save_stream(process_stream(fetch_stream()))
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```go
|
|
51
|
+
// Go (channel pipeline)
|
|
52
|
+
func fetch(ctx context.Context) <-chan Item {
|
|
53
|
+
out := make(chan Item, 100)
|
|
54
|
+
go func() { defer close(out); /* fetch and send */ }()
|
|
55
|
+
return out
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
func process(in <-chan Item) <-chan Result {
|
|
59
|
+
out := make(chan Result, 100)
|
|
60
|
+
go func() { defer close(out); for item := range in { out <- transform(item) } }()
|
|
61
|
+
return out
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// 파이프라인 연결
|
|
65
|
+
results := process(fetch(ctx))
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**적용 기준:** 데이터가 대량이고 단계별로 독립 처리 가능할 때.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Limit Concurrency with Pools
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: Prevents resource exhaustion, stable throughput
|
|
5
|
+
tags: concurrency, pool, semaphore, rate-limiting, backpressure
|
|
6
|
+
languages: all
|
|
7
|
+
related: [concurrency-parallel, io-connection-reuse, memory-bounded-cache]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 동시 실행 수 제한
|
|
11
|
+
|
|
12
|
+
무제한 병렬화는 리소스 고갈을 유발. 커넥션 풀, 세마포어, 워커 풀로 동시 실행 수를 제한합니다.
|
|
13
|
+
|
|
14
|
+
**❌ 잘못된 예시 (무제한 동시 실행):**
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
// 1000개 URL 동시 요청 → 커넥션 고갈, OOM
|
|
18
|
+
const results = await Promise.all(
|
|
19
|
+
urls.map(url => fetch(url))
|
|
20
|
+
)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**✅ 올바른 예시 (동시 실행 수 제한):**
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
// JS/TS (p-limit)
|
|
27
|
+
import pLimit from 'p-limit'
|
|
28
|
+
const limit = pLimit(10) // 최대 10개 동시
|
|
29
|
+
const results = await Promise.all(
|
|
30
|
+
urls.map(url => limit(() => fetch(url)))
|
|
31
|
+
)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
# Python (asyncio.Semaphore)
|
|
36
|
+
sem = asyncio.Semaphore(10)
|
|
37
|
+
async def limited_fetch(url):
|
|
38
|
+
async with sem:
|
|
39
|
+
return await fetch(url)
|
|
40
|
+
|
|
41
|
+
results = await asyncio.gather(*[limited_fetch(url) for url in urls])
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```go
|
|
45
|
+
// Go (worker pool)
|
|
46
|
+
func worker(jobs <-chan string, results chan<- Result) {
|
|
47
|
+
for url := range jobs {
|
|
48
|
+
results <- fetch(url)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// 10개 워커 실행
|
|
52
|
+
for i := 0; i < 10; i++ { go worker(jobs, results) }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```rust
|
|
56
|
+
// Rust (tokio::sync::Semaphore)
|
|
57
|
+
let sem = Arc::new(Semaphore::new(10));
|
|
58
|
+
let tasks: Vec<_> = urls.iter().map(|url| {
|
|
59
|
+
let permit = sem.clone().acquire_owned();
|
|
60
|
+
async move {
|
|
61
|
+
let _permit = permit.await.unwrap();
|
|
62
|
+
fetch(url).await
|
|
63
|
+
}
|
|
64
|
+
}).collect();
|
|
65
|
+
let results = futures::future::join_all(tasks).await;
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**적정 동시 실행 수:** DB 커넥션 10-25, HTTP 요청 10-50, 파일 I/O 5-20.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Replace Heavy Libraries with Lightweight Alternatives
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: 30-80% bundle/install size reduction
|
|
5
|
+
tags: deps, lightweight, alternative, bundle-size
|
|
6
|
+
languages: all
|
|
7
|
+
related: [build-tree-shake, build-minify]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 무거운 라이브러리 경량 대안으로 교체
|
|
11
|
+
|
|
12
|
+
사용 기능 대비 과도하게 큰 라이브러리를 경량 대안 또는 네이티브 API로 교체합니다.
|
|
13
|
+
|
|
14
|
+
**흔한 교체 대상:**
|
|
15
|
+
|
|
16
|
+
| 무거운 라이브러리 | 경량 대안 | 크기 감소 |
|
|
17
|
+
|-----------------|----------|----------|
|
|
18
|
+
| `moment.js` (300KB) | `date-fns` 또는 `dayjs` (2-7KB) | 97% |
|
|
19
|
+
| `lodash` (72KB) | 네이티브 JS 메서드 / `lodash-es` 직접 import | 90%+ |
|
|
20
|
+
| `axios` (29KB) | `fetch` (내장) / `ky` (3KB) | 90% |
|
|
21
|
+
| `uuid` (12KB) | `crypto.randomUUID()` (내장) | 100% |
|
|
22
|
+
| `chalk` (20KB) | `picocolors` (2KB) | 90% |
|
|
23
|
+
| `express` | `h3` / `Hono` (더 빠르고 작음) | 50%+ |
|
|
24
|
+
|
|
25
|
+
**Python:**
|
|
26
|
+
|
|
27
|
+
| 무거운 | 경량 대안 |
|
|
28
|
+
|-------|----------|
|
|
29
|
+
| `requests` | `httpx` (async 지원) |
|
|
30
|
+
| `beautifulsoup4` | `selectolax` (10x 빠름) |
|
|
31
|
+
| `pandas` (작은 작업) | `polars` (메모리 효율) |
|
|
32
|
+
| `flake8+isort+black` | `ruff` (100x 빠름, 올인원) |
|
|
33
|
+
|
|
34
|
+
**판단 기준:**
|
|
35
|
+
1. 사용하는 기능이 전체의 10% 미만 → 교체 고려
|
|
36
|
+
2. 네이티브 API로 대체 가능 → 교체
|
|
37
|
+
3. 번들 크기 50KB+ 차이 → 교체 고려
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Resolve Peer Dependency Conflicts
|
|
3
|
+
impact: LOW-MEDIUM
|
|
4
|
+
impactDescription: Eliminates runtime version conflicts
|
|
5
|
+
tags: deps, peer, conflict, resolution
|
|
6
|
+
languages: all
|
|
7
|
+
related: [deps-version-pin, deps-security-audit]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Peer Dependency 버전 충돌 해결
|
|
11
|
+
|
|
12
|
+
peer dependency 경고/에러를 해결하여 런타임 버전 충돌을 방지합니다.
|
|
13
|
+
|
|
14
|
+
**감지:**
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# npm
|
|
18
|
+
npm ls --all 2>&1 | grep "peer dep"
|
|
19
|
+
npm install # 경고 메시지 확인
|
|
20
|
+
|
|
21
|
+
# yarn
|
|
22
|
+
yarn install # 경고 확인
|
|
23
|
+
|
|
24
|
+
# pnpm
|
|
25
|
+
pnpm install # strict peer deps 기본
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**해결 전략:**
|
|
29
|
+
|
|
30
|
+
| 상황 | 해결 |
|
|
31
|
+
|------|------|
|
|
32
|
+
| 라이브러리 A가 react@18 요구, B가 react@19 요구 | A 업데이트 또는 overrides 사용 |
|
|
33
|
+
| 여러 버전의 같은 라이브러리 설치됨 | `npm ls [pkg]`로 확인, 상위 버전으로 통일 |
|
|
34
|
+
| 호환 불가 | `overrides` (npm) / `resolutions` (yarn) / `overrides` (pnpm) |
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
// package.json - 강제 버전 통일
|
|
38
|
+
{
|
|
39
|
+
"overrides": { "react": "^19.0.0" },
|
|
40
|
+
"resolutions": { "react": "^19.0.0" }
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**원칙:** overrides는 최후 수단. 먼저 라이브러리 업데이트 시도.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Audit Dependencies for Security Vulnerabilities
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Prevent known CVE exploitation
|
|
5
|
+
tags: deps, security, audit, vulnerability, cve
|
|
6
|
+
languages: all
|
|
7
|
+
related: [deps-version-pin]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 보안 취약점 스캔 및 업데이트
|
|
11
|
+
|
|
12
|
+
알려진 보안 취약점이 있는 의존성을 감지하고 업데이트합니다.
|
|
13
|
+
|
|
14
|
+
**스캔 도구:**
|
|
15
|
+
|
|
16
|
+
| 언어 | 도구 | 명령어 |
|
|
17
|
+
|------|------|--------|
|
|
18
|
+
| **JS/TS** | npm audit | `npm audit` / `npm audit fix` |
|
|
19
|
+
| **JS/TS** | yarn audit | `yarn npm audit` |
|
|
20
|
+
| **Python** | pip-audit | `pip-audit` |
|
|
21
|
+
| **Python** | safety | `safety check` |
|
|
22
|
+
| **Go** | govulncheck | `govulncheck ./...` |
|
|
23
|
+
| **Rust** | cargo-audit | `cargo audit` |
|
|
24
|
+
| **범용** | trivy | `trivy fs .` |
|
|
25
|
+
| **범용** | Snyk | `snyk test` |
|
|
26
|
+
|
|
27
|
+
**CI 통합:**
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
# GitHub Actions
|
|
31
|
+
- name: Security audit
|
|
32
|
+
run: npm audit --audit-level=high
|
|
33
|
+
|
|
34
|
+
# Dependabot (자동 PR)
|
|
35
|
+
# .github/dependabot.yml
|
|
36
|
+
version: 2
|
|
37
|
+
updates:
|
|
38
|
+
- package-ecosystem: "npm"
|
|
39
|
+
directory: "/"
|
|
40
|
+
schedule:
|
|
41
|
+
interval: "weekly"
|
|
42
|
+
open-pull-requests-limit: 10
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**원칙:** CI에서 high/critical 취약점 발견 시 빌드 실패 설정.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Remove Unused Dependencies
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Smaller install size, fewer vulnerabilities, faster CI
|
|
5
|
+
tags: deps, unused, cleanup, audit
|
|
6
|
+
languages: all
|
|
7
|
+
related: [build-tree-shake, code-dead-elimination]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 미사용 의존성 제거
|
|
11
|
+
|
|
12
|
+
설치되었지만 코드에서 import/require 되지 않는 패키지를 제거합니다.
|
|
13
|
+
|
|
14
|
+
**감지 도구:**
|
|
15
|
+
|
|
16
|
+
| 언어 | 도구 | 명령어 |
|
|
17
|
+
|------|------|--------|
|
|
18
|
+
| **JS/TS** | knip | `npx knip` |
|
|
19
|
+
| **JS/TS** | depcheck | `npx depcheck` |
|
|
20
|
+
| **Python** | deptry | `deptry .` |
|
|
21
|
+
| **Go** | go mod tidy | `go mod tidy` (자동 정리) |
|
|
22
|
+
| **Rust** | cargo-udeps | `cargo +nightly udeps` |
|
|
23
|
+
| **Java** | gradle-dependency-analysis | Gradle 플러그인 |
|
|
24
|
+
|
|
25
|
+
**주의:** devDependencies (빌드/테스트 도구)는 코드에서 직접 import하지 않아도 필요할 수 있음. 빌드 확인 후 제거.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Pin Production Dependency Versions
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Reproducible builds, no surprise breakages
|
|
5
|
+
tags: deps, version, pin, lock, reproducible
|
|
6
|
+
languages: all
|
|
7
|
+
related: [deps-security-audit, deps-peer-align]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 프로덕션 의존성 버전 고정
|
|
11
|
+
|
|
12
|
+
lockfile을 커밋하고 프로덕션 의존성은 정확한 버전으로 설치합니다.
|
|
13
|
+
|
|
14
|
+
**✅ 필수:**
|
|
15
|
+
|
|
16
|
+
| 파일 | 언어 | Git 커밋 |
|
|
17
|
+
|------|------|---------|
|
|
18
|
+
| `package-lock.json` / `yarn.lock` / `pnpm-lock.yaml` | JS/TS | 필수 |
|
|
19
|
+
| `Cargo.lock` | Rust (바이너리) | 필수 |
|
|
20
|
+
| `go.sum` | Go | 필수 |
|
|
21
|
+
| `poetry.lock` / `uv.lock` | Python | 필수 |
|
|
22
|
+
| `Gemfile.lock` | Ruby | 필수 |
|
|
23
|
+
|
|
24
|
+
**CI에서 lockfile 기반 설치:**
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# npm
|
|
28
|
+
npm ci # (npm install 아님!)
|
|
29
|
+
|
|
30
|
+
# yarn
|
|
31
|
+
yarn install --immutable
|
|
32
|
+
|
|
33
|
+
# pnpm
|
|
34
|
+
pnpm install --frozen-lockfile
|
|
35
|
+
|
|
36
|
+
# pip
|
|
37
|
+
pip install -r requirements.txt --no-deps
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**원칙:** `npm install`/`yarn install`은 lockfile을 수정할 수 있으므로 CI에서는 `ci`/`--frozen-lockfile` 사용.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Optimize CI Pipeline Speed
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: 30-70% CI time reduction
|
|
5
|
+
tags: dx, ci, pipeline, speed, cache
|
|
6
|
+
languages: all
|
|
7
|
+
related: [build-cache, build-incremental, dx-test-coverage]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## CI 파이프라인 속도 최적화
|
|
11
|
+
|
|
12
|
+
CI 파이프라인의 불필요한 단계를 제거하고 병렬화/캐싱을 적용합니다.
|
|
13
|
+
|
|
14
|
+
**최적화 전략:**
|
|
15
|
+
|
|
16
|
+
| 전략 | 효과 | 적용 |
|
|
17
|
+
|------|------|------|
|
|
18
|
+
| **의존성 캐시** | 50-80% 설치 시간 감소 | lockfile 해시 기반 캐시 키 |
|
|
19
|
+
| **병렬 단계** | 단계 수에 비례 감소 | lint, test, build 동시 실행 |
|
|
20
|
+
| **변경 파일만** | 대규모 모노레포에서 효과적 | `turbo run --filter=...` |
|
|
21
|
+
| **불필요 단계 제거** | 즉시 효과 | 중복 설치, 불필요 빌드 제거 |
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
# GitHub Actions - 병렬 + 캐시
|
|
25
|
+
jobs:
|
|
26
|
+
lint:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
steps:
|
|
29
|
+
- uses: actions/cache@v4
|
|
30
|
+
with: { path: node_modules, key: deps-${{ hashFiles('yarn.lock') }} }
|
|
31
|
+
- run: yarn lint
|
|
32
|
+
|
|
33
|
+
test:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/cache@v4
|
|
37
|
+
with: { path: node_modules, key: deps-${{ hashFiles('yarn.lock') }} }
|
|
38
|
+
- run: yarn test
|
|
39
|
+
|
|
40
|
+
build:
|
|
41
|
+
runs-on: ubuntu-latest
|
|
42
|
+
needs: [lint, test] # lint/test 병렬 후 build
|
|
43
|
+
steps:
|
|
44
|
+
- run: yarn build
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**모노레포:** Turborepo `--filter=[HEAD^1]`, Nx `affected:test`.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Speed Up Local Development Server
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Faster feedback loop, improved developer productivity
|
|
5
|
+
tags: dx, dev-server, hmr, startup, watch
|
|
6
|
+
languages: [js, ts, go, python, rust]
|
|
7
|
+
related: [build-incremental, dx-ci-speed]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 로컬 개발 서버 시작 속도 개선
|
|
11
|
+
|
|
12
|
+
개발 서버 시작 시간과 HMR(Hot Module Replacement) 속도를 최적화합니다.
|
|
13
|
+
|
|
14
|
+
**프론트엔드:**
|
|
15
|
+
|
|
16
|
+
| 도구 | 팁 |
|
|
17
|
+
|------|-----|
|
|
18
|
+
| **Vite** | 이미 빠름. `server.warmup` 활성화, `optimizeDeps.include` 프리번들링 |
|
|
19
|
+
| **webpack** | Vite/Turbopack으로 마이그레이션 고려 |
|
|
20
|
+
| **Next.js** | Turbopack (`next dev --turbo`) |
|
|
21
|
+
|
|
22
|
+
**백엔드:**
|
|
23
|
+
|
|
24
|
+
| 언어 | 도구 | 설정 |
|
|
25
|
+
|------|------|------|
|
|
26
|
+
| **Node.js** | `tsx --watch` | 네이티브 ESM, 즉시 시작 |
|
|
27
|
+
| **Go** | `air` | `.air.toml` 설정 |
|
|
28
|
+
| **Python** | `uvicorn --reload` | FastAPI 기본 |
|
|
29
|
+
| **Rust** | `cargo-watch` | `cargo watch -x run` |
|
|
30
|
+
|
|
31
|
+
**공통 개선:**
|
|
32
|
+
|
|
33
|
+
- TypeScript: `tsconfig.json`에서 `skipLibCheck: true` (개발 시)
|
|
34
|
+
- 불필요 플러그인 비활성화 (개발 시 린팅 플러그인 분리)
|
|
35
|
+
- `.gitignore`/`watchignore`에 빌드 출력 디렉토리 추가
|