@kood/claude-code 0.6.6 → 0.7.0
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 +7 -1
- package/package.json +1 -1
- package/templates/.claude/agents/analyst.md +5 -0
- package/templates/.claude/agents/architect.md +5 -0
- package/templates/.claude/agents/build-fixer.md +1 -0
- package/templates/.claude/agents/code-reviewer.md +1 -0
- package/templates/.claude/agents/critic.md +4 -0
- package/templates/.claude/agents/deep-executor.md +1 -0
- package/templates/.claude/agents/dependency-manager.md +2 -0
- package/templates/.claude/agents/deployment-validator.md +2 -0
- package/templates/.claude/agents/designer.md +2 -0
- package/templates/.claude/agents/document-writer.md +3 -0
- package/templates/.claude/agents/explore.md +1 -0
- package/templates/.claude/agents/git-operator.md +2 -0
- package/templates/.claude/agents/implementation-executor.md +2 -0
- package/templates/.claude/agents/ko-to-en-translator.md +3 -0
- package/templates/.claude/agents/lint-fixer.md +2 -0
- package/templates/.claude/agents/planner.md +3 -0
- package/templates/.claude/agents/pm.md +349 -0
- package/templates/.claude/agents/qa-tester.md +1 -0
- package/templates/.claude/agents/refactor-advisor.md +4 -0
- package/templates/.claude/agents/researcher.md +9 -1
- package/templates/.claude/agents/scientist.md +1 -0
- package/templates/.claude/agents/security-reviewer.md +1 -0
- package/templates/.claude/agents/tdd-guide.md +1 -0
- package/templates/.claude/agents/vision.md +1 -0
- package/templates/.claude/instructions/agent-patterns/agent-teams-usage.md +376 -0
- package/templates/.claude/instructions/sourcing/reliable-search.md +49 -2
- package/templates/.claude/scripts/agent-teams/check-availability.sh +238 -0
- package/templates/.claude/scripts/agent-teams/setup-tmux.sh +125 -0
- package/templates/.claude/skills/agent-teams-setup/SKILL.md +460 -0
- package/templates/.claude/skills/brainstorm/SKILL.md +1 -0
- package/templates/.claude/skills/bug-fix/SKILL.md +1 -0
- package/templates/.claude/skills/crawler/SKILL.md +2 -0
- package/templates/.claude/skills/docs-creator/SKILL.md +1 -0
- package/templates/.claude/skills/docs-fetch/SKILL.md +6 -4
- package/templates/.claude/skills/docs-refactor/SKILL.md +1 -0
- package/templates/.claude/skills/elon-musk/SKILL.md +1 -0
- package/templates/.claude/skills/execute/SKILL.md +1 -0
- package/templates/.claude/skills/feedback/SKILL.md +1 -0
- package/templates/.claude/skills/figma-to-code/SKILL.md +1 -0
- package/templates/.claude/skills/genius-thinking/SKILL.md +1 -0
- package/templates/.claude/skills/global-uiux-design/SKILL.md +1 -0
- package/templates/.claude/skills/korea-uiux-design/SKILL.md +1 -0
- package/templates/.claude/skills/nextjs-react-best-practices/SKILL.md +1 -0
- package/templates/.claude/skills/plan/SKILL.md +1 -0
- package/templates/.claude/skills/prd/SKILL.md +1 -0
- package/templates/.claude/skills/project-optimizer/AGENTS.md +275 -0
- package/templates/.claude/skills/project-optimizer/SKILL.md +375 -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/ralph/SKILL.md +1 -0
- package/templates/.claude/skills/refactor/SKILL.md +1 -0
- package/templates/.claude/skills/research/SKILL.md +1 -0
- package/templates/.claude/skills/sql-optimizer/SKILL.md +438 -0
- package/templates/.claude/skills/sql-optimizer/orm-patterns.md +218 -0
- package/templates/.claude/skills/startup-validator/SKILL.md +1 -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 +94 -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 +571 -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
|
@@ -1,52 +1,408 @@
|
|
|
1
1
|
# TanStack Start - 설치 및 설정
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> v1.159.4 기준
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<installation>
|
|
8
|
+
|
|
9
|
+
## 패키지 설치
|
|
4
10
|
|
|
5
11
|
```bash
|
|
6
|
-
|
|
7
|
-
|
|
12
|
+
npm install @tanstack/react-start @tanstack/react-router react react-dom
|
|
13
|
+
npm install -D vite @vitejs/plugin-react vite-tsconfig-paths typescript @types/react @types/react-dom @types/node
|
|
8
14
|
```
|
|
9
15
|
|
|
10
|
-
|
|
16
|
+
**vinxi 사용 금지**: TanStack Start v1은 Vite를 직접 사용합니다.
|
|
17
|
+
|
|
18
|
+
| 패키지 | 버전 | 용도 |
|
|
19
|
+
|--------|------|------|
|
|
20
|
+
| `@tanstack/react-start` | 최신 | Full-stack framework |
|
|
21
|
+
| `@tanstack/react-router` | 최신 | File-based routing |
|
|
22
|
+
| `react`, `react-dom` | 19+ | React 라이브러리 |
|
|
23
|
+
| `vite` | 7+ | Build tool |
|
|
24
|
+
| `@vitejs/plugin-react` | 최신 | React JSX 처리 |
|
|
25
|
+
| `vite-tsconfig-paths` | 최신 | Path alias 지원 |
|
|
26
|
+
|
|
27
|
+
> **참고:** `@vitejs/plugin-react` 대신 `@vitejs/plugin-react-oxc` 또는 `@vitejs/plugin-react-swc`도 사용 가능합니다.
|
|
28
|
+
|
|
29
|
+
### 프로젝트 생성 (자동)
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm create @tanstack/start@latest my-app
|
|
33
|
+
cd my-app
|
|
34
|
+
npm install
|
|
35
|
+
npm run dev
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
</installation>
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
<vite_config>
|
|
43
|
+
|
|
44
|
+
## vite.config.ts
|
|
11
45
|
|
|
12
46
|
```typescript
|
|
13
|
-
// vite.config.ts
|
|
14
47
|
import { defineConfig } from 'vite'
|
|
15
48
|
import tsConfigPaths from 'vite-tsconfig-paths'
|
|
16
49
|
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
|
|
17
50
|
import viteReact from '@vitejs/plugin-react'
|
|
18
51
|
|
|
19
52
|
export default defineConfig({
|
|
20
|
-
server: {
|
|
21
|
-
|
|
53
|
+
server: {
|
|
54
|
+
port: 3000,
|
|
55
|
+
},
|
|
56
|
+
plugins: [
|
|
57
|
+
tsConfigPaths(),
|
|
58
|
+
tanstackStart(),
|
|
59
|
+
// react 플러그인은 반드시 start 플러그인 뒤에 위치해야 함
|
|
60
|
+
viteReact(),
|
|
61
|
+
],
|
|
62
|
+
})
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**플러그인 순서 (중요):**
|
|
66
|
+
1. `tsConfigPaths()` - Path alias
|
|
67
|
+
2. `tanstackStart()` - Server Functions, SSR
|
|
68
|
+
3. `viteReact()` - JSX 처리 (반드시 start 뒤에!)
|
|
69
|
+
|
|
70
|
+
### Server Function ID 커스터마이징 (실험적)
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { defineConfig } from 'vite'
|
|
74
|
+
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
|
|
75
|
+
import viteReact from '@vitejs/plugin-react'
|
|
76
|
+
|
|
77
|
+
export default defineConfig({
|
|
78
|
+
plugins: [
|
|
79
|
+
tanstackStart({
|
|
80
|
+
serverFns: {
|
|
81
|
+
generateFunctionId: ({ filename, functionName }) => {
|
|
82
|
+
return crypto
|
|
83
|
+
.createHash('sha1')
|
|
84
|
+
.update(`${filename}--${functionName}`)
|
|
85
|
+
.digest('hex')
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
}),
|
|
89
|
+
viteReact(),
|
|
90
|
+
],
|
|
22
91
|
})
|
|
23
92
|
```
|
|
24
93
|
|
|
94
|
+
</vite_config>
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
<typescript_config>
|
|
99
|
+
|
|
100
|
+
## tsconfig.json
|
|
101
|
+
|
|
25
102
|
```json
|
|
26
|
-
// tsconfig.json
|
|
27
103
|
{
|
|
28
104
|
"compilerOptions": {
|
|
29
105
|
"target": "ES2022",
|
|
30
106
|
"module": "ESNext",
|
|
31
|
-
"moduleResolution": "
|
|
107
|
+
"moduleResolution": "Bundler",
|
|
32
108
|
"strict": true,
|
|
33
109
|
"jsx": "react-jsx",
|
|
34
|
-
"
|
|
110
|
+
"strictNullChecks": true,
|
|
111
|
+
"skipLibCheck": true,
|
|
112
|
+
"paths": {
|
|
113
|
+
"@/*": ["./src/*"]
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
"include": ["src"],
|
|
117
|
+
"exclude": ["node_modules"]
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**주의사항:**
|
|
122
|
+
- `strictNullChecks: true` - null/undefined 체크 필수
|
|
123
|
+
- `jsx: "react-jsx"` - React 17+ 문법
|
|
124
|
+
- `moduleResolution: "Bundler"` - Vite와 호환 (대소문자 주의)
|
|
125
|
+
- `verbatimModuleSyntax` **사용 금지** - 서버 번들이 클라이언트 번들로 유출될 수 있음
|
|
126
|
+
- `skipLibCheck: true` 권장
|
|
127
|
+
|
|
128
|
+
</typescript_config>
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
<package_json>
|
|
133
|
+
|
|
134
|
+
## package.json Scripts
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"type": "module",
|
|
139
|
+
"scripts": {
|
|
140
|
+
"dev": "vite dev",
|
|
141
|
+
"build": "vite build",
|
|
142
|
+
"start": "node .output/server/index.mjs",
|
|
143
|
+
"preview": "vite preview",
|
|
144
|
+
"type-check": "tsc --noEmit"
|
|
35
145
|
}
|
|
36
146
|
}
|
|
37
147
|
```
|
|
38
148
|
|
|
39
|
-
|
|
149
|
+
| Script | 명령 | 설명 |
|
|
150
|
+
|--------|------|------|
|
|
151
|
+
| `dev` | `vite dev` | 개발 서버 (Hot reload) |
|
|
152
|
+
| `build` | `vite build` | 프로덕션 빌드 (`.output/` 생성) |
|
|
153
|
+
| `start` | `node .output/server/index.mjs` | 프로덕션 서버 |
|
|
154
|
+
|
|
155
|
+
> **참고:** `package.json`에 `"type": "module"` 설정이 필요합니다.
|
|
156
|
+
|
|
157
|
+
</package_json>
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
<required_files>
|
|
162
|
+
|
|
163
|
+
## 필수 파일
|
|
164
|
+
|
|
165
|
+
TanStack Start 사용에 필요한 최소 파일:
|
|
166
|
+
|
|
167
|
+
### 1. Router 설정 (src/router.tsx)
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
// src/router.tsx
|
|
171
|
+
import { createRouter } from '@tanstack/react-router'
|
|
172
|
+
import { routeTree } from './routeTree.gen'
|
|
173
|
+
|
|
174
|
+
// 매번 새 router 인스턴스를 반환하는 함수를 export해야 합니다
|
|
175
|
+
export function getRouter() {
|
|
176
|
+
const router = createRouter({
|
|
177
|
+
routeTree,
|
|
178
|
+
scrollRestoration: true,
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
return router
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 2. Root Route (src/routes/__root.tsx)
|
|
186
|
+
|
|
187
|
+
```tsx
|
|
188
|
+
// src/routes/__root.tsx
|
|
189
|
+
/// <reference types="vite/client" />
|
|
190
|
+
import type { ReactNode } from 'react'
|
|
191
|
+
import {
|
|
192
|
+
Outlet,
|
|
193
|
+
createRootRoute,
|
|
194
|
+
HeadContent,
|
|
195
|
+
Scripts,
|
|
196
|
+
} from '@tanstack/react-router'
|
|
197
|
+
|
|
198
|
+
export const Route = createRootRoute({
|
|
199
|
+
head: () => ({
|
|
200
|
+
meta: [
|
|
201
|
+
{ charSet: 'utf-8' },
|
|
202
|
+
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
|
|
203
|
+
{ title: 'My App' },
|
|
204
|
+
],
|
|
205
|
+
}),
|
|
206
|
+
component: RootComponent,
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
function RootComponent() {
|
|
210
|
+
return (
|
|
211
|
+
<RootDocument>
|
|
212
|
+
<Outlet />
|
|
213
|
+
</RootDocument>
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
|
|
218
|
+
return (
|
|
219
|
+
<html>
|
|
220
|
+
<head>
|
|
221
|
+
<HeadContent />
|
|
222
|
+
</head>
|
|
223
|
+
<body>
|
|
224
|
+
{children}
|
|
225
|
+
<Scripts />
|
|
226
|
+
</body>
|
|
227
|
+
</html>
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
**핵심 컴포넌트:**
|
|
233
|
+
- `<HeadContent />` - `<head>` 태그 안에 배치, meta/title/link 렌더링
|
|
234
|
+
- `<Outlet />` - 자식 라우트 렌더링
|
|
235
|
+
- `<Scripts />` - `<body>` 태그 안에 배치, 클라이언트 JavaScript 로드 (필수)
|
|
236
|
+
|
|
237
|
+
### 3. Route Tree (src/routeTree.gen.ts)
|
|
238
|
+
|
|
239
|
+
이 파일은 `npm run dev` 또는 `npm run build` 실행 시 **자동 생성**됩니다. 수동으로 생성하지 마세요.
|
|
240
|
+
|
|
241
|
+
### 4. Start 설정 (src/start.ts) - 선택적
|
|
242
|
+
|
|
243
|
+
전역 미들웨어나 Start 레벨 옵션 설정 시 필요:
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
// src/start.ts
|
|
247
|
+
import { createStart } from '@tanstack/react-start'
|
|
248
|
+
|
|
249
|
+
export const startInstance = createStart(() => ({
|
|
250
|
+
// 전역 미들웨어, SSR 기본값 등 설정
|
|
251
|
+
}))
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
</required_files>
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
<environment_variables>
|
|
259
|
+
|
|
260
|
+
## 환경 변수 설정
|
|
261
|
+
|
|
262
|
+
### .env (프로젝트 루트)
|
|
263
|
+
|
|
264
|
+
```env
|
|
265
|
+
# 데이터베이스
|
|
266
|
+
DATABASE_URL=postgresql://user:password@localhost:5432/myapp
|
|
267
|
+
|
|
268
|
+
# 서버
|
|
269
|
+
API_SECRET=your-secret-key-min-32-characters-long
|
|
270
|
+
|
|
271
|
+
# 클라이언트 (VITE_ prefix)
|
|
272
|
+
VITE_API_BASEURL=http://localhost:3000
|
|
273
|
+
VITE_ENVIRONMENT=development
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### lib/env.ts (Zod 검증)
|
|
40
277
|
|
|
41
278
|
```typescript
|
|
42
|
-
// lib/env.ts
|
|
43
279
|
import { z } from 'zod'
|
|
44
280
|
|
|
45
|
-
|
|
46
|
-
|
|
281
|
+
// 서버 환경변수 (process.env)
|
|
282
|
+
const serverEnvSchema = z.object({
|
|
283
|
+
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
|
|
47
284
|
DATABASE_URL: z.string().url(),
|
|
48
285
|
API_SECRET: z.string().min(32),
|
|
49
286
|
})
|
|
50
287
|
|
|
51
|
-
export const
|
|
288
|
+
export const serverEnv = serverEnvSchema.parse(process.env)
|
|
289
|
+
|
|
290
|
+
// 클라이언트 환경변수 (import.meta.env)
|
|
291
|
+
const clientEnvSchema = z.object({
|
|
292
|
+
VITE_API_BASEURL: z.string().url().default('http://localhost:3000'),
|
|
293
|
+
VITE_ENVIRONMENT: z.enum(['development', 'production']).default('development'),
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
export const clientEnv = clientEnvSchema.parse(import.meta.env)
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
**보안 규칙:**
|
|
300
|
+
- Server Function에서만 `serverEnv` 사용
|
|
301
|
+
- Loader에서 `process.env` 직접 접근 금지 (클라이언트 노출)
|
|
302
|
+
- 클라이언트에서는 `clientEnv` 사용
|
|
303
|
+
- `VITE_` prefix로 시작하는 환경변수만 클라이언트 노출
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
// 올바른 방식: Server Function에서 검증
|
|
307
|
+
export const getSecretConfig = createServerFn({ method: 'GET' })
|
|
308
|
+
.middleware([authMiddleware])
|
|
309
|
+
.handler(async () => {
|
|
310
|
+
return { secret: serverEnv.API_SECRET }
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
// 잘못된 방식: Loader에서 직접 사용
|
|
314
|
+
export const Route = createFileRoute('/config')({
|
|
315
|
+
loader: () => {
|
|
316
|
+
const secret = process.env.API_SECRET // 클라이언트에 노출!
|
|
317
|
+
return { secret }
|
|
318
|
+
},
|
|
319
|
+
})
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
</environment_variables>
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
<project_structure>
|
|
327
|
+
|
|
328
|
+
## 초기 프로젝트 구조
|
|
329
|
+
|
|
52
330
|
```
|
|
331
|
+
my-app/
|
|
332
|
+
├── src/
|
|
333
|
+
│ ├── routes/
|
|
334
|
+
│ │ ├── __root.tsx # Root layout (html/body)
|
|
335
|
+
│ │ ├── index.tsx # /
|
|
336
|
+
│ │ └── $.tsx # Catch-all (404)
|
|
337
|
+
│ ├── router.tsx # Router 설정
|
|
338
|
+
│ ├── routeTree.gen.ts # 자동 생성 (수정 금지)
|
|
339
|
+
│ ├── functions/ # 공통 Server Functions
|
|
340
|
+
│ ├── middleware/ # 공통 Middleware
|
|
341
|
+
│ ├── components/ # UI 컴포넌트
|
|
342
|
+
│ ├── lib/
|
|
343
|
+
│ │ └── env.ts # 환경변수 검증
|
|
344
|
+
│ └── database/ # Prisma
|
|
345
|
+
├── vite.config.ts
|
|
346
|
+
├── tsconfig.json
|
|
347
|
+
├── package.json
|
|
348
|
+
└── .env
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Server Function 파일 조직 패턴
|
|
352
|
+
|
|
353
|
+
```
|
|
354
|
+
src/utils/
|
|
355
|
+
├── users.functions.ts # Server Function 래퍼 (createServerFn) - 어디서든 import 가능
|
|
356
|
+
├── users.server.ts # 서버 전용 헬퍼 (DB 쿼리 등) - handler 안에서만 import
|
|
357
|
+
└── schemas.ts # 공유 검증 스키마 (클라이언트 안전)
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
> **참고:** Server Function은 정적 import가 안전합니다. 빌드 프로세스가 클라이언트 번들에서 서버 구현을 RPC 스텁으로 교체합니다. 단, 동적 import는 피하세요.
|
|
361
|
+
|
|
362
|
+
</project_structure>
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
<verification>
|
|
367
|
+
|
|
368
|
+
## 설정 확인
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
# 1. 개발 서버 시작
|
|
372
|
+
npm run dev
|
|
373
|
+
|
|
374
|
+
# 2. http://localhost:3000 접속
|
|
375
|
+
|
|
376
|
+
# 3. 타입 체크
|
|
377
|
+
npm run type-check
|
|
378
|
+
|
|
379
|
+
# 4. 프로덕션 빌드
|
|
380
|
+
npm run build
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
성공 기준:
|
|
384
|
+
- 개발 서버 실행
|
|
385
|
+
- Hot reload 작동
|
|
386
|
+
- TypeScript 에러 없음
|
|
387
|
+
- `vite build` 성공 (`.output/` 생성)
|
|
388
|
+
- `routeTree.gen.ts` 자동 생성됨
|
|
389
|
+
|
|
390
|
+
</verification>
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
<version_info>
|
|
395
|
+
|
|
396
|
+
**Version:** TanStack Start/Router v1.159.4
|
|
397
|
+
|
|
398
|
+
**Key Points:**
|
|
399
|
+
- Vite 7+ 필수 (vinxi 사용 안함)
|
|
400
|
+
- `.inputValidator()` 사용 (`.validator()` deprecated)
|
|
401
|
+
- `verbatimModuleSyntax` 사용 금지
|
|
402
|
+
- TypeScript `strict: true` 필수
|
|
403
|
+
- `package.json`에 `"type": "module"` 필수
|
|
404
|
+
- React 플러그인은 반드시 Start 플러그인 뒤에 위치
|
|
405
|
+
- `routeTree.gen.ts`는 자동 생성 (수동 생성 금지)
|
|
406
|
+
- Server Function 정적 import 안전, 동적 import 금지
|
|
407
|
+
|
|
408
|
+
</version_info>
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# CLAUDE.md - Tauri
|
|
2
|
+
|
|
3
|
+
> Cross-platform Desktop & Mobile App Framework
|
|
4
|
+
|
|
5
|
+
<context>
|
|
6
|
+
|
|
7
|
+
**Purpose:** Tauri v2 프레임워크로 데스크톱/모바일 크로스플랫폼 애플리케이션 개발을 위한 작업 지침
|
|
8
|
+
|
|
9
|
+
**Scope:** Rust 백엔드 + React + TypeScript + Vite 프론트엔드 기반 크로스플랫폼 앱 (iOS, Android, Windows, macOS)
|
|
10
|
+
|
|
11
|
+
**Key Features:**
|
|
12
|
+
- Rust 백엔드 + 시스템 WebView (작은 바이너리 사이즈)
|
|
13
|
+
- React + TypeScript + Vite 프론트엔드
|
|
14
|
+
- IPC (Commands + Events) 기반 프론트엔드-백엔드 통신
|
|
15
|
+
- Capabilities/Permissions 보안 모델
|
|
16
|
+
- Plugin 시스템 (데스크톱 + 모바일 네이티브 확장)
|
|
17
|
+
- iOS, Android, Windows, macOS, Linux 빌드
|
|
18
|
+
|
|
19
|
+
</context>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
<instructions>
|
|
24
|
+
@docs/library/tauri/index.md
|
|
25
|
+
@docs/guides/getting-started.md
|
|
26
|
+
@docs/guides/mobile.md
|
|
27
|
+
@docs/guides/distribution.md
|
|
28
|
+
</instructions>
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
<forbidden>
|
|
33
|
+
|
|
34
|
+
| 분류 | 금지 행동 |
|
|
35
|
+
|------|----------|
|
|
36
|
+
| **보안** | Capabilities 없이 Command 노출, CSP 비활성화, `'unsafe-eval'` 무분별 사용 |
|
|
37
|
+
| **IPC** | 프론트엔드에서 Rust 함수 직접 호출 (invoke 사용), 민감 데이터 Event로 브로드캐스트 |
|
|
38
|
+
| **상태관리** | Arc 래핑 (State<T>가 내부 처리), 비동기 코드에서 await 걸쳐 Mutex lock 유지 |
|
|
39
|
+
| **모바일** | iOS 개발을 macOS 외 플랫폼에서 시도, Android 메인 스레드에서 블로킹 I/O |
|
|
40
|
+
| **빌드** | `--no-verify` 또는 보안 검증 우회, WebView2 설치 skip |
|
|
41
|
+
| **v1 API** | allowlist 사용 (capabilities 사용), `@tauri-apps/api/tauri` import (core 사용), Window 타입 (WebviewWindow 사용) |
|
|
42
|
+
|
|
43
|
+
</forbidden>
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
<required>
|
|
48
|
+
|
|
49
|
+
| 작업 | 필수 행동 |
|
|
50
|
+
|------|----------|
|
|
51
|
+
| **Command 정의** | `#[tauri::command]` 어노테이션, `tauri::generate_handler!` 등록 |
|
|
52
|
+
| **프론트엔드 호출** | `invoke()` from `@tauri-apps/api/core` 사용 |
|
|
53
|
+
| **보안** | Capabilities 파일 정의 (`src-tauri/capabilities/`), Permission 명시 |
|
|
54
|
+
| **상태관리** | `app.manage()` + `State<T>` 패턴, 가변 상태 → `Mutex<T>` |
|
|
55
|
+
| **모바일 빌드** | `tauri android init` / `tauri ios init` 먼저 실행 |
|
|
56
|
+
| **Plugin 사용** | Plugin별 Permission 추가 (`src-tauri/capabilities/`) |
|
|
57
|
+
| **타입 안전성** | Command 인자/반환 → `serde::Serialize`/`Deserialize` |
|
|
58
|
+
| **에러 처리** | Command → `Result<T, E>` 반환, Error 타입 직렬화 가능 |
|
|
59
|
+
|
|
60
|
+
</required>
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
<tech_stack>
|
|
65
|
+
|
|
66
|
+
| 기술 | 버전 | 주의 |
|
|
67
|
+
|------|------|------|
|
|
68
|
+
| Tauri | 2.x | CLI: @tauri-apps/cli@latest |
|
|
69
|
+
| Rust | stable | MSVC 툴체인 (Windows) |
|
|
70
|
+
| React | 19.x | - |
|
|
71
|
+
| TypeScript | 5.x | strict |
|
|
72
|
+
| Vite | 6.x | strictPort: true |
|
|
73
|
+
| @tauri-apps/api | 2.x | core, webviewWindow |
|
|
74
|
+
|
|
75
|
+
</tech_stack>
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
<structure>
|
|
80
|
+
```
|
|
81
|
+
my-tauri-app/
|
|
82
|
+
├── src/ # React + TypeScript 프론트엔드
|
|
83
|
+
│ ├── App.tsx
|
|
84
|
+
│ ├── main.tsx
|
|
85
|
+
│ └── components/
|
|
86
|
+
├── src-tauri/ # Rust 백엔드
|
|
87
|
+
│ ├── src/
|
|
88
|
+
│ │ ├── main.rs # 앱 엔트리, Command 등록
|
|
89
|
+
│ │ ├── lib.rs # 라이브러리 (모바일 지원)
|
|
90
|
+
│ │ └── commands/ # Command 모듈
|
|
91
|
+
│ ├── capabilities/ # 보안 Capabilities
|
|
92
|
+
│ │ └── default.json
|
|
93
|
+
│ ├── Cargo.toml
|
|
94
|
+
│ ├── tauri.conf.json # Tauri 설정
|
|
95
|
+
│ ├── tauri.android.conf.json # Android 설정
|
|
96
|
+
│ └── tauri.ios.conf.json # iOS 설정
|
|
97
|
+
├── package.json
|
|
98
|
+
├── vite.config.ts
|
|
99
|
+
└── tsconfig.json
|
|
100
|
+
```
|
|
101
|
+
</structure>
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
<conventions>
|
|
106
|
+
|
|
107
|
+
파일명: kebab-case (TS), snake_case (Rust)
|
|
108
|
+
Command: snake_case (Rust) → camelCase (JS invoke)
|
|
109
|
+
Config: `tauri.conf.json` (메인), `tauri.[platform].conf.json` (플랫폼별)
|
|
110
|
+
Capabilities: `src-tauri/capabilities/` (JSON/TOML)
|
|
111
|
+
Permissions: `<plugin>:allow-<command>`, `<plugin>:deny-<command>`
|
|
112
|
+
|
|
113
|
+
</conventions>
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
<quick_patterns>
|
|
118
|
+
|
|
119
|
+
```rust
|
|
120
|
+
// Rust Command 정의
|
|
121
|
+
#[tauri::command]
|
|
122
|
+
async fn greet(name: String) -> Result<String, String> {
|
|
123
|
+
Ok(format!("Hello, {}!", name))
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// State 사용
|
|
127
|
+
#[tauri::command]
|
|
128
|
+
async fn increment(state: State<'_, Mutex<AppState>>) -> Result<u32, String> {
|
|
129
|
+
let mut s = state.lock().unwrap();
|
|
130
|
+
s.counter += 1;
|
|
131
|
+
Ok(s.counter)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// main.rs에 등록
|
|
135
|
+
fn main() {
|
|
136
|
+
tauri::Builder::default()
|
|
137
|
+
.plugin(tauri_plugin_shell::init())
|
|
138
|
+
.setup(|app| {
|
|
139
|
+
app.manage(Mutex::new(AppState { counter: 0 }));
|
|
140
|
+
Ok(())
|
|
141
|
+
})
|
|
142
|
+
.invoke_handler(tauri::generate_handler![greet, increment])
|
|
143
|
+
.run(tauri::generate_context!())
|
|
144
|
+
.expect("error while running tauri application");
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
// 프론트엔드 invoke
|
|
150
|
+
import { invoke } from '@tauri-apps/api/core';
|
|
151
|
+
|
|
152
|
+
const greeting = await invoke<string>('greet', { name: 'World' });
|
|
153
|
+
|
|
154
|
+
// Event 리스닝
|
|
155
|
+
import { listen } from '@tauri-apps/api/event';
|
|
156
|
+
const unlisten = await listen<string>('download-progress', (event) => {
|
|
157
|
+
console.log(event.payload);
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
// src-tauri/capabilities/default.json
|
|
163
|
+
{
|
|
164
|
+
"identifier": "default",
|
|
165
|
+
"description": "기본 앱 권한",
|
|
166
|
+
"windows": ["main"],
|
|
167
|
+
"permissions": [
|
|
168
|
+
"core:default",
|
|
169
|
+
"shell:allow-open"
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
</quick_patterns>
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
<docs_structure>
|
|
179
|
+
```
|
|
180
|
+
docs/
|
|
181
|
+
├── guides/
|
|
182
|
+
│ ├── getting-started.md # 설치, 프로젝트 생성, 개발 시작
|
|
183
|
+
│ ├── mobile.md # iOS/Android 개발 가이드
|
|
184
|
+
│ └── distribution.md # 빌드, 코드 서명, 배포
|
|
185
|
+
└── library/
|
|
186
|
+
└── tauri/
|
|
187
|
+
└── index.md # Tauri 핵심 API + IPC + Security
|
|
188
|
+
```
|
|
189
|
+
</docs_structure>
|