@kood/claude-code 0.1.6 → 0.1.9
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 +109 -216
- package/package.json +8 -2
- package/templates/hono/CLAUDE.md +59 -328
- package/templates/hono/docs/architecture/architecture.md +93 -747
- package/templates/hono/docs/deployment/cloudflare.md +59 -513
- package/templates/hono/docs/deployment/docker.md +41 -356
- package/templates/hono/docs/deployment/index.md +54 -190
- package/templates/hono/docs/deployment/railway.md +36 -306
- package/templates/hono/docs/deployment/vercel.md +49 -434
- package/templates/hono/docs/library/ai-sdk/index.md +53 -290
- package/templates/hono/docs/library/ai-sdk/openrouter.md +19 -387
- package/templates/hono/docs/library/ai-sdk/providers.md +28 -394
- package/templates/hono/docs/library/ai-sdk/streaming.md +52 -353
- package/templates/hono/docs/library/ai-sdk/structured-output.md +63 -395
- package/templates/hono/docs/library/ai-sdk/tools.md +62 -431
- package/templates/hono/docs/library/hono/env-setup.md +24 -313
- package/templates/hono/docs/library/hono/error-handling.md +34 -295
- package/templates/hono/docs/library/hono/index.md +29 -121
- package/templates/hono/docs/library/hono/middleware.md +21 -188
- package/templates/hono/docs/library/hono/rpc.md +40 -341
- package/templates/hono/docs/library/hono/validation.md +35 -195
- package/templates/hono/docs/library/pino/index.md +42 -333
- package/templates/hono/docs/library/prisma/cloudflare-d1.md +64 -367
- package/templates/hono/docs/library/prisma/config.md +19 -260
- package/templates/hono/docs/library/prisma/index.md +67 -320
- package/templates/hono/docs/library/zod/index.md +53 -257
- package/templates/npx/CLAUDE.md +62 -274
- package/templates/npx/docs/references/patterns.md +160 -0
- package/templates/tanstack-start/CLAUDE.md +100 -256
- package/templates/tanstack-start/docs/architecture/architecture.md +44 -589
- package/templates/tanstack-start/docs/deployment/cloudflare.md +37 -424
- package/templates/tanstack-start/docs/deployment/index.md +57 -286
- package/templates/tanstack-start/docs/deployment/nitro.md +36 -318
- package/templates/tanstack-start/docs/deployment/railway.md +40 -409
- package/templates/tanstack-start/docs/deployment/vercel.md +43 -465
- package/templates/tanstack-start/docs/design/components.md +77 -311
- package/templates/tanstack-start/docs/design/index.md +113 -69
- package/templates/tanstack-start/docs/design/safe-area.md +51 -250
- package/templates/tanstack-start/docs/design/tailwind-setup.md +45 -359
- package/templates/tanstack-start/docs/guides/conventions.md +103 -0
- package/templates/tanstack-start/docs/guides/env-setup.md +34 -340
- package/templates/tanstack-start/docs/guides/getting-started.md +22 -209
- package/templates/tanstack-start/docs/guides/hooks.md +166 -0
- package/templates/tanstack-start/docs/guides/routes.md +166 -0
- package/templates/tanstack-start/docs/guides/services.md +143 -0
- package/templates/tanstack-start/docs/library/better-auth/2fa.md +27 -115
- package/templates/tanstack-start/docs/library/better-auth/advanced.md +22 -105
- package/templates/tanstack-start/docs/library/better-auth/index.md +17 -66
- package/templates/tanstack-start/docs/library/better-auth/plugins.md +11 -88
- package/templates/tanstack-start/docs/library/better-auth/session.md +12 -92
- package/templates/tanstack-start/docs/library/better-auth/setup.md +9 -91
- package/templates/tanstack-start/docs/library/prisma/cloudflare-d1.md +30 -358
- package/templates/tanstack-start/docs/library/prisma/config.md +27 -327
- package/templates/tanstack-start/docs/library/prisma/crud.md +46 -174
- package/templates/tanstack-start/docs/library/prisma/index.md +23 -113
- package/templates/tanstack-start/docs/library/prisma/relations.md +31 -153
- package/templates/tanstack-start/docs/library/prisma/schema.md +40 -217
- package/templates/tanstack-start/docs/library/prisma/setup.md +12 -112
- package/templates/tanstack-start/docs/library/prisma/transactions.md +20 -110
- package/templates/tanstack-start/docs/library/tanstack-query/index.md +26 -97
- package/templates/tanstack-start/docs/library/tanstack-query/invalidation.md +28 -107
- package/templates/tanstack-start/docs/library/tanstack-query/optimistic-updates.md +44 -146
- package/templates/tanstack-start/docs/library/tanstack-query/use-mutation.md +33 -127
- package/templates/tanstack-start/docs/library/tanstack-query/use-query.md +49 -149
- package/templates/tanstack-start/docs/library/tanstack-start/auth-patterns.md +19 -112
- package/templates/tanstack-start/docs/library/tanstack-start/index.md +33 -80
- package/templates/tanstack-start/docs/library/tanstack-start/middleware.md +28 -106
- package/templates/tanstack-start/docs/library/tanstack-start/routing.md +21 -118
- package/templates/tanstack-start/docs/library/tanstack-start/server-functions.md +34 -246
- package/templates/tanstack-start/docs/library/tanstack-start/setup.md +6 -39
- package/templates/tanstack-start/docs/library/zod/complex-types.md +32 -156
- package/templates/tanstack-start/docs/library/zod/index.md +31 -144
- package/templates/tanstack-start/docs/library/zod/transforms.md +20 -129
- package/templates/tanstack-start/docs/library/zod/validation.md +39 -155
- package/templates/hono/docs/commands/git.md +0 -145
- package/templates/hono/docs/mcp/context7.md +0 -106
- package/templates/hono/docs/mcp/index.md +0 -176
- package/templates/hono/docs/mcp/sequential-thinking.md +0 -101
- package/templates/hono/docs/mcp/serena.md +0 -269
- package/templates/hono/docs/mcp/sgrep.md +0 -105
- package/templates/hono/docs/skills/gemini-review/SKILL.md +0 -220
- package/templates/hono/docs/skills/gemini-review/references/checklists.md +0 -136
- package/templates/hono/docs/skills/gemini-review/references/prompt-templates.md +0 -303
- package/templates/npx/docs/commands/git.md +0 -145
- package/templates/npx/docs/mcp/index.md +0 -60
- package/templates/npx/docs/skills/gemini-review/SKILL.md +0 -220
- package/templates/npx/docs/skills/gemini-review/references/checklists.md +0 -134
- package/templates/npx/docs/skills/gemini-review/references/prompt-templates.md +0 -301
- package/templates/tanstack-start/docs/commands/git.md +0 -145
- package/templates/tanstack-start/docs/design/accessibility.md +0 -433
- package/templates/tanstack-start/docs/design/color.md +0 -235
- package/templates/tanstack-start/docs/design/spacing.md +0 -341
- package/templates/tanstack-start/docs/design/typography.md +0 -324
- package/templates/tanstack-start/docs/guides/best-practices.md +0 -950
- package/templates/tanstack-start/docs/guides/husky-lint-staged.md +0 -303
- package/templates/tanstack-start/docs/guides/prettier.md +0 -189
- package/templates/tanstack-start/docs/guides/project-templates.md +0 -710
- package/templates/tanstack-start/docs/library/tanstack-query/setup.md +0 -107
- package/templates/tanstack-start/docs/library/zod/basic-types.md +0 -186
- package/templates/tanstack-start/docs/mcp/context7.md +0 -204
- package/templates/tanstack-start/docs/mcp/index.md +0 -177
- package/templates/tanstack-start/docs/mcp/sequential-thinking.md +0 -180
- package/templates/tanstack-start/docs/mcp/serena.md +0 -269
- package/templates/tanstack-start/docs/mcp/sgrep.md +0 -174
- package/templates/tanstack-start/docs/skills/gemini-review/SKILL.md +0 -220
- package/templates/tanstack-start/docs/skills/gemini-review/references/checklists.md +0 -144
- package/templates/tanstack-start/docs/skills/gemini-review/references/prompt-templates.md +0 -292
|
@@ -1,374 +1,125 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 환경 변수 설정
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
TanStack Start는 Vite 기반으로 동작하며, 환경별 `.env` 파일을 통해 환경 변수를 관리합니다.
|
|
6
|
-
|
|
7
|
-
---
|
|
3
|
+
TanStack Start (Vite 기반) 환경 변수 관리.
|
|
8
4
|
|
|
9
5
|
## 핵심 개념
|
|
10
6
|
|
|
11
|
-
### 서버 vs 클라이언트 환경 변수
|
|
12
|
-
|
|
13
7
|
```
|
|
14
8
|
서버 전용 → process.env.DATABASE_URL (노출 X)
|
|
15
9
|
클라이언트용 → import.meta.env.VITE_* (노출 O)
|
|
16
10
|
```
|
|
17
11
|
|
|
18
|
-
| 접근 방식 |
|
|
19
|
-
|
|
20
|
-
| `process.env.*` | Server Function
|
|
21
|
-
| `import.meta.env.VITE_*` | 클라이언트 + 서버 | 공개
|
|
22
|
-
|
|
23
|
-
⚠️ **중요**: `VITE_` 접두사가 없는 변수는 클라이언트에 노출되지 않습니다.
|
|
24
|
-
|
|
25
|
-
---
|
|
12
|
+
| 접근 방식 | 위치 | 용도 |
|
|
13
|
+
|-----------|------|------|
|
|
14
|
+
| `process.env.*` | Server Function | DB, API 키, 시크릿 |
|
|
15
|
+
| `import.meta.env.VITE_*` | 클라이언트 + 서버 | 공개 설정 |
|
|
26
16
|
|
|
27
17
|
## 환경 파일 구조
|
|
28
18
|
|
|
29
19
|
```
|
|
30
|
-
|
|
31
|
-
├── .env
|
|
32
|
-
├── .env.
|
|
33
|
-
├── .env.
|
|
34
|
-
|
|
35
|
-
├── .env.development.local # 개발 로컬 오버라이드 (커밋 X)
|
|
36
|
-
├── .env.production.local # 프로덕션 로컬 오버라이드 (커밋 X)
|
|
37
|
-
└── app/
|
|
38
|
-
└── config/
|
|
39
|
-
└── env.ts # 환경 변수 검증 및 타입
|
|
20
|
+
├── .env # 기본 (커밋 O)
|
|
21
|
+
├── .env.development # 개발 (커밋 O)
|
|
22
|
+
├── .env.production # 프로덕션 (커밋 O)
|
|
23
|
+
├── .env.local # 로컬 오버라이드 (커밋 X)
|
|
24
|
+
└── app/config/env.ts # 검증 및 타입
|
|
40
25
|
```
|
|
41
26
|
|
|
42
|
-
### 로드 우선순위
|
|
27
|
+
### 로드 우선순위
|
|
43
28
|
|
|
44
29
|
```
|
|
45
30
|
1. .env.{mode}.local # 최우선 (gitignore)
|
|
46
|
-
2. .env.local # 로컬 오버라이드
|
|
31
|
+
2. .env.local # 로컬 오버라이드
|
|
47
32
|
3. .env.{mode} # 환경별 설정
|
|
48
33
|
4. .env # 기본 설정
|
|
49
34
|
```
|
|
50
35
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
## 환경 변수 파일 예시
|
|
36
|
+
## 환경 파일 예시
|
|
54
37
|
|
|
55
|
-
### .env (
|
|
38
|
+
### .env.local (gitignore, 시크릿)
|
|
56
39
|
|
|
57
40
|
```env
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
# 클라이언트 공개 설정 (VITE_ 접두사 필수)
|
|
63
|
-
VITE_APP_NAME=My TanStack App
|
|
64
|
-
VITE_API_URL=https://api.example.com
|
|
65
|
-
|
|
66
|
-
# 서버 설정 템플릿 (실제 값은 .env.local에서 오버라이드)
|
|
67
|
-
DATABASE_URL=postgresql://localhost:5432/myapp_dev
|
|
68
|
-
REDIS_URL=redis://localhost:6379
|
|
41
|
+
DATABASE_URL=postgresql://user:password@localhost:5432/myapp
|
|
42
|
+
JWT_SECRET=your-super-secret-jwt-key-at-least-32-chars
|
|
43
|
+
OPENAI_API_KEY=sk-xxx
|
|
69
44
|
```
|
|
70
45
|
|
|
71
46
|
### .env.development
|
|
72
47
|
|
|
73
48
|
```env
|
|
74
|
-
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
75
|
-
# 개발 환경 설정
|
|
76
|
-
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
77
|
-
|
|
78
49
|
NODE_ENV=development
|
|
79
|
-
|
|
80
|
-
# 클라이언트 공개 설정
|
|
81
50
|
VITE_APP_NAME=My App (Dev)
|
|
82
51
|
VITE_API_URL=http://localhost:3001/api
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
# 서버 설정
|
|
86
|
-
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/myapp_dev
|
|
87
|
-
DATABASE_POOL_SIZE=5
|
|
88
|
-
|
|
89
|
-
# 개발용 설정
|
|
90
|
-
LOG_LEVEL=debug
|
|
91
|
-
CORS_ORIGIN=http://localhost:3000
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
### .env.production
|
|
95
|
-
|
|
96
|
-
```env
|
|
97
|
-
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
98
|
-
# 프로덕션 환경 설정
|
|
99
|
-
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
100
|
-
|
|
101
|
-
NODE_ENV=production
|
|
102
|
-
|
|
103
|
-
# 클라이언트 공개 설정
|
|
104
|
-
VITE_APP_NAME=My App
|
|
105
|
-
VITE_API_URL=https://api.myapp.com
|
|
106
|
-
VITE_DEBUG=false
|
|
107
|
-
|
|
108
|
-
# 서버 설정 (실제 값은 CI/CD 또는 호스팅 환경에서 주입)
|
|
109
|
-
DATABASE_POOL_SIZE=20
|
|
110
|
-
|
|
111
|
-
# 프로덕션 설정
|
|
112
|
-
LOG_LEVEL=info
|
|
113
|
-
CORS_ORIGIN=https://myapp.com
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
### .env.local (gitignore, 실제 시크릿)
|
|
117
|
-
|
|
118
|
-
```env
|
|
119
|
-
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
120
|
-
# 로컬 개발용 시크릿 (절대 커밋 금지!)
|
|
121
|
-
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
122
|
-
|
|
123
|
-
# 데이터베이스
|
|
124
|
-
DATABASE_URL=postgresql://user:realpassword@localhost:5432/myapp_local
|
|
125
|
-
|
|
126
|
-
# 인증
|
|
127
|
-
JWT_SECRET=your-super-secret-jwt-key-at-least-32-chars
|
|
128
|
-
AUTH_SECRET=your-auth-secret-key
|
|
129
|
-
|
|
130
|
-
# 외부 서비스 API 키
|
|
131
|
-
OPENAI_API_KEY=sk-xxx
|
|
132
|
-
STRIPE_SECRET_KEY=sk_test_xxx
|
|
52
|
+
DATABASE_URL=postgresql://localhost:5432/myapp_dev
|
|
133
53
|
```
|
|
134
54
|
|
|
135
|
-
---
|
|
136
|
-
|
|
137
55
|
## 타입 안전한 환경 변수 (Zod)
|
|
138
56
|
|
|
139
|
-
### app/config/env.ts
|
|
140
|
-
|
|
141
57
|
```typescript
|
|
142
58
|
// app/config/env.ts
|
|
143
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
144
|
-
// 환경 변수 검증 및 타입 정의
|
|
145
|
-
// 서버/클라이언트 환경 변수를 분리하여 관리합니다
|
|
146
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
147
59
|
import { z } from 'zod'
|
|
148
60
|
|
|
149
|
-
// 서버 환경 변수 스키마
|
|
150
61
|
const serverEnvSchema = z.object({
|
|
151
62
|
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
|
|
152
|
-
|
|
153
|
-
// 데이터베이스
|
|
154
63
|
DATABASE_URL: z.string().url(),
|
|
155
|
-
DATABASE_POOL_SIZE: z.coerce.number().default(10),
|
|
156
|
-
|
|
157
|
-
// 인증
|
|
158
64
|
JWT_SECRET: z.string().min(32),
|
|
159
|
-
AUTH_SECRET: z.string().min(16).optional(),
|
|
160
|
-
|
|
161
|
-
// 외부 서비스 (선택적)
|
|
162
65
|
OPENAI_API_KEY: z.string().optional(),
|
|
163
|
-
STRIPE_SECRET_KEY: z.string().optional(),
|
|
164
|
-
|
|
165
|
-
// 설정
|
|
166
|
-
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
|
|
167
|
-
CORS_ORIGIN: z.string().default('*'),
|
|
168
66
|
})
|
|
169
67
|
|
|
170
|
-
// 클라이언트 환경 변수 스키마 (VITE_ 접두사)
|
|
171
68
|
const clientEnvSchema = z.object({
|
|
172
69
|
VITE_APP_NAME: z.string(),
|
|
173
70
|
VITE_API_URL: z.string().url(),
|
|
174
|
-
VITE_DEBUG: z.coerce.boolean().default(false),
|
|
175
71
|
})
|
|
176
72
|
|
|
177
|
-
// 타입 추출
|
|
178
73
|
export type ServerEnv = z.infer<typeof serverEnvSchema>
|
|
179
74
|
export type ClientEnv = z.infer<typeof clientEnvSchema>
|
|
180
75
|
|
|
181
|
-
// 서버 환경 변수 파싱 (Server Function에서만 호출)
|
|
182
|
-
const parseServerEnv = (): ServerEnv => {
|
|
183
|
-
const result = serverEnvSchema.safeParse(process.env)
|
|
184
|
-
|
|
185
|
-
if (!result.success) {
|
|
186
|
-
console.error('❌ 서버 환경 변수 검증 실패:')
|
|
187
|
-
console.error(result.error.format())
|
|
188
|
-
throw new Error('Server environment validation failed')
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return result.data
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// 클라이언트 환경 변수 파싱
|
|
195
|
-
const parseClientEnv = (): ClientEnv => {
|
|
196
|
-
const result = clientEnvSchema.safeParse(import.meta.env)
|
|
197
|
-
|
|
198
|
-
if (!result.success) {
|
|
199
|
-
console.error('❌ 클라이언트 환경 변수 검증 실패:')
|
|
200
|
-
console.error(result.error.format())
|
|
201
|
-
throw new Error('Client environment validation failed')
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
return result.data
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Export (서버 환경 변수는 lazy evaluation)
|
|
208
76
|
let _serverEnv: ServerEnv | null = null
|
|
209
77
|
|
|
210
78
|
export const getServerEnv = (): ServerEnv => {
|
|
211
79
|
if (!_serverEnv) {
|
|
212
|
-
|
|
80
|
+
const result = serverEnvSchema.safeParse(process.env)
|
|
81
|
+
if (!result.success) {
|
|
82
|
+
console.error('❌ 서버 환경 변수 검증 실패:', result.error.format())
|
|
83
|
+
throw new Error('Server environment validation failed')
|
|
84
|
+
}
|
|
85
|
+
_serverEnv = result.data
|
|
213
86
|
}
|
|
214
87
|
return _serverEnv
|
|
215
88
|
}
|
|
216
89
|
|
|
217
|
-
export const clientEnv =
|
|
90
|
+
export const clientEnv = clientEnvSchema.parse(import.meta.env)
|
|
218
91
|
```
|
|
219
92
|
|
|
220
|
-
---
|
|
221
|
-
|
|
222
93
|
## 사용 예시
|
|
223
94
|
|
|
224
|
-
### Server Function
|
|
95
|
+
### Server Function
|
|
225
96
|
|
|
226
97
|
```typescript
|
|
227
|
-
// app/server-functions/users.ts
|
|
228
98
|
import { createServerFn } from '@tanstack/react-start'
|
|
229
99
|
import { getServerEnv } from '@/config/env'
|
|
230
100
|
|
|
231
101
|
export const getUsers = createServerFn({ method: 'GET' })
|
|
232
102
|
.handler(async () => {
|
|
233
103
|
const env = getServerEnv()
|
|
234
|
-
|
|
235
|
-
// ✅ 서버 전용 환경 변수 사용
|
|
236
|
-
const config = {
|
|
237
|
-
url: env.DATABASE_URL,
|
|
238
|
-
maxConnections: env.DATABASE_POOL_SIZE,
|
|
239
|
-
ssl: env.NODE_ENV === 'production',
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const db = await createConnection(config)
|
|
243
|
-
return db.user.findMany()
|
|
104
|
+
// env.DATABASE_URL 사용
|
|
244
105
|
})
|
|
245
106
|
```
|
|
246
107
|
|
|
247
|
-
### 클라이언트
|
|
108
|
+
### 클라이언트
|
|
248
109
|
|
|
249
110
|
```tsx
|
|
250
|
-
// app/components/AppHeader.tsx
|
|
251
111
|
import { clientEnv } from '@/config/env'
|
|
252
112
|
|
|
253
|
-
export const AppHeader = () =>
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
{/* ✅ VITE_ 접두사 변수만 접근 가능 */}
|
|
257
|
-
<h1>{clientEnv.VITE_APP_NAME}</h1>
|
|
258
|
-
|
|
259
|
-
{clientEnv.VITE_DEBUG && (
|
|
260
|
-
<span className="text-red-500">Debug Mode</span>
|
|
261
|
-
)}
|
|
262
|
-
</header>
|
|
263
|
-
)
|
|
264
|
-
}
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### 직접 접근 (검증 없이)
|
|
268
|
-
|
|
269
|
-
```tsx
|
|
270
|
-
// Server Function 내부
|
|
271
|
-
const dbUrl = process.env.DATABASE_URL // ✅ 서버에서만
|
|
272
|
-
|
|
273
|
-
// 클라이언트 컴포넌트
|
|
274
|
-
const appName = import.meta.env.VITE_APP_NAME // ✅ VITE_ 접두사만
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
---
|
|
278
|
-
|
|
279
|
-
## 인증 설정 예시
|
|
280
|
-
|
|
281
|
-
### 서버 측 인증 설정
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
// app/lib/auth.ts
|
|
285
|
-
import { getServerEnv } from '@/config/env'
|
|
286
|
-
|
|
287
|
-
export const getAuthConfig = () => {
|
|
288
|
-
const env = getServerEnv()
|
|
289
|
-
|
|
290
|
-
return {
|
|
291
|
-
secret: env.AUTH_SECRET,
|
|
292
|
-
providers: {
|
|
293
|
-
auth0: {
|
|
294
|
-
domain: process.env.AUTH0_DOMAIN,
|
|
295
|
-
clientId: process.env.AUTH0_CLIENT_ID,
|
|
296
|
-
clientSecret: process.env.AUTH0_CLIENT_SECRET, // ✅ 서버 전용
|
|
297
|
-
},
|
|
298
|
-
},
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
### 클라이언트 측 인증 Provider
|
|
304
|
-
|
|
305
|
-
```tsx
|
|
306
|
-
// app/components/AuthProvider.tsx
|
|
307
|
-
export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
|
308
|
-
return (
|
|
309
|
-
<Auth0Provider
|
|
310
|
-
domain={import.meta.env.VITE_AUTH0_DOMAIN}
|
|
311
|
-
clientId={import.meta.env.VITE_AUTH0_CLIENT_ID}
|
|
312
|
-
// ❌ clientSecret은 여기에 없음 - 서버에만 존재
|
|
313
|
-
>
|
|
314
|
-
{children}
|
|
315
|
-
</Auth0Provider>
|
|
316
|
-
)
|
|
317
|
-
}
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
---
|
|
321
|
-
|
|
322
|
-
## 필수 환경 변수 검증
|
|
323
|
-
|
|
324
|
-
### 앱 시작 시 검증
|
|
325
|
-
|
|
326
|
-
```typescript
|
|
327
|
-
// app/config/validation.ts
|
|
328
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
329
|
-
// 필수 환경 변수 검증
|
|
330
|
-
// 앱 시작 시 누락된 환경 변수를 조기에 발견합니다
|
|
331
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
332
|
-
|
|
333
|
-
const requiredServerEnv = [
|
|
334
|
-
'DATABASE_URL',
|
|
335
|
-
'JWT_SECRET',
|
|
336
|
-
] as const
|
|
337
|
-
|
|
338
|
-
const requiredClientEnv = [
|
|
339
|
-
'VITE_APP_NAME',
|
|
340
|
-
'VITE_API_URL',
|
|
341
|
-
] as const
|
|
342
|
-
|
|
343
|
-
export const validateEnv = () => {
|
|
344
|
-
// 서버 환경 변수 검증
|
|
345
|
-
for (const key of requiredServerEnv) {
|
|
346
|
-
if (!process.env[key]) {
|
|
347
|
-
throw new Error(`❌ Missing required server env: ${key}`)
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// 클라이언트 환경 변수 검증
|
|
352
|
-
for (const key of requiredClientEnv) {
|
|
353
|
-
if (!import.meta.env[key]) {
|
|
354
|
-
throw new Error(`❌ Missing required client env: ${key}`)
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
console.log('✅ Environment variables validated')
|
|
359
|
-
}
|
|
113
|
+
export const AppHeader = () => (
|
|
114
|
+
<h1>{clientEnv.VITE_APP_NAME}</h1>
|
|
115
|
+
)
|
|
360
116
|
```
|
|
361
117
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
## .gitignore 설정
|
|
118
|
+
## .gitignore
|
|
365
119
|
|
|
366
120
|
```gitignore
|
|
367
|
-
# 환경 변수 파일
|
|
368
121
|
.env.local
|
|
369
122
|
.env.*.local
|
|
370
|
-
.env.development.local
|
|
371
|
-
.env.production.local
|
|
372
123
|
|
|
373
124
|
# 커밋해도 되는 파일 (시크릿 없음)
|
|
374
125
|
!.env
|
|
@@ -376,53 +127,7 @@ export const validateEnv = () => {
|
|
|
376
127
|
!.env.production
|
|
377
128
|
```
|
|
378
129
|
|
|
379
|
-
|
|
380
|
-
- 실제 시크릿은 `.env.local` 또는 CI/CD 환경 변수로 관리
|
|
381
|
-
- `.env.*` 파일에는 플레이스홀더나 기본값만 포함
|
|
382
|
-
|
|
383
|
-
---
|
|
384
|
-
|
|
385
|
-
## 빌드 모드
|
|
386
|
-
|
|
387
|
-
### 개발 서버
|
|
388
|
-
|
|
389
|
-
```bash
|
|
390
|
-
# 기본 development 모드
|
|
391
|
-
npm run dev
|
|
392
|
-
|
|
393
|
-
# .env.development + .env 로드
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
### 프로덕션 빌드
|
|
397
|
-
|
|
398
|
-
```bash
|
|
399
|
-
# 기본 production 모드
|
|
400
|
-
npm run build
|
|
401
|
-
|
|
402
|
-
# .env.production + .env 로드
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
### 커스텀 모드
|
|
406
|
-
|
|
407
|
-
```bash
|
|
408
|
-
# staging 모드로 빌드
|
|
409
|
-
npm run build -- --mode staging
|
|
410
|
-
|
|
411
|
-
# .env.staging + .env 로드
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
```env
|
|
415
|
-
# .env.staging
|
|
416
|
-
NODE_ENV=production
|
|
417
|
-
VITE_APP_NAME=My App (Staging)
|
|
418
|
-
VITE_API_URL=https://staging-api.myapp.com
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
---
|
|
422
|
-
|
|
423
|
-
## TypeScript 타입 정의
|
|
424
|
-
|
|
425
|
-
### vite-env.d.ts
|
|
130
|
+
## TypeScript 타입
|
|
426
131
|
|
|
427
132
|
```typescript
|
|
428
133
|
// app/vite-env.d.ts
|
|
@@ -431,20 +136,9 @@ VITE_API_URL=https://staging-api.myapp.com
|
|
|
431
136
|
interface ImportMetaEnv {
|
|
432
137
|
readonly VITE_APP_NAME: string
|
|
433
138
|
readonly VITE_API_URL: string
|
|
434
|
-
readonly VITE_DEBUG: string
|
|
435
|
-
readonly VITE_AUTH0_DOMAIN?: string
|
|
436
|
-
readonly VITE_AUTH0_CLIENT_ID?: string
|
|
437
139
|
}
|
|
438
140
|
|
|
439
141
|
interface ImportMeta {
|
|
440
142
|
readonly env: ImportMetaEnv
|
|
441
143
|
}
|
|
442
144
|
```
|
|
443
|
-
|
|
444
|
-
---
|
|
445
|
-
|
|
446
|
-
## 관련 문서
|
|
447
|
-
|
|
448
|
-
- [Best Practices](./best-practices.md)
|
|
449
|
-
- [Server Functions](../library/tanstack-start/server-functions.md)
|
|
450
|
-
- [Vite 환경 변수 공식 문서](https://vitejs.dev/guide/env-and-mode.html)
|