@kood/claude-code 0.1.7 → 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 +118 -3
- package/package.json +8 -2
- package/templates/hono/CLAUDE.md +53 -326
- 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 +49 -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 +24 -122
- 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 +64 -320
- package/templates/hono/docs/library/zod/index.md +53 -257
- package/templates/npx/CLAUDE.md +58 -276
- package/templates/npx/docs/references/patterns.md +160 -0
- package/templates/tanstack-start/CLAUDE.md +0 -4
- package/templates/tanstack-start/docs/architecture/architecture.md +44 -589
- package/templates/tanstack-start/docs/design/index.md +119 -12
- 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/tanstack-query/index.md +18 -2
- package/templates/tanstack-start/docs/library/zod/index.md +16 -1
- package/templates/tanstack-start/docs/design/accessibility.md +0 -163
- package/templates/tanstack-start/docs/design/color.md +0 -93
- package/templates/tanstack-start/docs/design/spacing.md +0 -122
- package/templates/tanstack-start/docs/design/typography.md +0 -80
- 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 -48
- package/templates/tanstack-start/docs/library/zod/basic-types.md +0 -74
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
# Nitro
|
|
1
|
+
# Nitro - Cloudflare 배포
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
Cloudflare Workers/Pages를 사용하여 Hono + Nitro 애플리케이션을 Edge에 배포합니다.
|
|
3
|
+
> Cloudflare Workers/Pages Edge 배포
|
|
6
4
|
|
|
7
5
|
---
|
|
8
6
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
### Cloudflare Workers
|
|
7
|
+
## Workers 설정
|
|
12
8
|
|
|
13
9
|
```typescript
|
|
14
10
|
// nitro.config.ts
|
|
@@ -24,468 +20,155 @@ export default defineNitroConfig({
|
|
|
24
20
|
});
|
|
25
21
|
```
|
|
26
22
|
|
|
27
|
-
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Pages 설정
|
|
28
26
|
|
|
29
27
|
```typescript
|
|
30
28
|
// nitro.config.ts
|
|
31
|
-
import { defineNitroConfig } from "nitro/config";
|
|
32
|
-
|
|
33
29
|
export default defineNitroConfig({
|
|
34
30
|
preset: "cloudflare_pages",
|
|
35
31
|
compatibilityDate: "2024-09-19",
|
|
36
32
|
cloudflare: {
|
|
37
33
|
deployConfig: true,
|
|
38
|
-
|
|
34
|
+
pages: { staticDir: "public" },
|
|
39
35
|
},
|
|
40
36
|
});
|
|
41
37
|
```
|
|
42
38
|
|
|
43
|
-
```bash
|
|
44
|
-
# Wrangler CLI 배포
|
|
45
|
-
wrangler login
|
|
46
|
-
wrangler deploy
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## Cloudflare Workers vs Pages
|
|
52
|
-
|
|
53
|
-
| 기능 | Workers | Pages |
|
|
54
|
-
|------|---------|-------|
|
|
55
|
-
| 용도 | 순수 API/서버리스 | 정적 사이트 + API |
|
|
56
|
-
| 정적 파일 | ❌ | ✅ |
|
|
57
|
-
| 무료 요청 | 100,000/일 | 무제한 정적 |
|
|
58
|
-
| 커스텀 도메인 | ✅ | ✅ |
|
|
59
|
-
| D1/KV/R2 | ✅ | ✅ |
|
|
60
|
-
|
|
61
39
|
---
|
|
62
40
|
|
|
63
|
-
##
|
|
64
|
-
|
|
65
|
-
### nitro.config.ts
|
|
66
|
-
|
|
67
|
-
```typescript
|
|
68
|
-
// nitro.config.ts
|
|
69
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
70
|
-
// Cloudflare Workers 배포용 Nitro 설정
|
|
71
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
72
|
-
import { defineNitroConfig } from "nitro/config";
|
|
73
|
-
|
|
74
|
-
export default defineNitroConfig({
|
|
75
|
-
// Cloudflare Workers (ES Module 형식)
|
|
76
|
-
preset: "cloudflare_module",
|
|
77
|
-
|
|
78
|
-
// 호환성 날짜 (필수)
|
|
79
|
-
compatibilityDate: "2024-09-19",
|
|
80
|
-
|
|
81
|
-
// Cloudflare 설정
|
|
82
|
-
cloudflare: {
|
|
83
|
-
// wrangler.toml 자동 생성
|
|
84
|
-
deployConfig: true,
|
|
85
|
-
|
|
86
|
-
// Node.js 호환성 활성화
|
|
87
|
-
nodeCompat: true,
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### wrangler.toml
|
|
41
|
+
## wrangler.toml
|
|
93
42
|
|
|
94
43
|
```toml
|
|
95
|
-
|
|
96
|
-
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
97
|
-
# Cloudflare Workers 설정
|
|
98
|
-
# ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
99
|
-
|
|
100
|
-
name = "hono-nitro-app"
|
|
44
|
+
name = "hono-app"
|
|
101
45
|
main = ".output/server/index.mjs"
|
|
102
46
|
compatibility_date = "2024-09-19"
|
|
103
|
-
|
|
104
|
-
# Node.js 호환성 플래그
|
|
105
47
|
compatibility_flags = ["nodejs_compat"]
|
|
106
48
|
|
|
107
|
-
# 환경 변수
|
|
108
49
|
[vars]
|
|
109
50
|
NODE_ENV = "production"
|
|
110
51
|
|
|
111
|
-
# D1 데이터베이스 바인딩
|
|
112
52
|
[[d1_databases]]
|
|
113
53
|
binding = "DB"
|
|
114
54
|
database_name = "my-database"
|
|
115
|
-
database_id = "
|
|
55
|
+
database_id = "xxx"
|
|
116
56
|
|
|
117
|
-
# KV 네임스페이스 바인딩
|
|
118
57
|
[[kv_namespaces]]
|
|
119
58
|
binding = "KV"
|
|
120
|
-
id = "
|
|
59
|
+
id = "xxx"
|
|
121
60
|
|
|
122
|
-
# R2 버킷 바인딩
|
|
123
61
|
[[r2_buckets]]
|
|
124
62
|
binding = "BUCKET"
|
|
125
63
|
bucket_name = "my-bucket"
|
|
126
|
-
|
|
127
|
-
# 시크릿 (wrangler secret put 으로 설정)
|
|
128
|
-
# API_SECRET = "..."
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## Cloudflare Pages 설정
|
|
134
|
-
|
|
135
|
-
### nitro.config.ts
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
// nitro.config.ts
|
|
139
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
140
|
-
// Cloudflare Pages 배포용 Nitro 설정
|
|
141
|
-
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
142
|
-
import { defineNitroConfig } from "nitro/config";
|
|
143
|
-
|
|
144
|
-
export default defineNitroConfig({
|
|
145
|
-
// Cloudflare Pages
|
|
146
|
-
preset: "cloudflare_pages",
|
|
147
|
-
|
|
148
|
-
// 호환성 날짜
|
|
149
|
-
compatibilityDate: "2024-09-19",
|
|
150
|
-
|
|
151
|
-
// Cloudflare 설정
|
|
152
|
-
cloudflare: {
|
|
153
|
-
deployConfig: true,
|
|
154
|
-
nodeCompat: true,
|
|
155
|
-
|
|
156
|
-
// Pages 전용 설정
|
|
157
|
-
pages: {
|
|
158
|
-
// 정적 파일 디렉토리
|
|
159
|
-
staticDir: "public",
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
});
|
|
163
64
|
```
|
|
164
65
|
|
|
165
66
|
---
|
|
166
67
|
|
|
167
|
-
## 배포
|
|
168
|
-
|
|
169
|
-
### 방법 1: Wrangler CLI (Workers)
|
|
68
|
+
## 배포
|
|
170
69
|
|
|
171
70
|
```bash
|
|
172
|
-
# Wrangler CLI 설치
|
|
173
|
-
npm install -g wrangler
|
|
174
|
-
|
|
175
|
-
# 로그인
|
|
176
71
|
wrangler login
|
|
177
|
-
|
|
178
|
-
# 빌드
|
|
179
72
|
yarn build
|
|
180
|
-
|
|
181
|
-
# 배포
|
|
182
73
|
wrangler deploy
|
|
183
74
|
|
|
184
|
-
#
|
|
185
|
-
wrangler dev
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### 방법 2: GitHub 연동 (Pages)
|
|
189
|
-
|
|
190
|
-
1. **Cloudflare Pages 프로젝트 생성**
|
|
191
|
-
- [Cloudflare Dashboard](https://dash.cloudflare.com) → Pages
|
|
192
|
-
- "Create a project" → "Connect to Git"
|
|
193
|
-
- GitHub 저장소 선택
|
|
194
|
-
|
|
195
|
-
2. **빌드 설정**
|
|
196
|
-
```
|
|
197
|
-
Framework preset: None
|
|
198
|
-
Build command: yarn build
|
|
199
|
-
Build output directory: .output/public
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
3. **환경 변수 설정**
|
|
203
|
-
- Settings → Environment variables
|
|
204
|
-
|
|
205
|
-
### 방법 3: Wrangler CLI (Pages)
|
|
206
|
-
|
|
207
|
-
```bash
|
|
208
|
-
# Pages 배포
|
|
75
|
+
# Pages
|
|
209
76
|
wrangler pages deploy .output/public
|
|
210
|
-
|
|
211
|
-
# 프로덕션 배포
|
|
212
|
-
wrangler pages deploy .output/public --branch main
|
|
213
77
|
```
|
|
214
78
|
|
|
215
79
|
---
|
|
216
80
|
|
|
217
|
-
## Bindings
|
|
81
|
+
## Bindings 사용
|
|
218
82
|
|
|
219
|
-
### D1
|
|
83
|
+
### D1
|
|
220
84
|
|
|
221
85
|
```typescript
|
|
222
|
-
|
|
223
|
-
import { Hono } from "hono";
|
|
224
|
-
|
|
225
|
-
// Cloudflare Bindings 타입 정의
|
|
226
|
-
type Bindings = {
|
|
227
|
-
DB: D1Database;
|
|
228
|
-
};
|
|
229
|
-
|
|
86
|
+
type Bindings = { DB: D1Database };
|
|
230
87
|
const app = new Hono<{ Bindings: Bindings }>();
|
|
231
88
|
|
|
232
|
-
// D1 쿼리
|
|
233
89
|
app.get("/users", async (c) => {
|
|
234
|
-
const { results } = await c.env.DB.prepare(
|
|
235
|
-
"SELECT * FROM users"
|
|
236
|
-
).all();
|
|
237
|
-
|
|
90
|
+
const { results } = await c.env.DB.prepare("SELECT * FROM users").all();
|
|
238
91
|
return c.json(results);
|
|
239
92
|
});
|
|
240
93
|
|
|
241
94
|
app.post("/users", async (c) => {
|
|
242
95
|
const { name, email } = await c.req.json();
|
|
243
|
-
|
|
244
96
|
const result = await c.env.DB.prepare(
|
|
245
97
|
"INSERT INTO users (name, email) VALUES (?, ?)"
|
|
246
|
-
)
|
|
247
|
-
.bind(name, email)
|
|
248
|
-
.run();
|
|
249
|
-
|
|
98
|
+
).bind(name, email).run();
|
|
250
99
|
return c.json({ id: result.meta.last_row_id });
|
|
251
100
|
});
|
|
252
|
-
|
|
253
|
-
export default app;
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
### D1 마이그레이션
|
|
257
|
-
|
|
258
|
-
```bash
|
|
259
|
-
# 마이그레이션 생성
|
|
260
|
-
wrangler d1 migrations create my-database create_users
|
|
261
|
-
|
|
262
|
-
# 마이그레이션 적용
|
|
263
|
-
wrangler d1 migrations apply my-database
|
|
264
|
-
|
|
265
|
-
# 로컬 D1 실행
|
|
266
|
-
wrangler d1 execute my-database --local --command="SELECT * FROM users"
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
```sql
|
|
270
|
-
-- migrations/0001_create_users.sql
|
|
271
|
-
CREATE TABLE users (
|
|
272
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
273
|
-
name TEXT NOT NULL,
|
|
274
|
-
email TEXT UNIQUE NOT NULL,
|
|
275
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
276
|
-
);
|
|
277
101
|
```
|
|
278
102
|
|
|
279
|
-
### KV
|
|
103
|
+
### KV
|
|
280
104
|
|
|
281
105
|
```typescript
|
|
282
|
-
|
|
283
|
-
import { Hono } from "hono";
|
|
284
|
-
|
|
285
|
-
type Bindings = {
|
|
286
|
-
KV: KVNamespace;
|
|
287
|
-
};
|
|
288
|
-
|
|
106
|
+
type Bindings = { KV: KVNamespace };
|
|
289
107
|
const app = new Hono<{ Bindings: Bindings }>();
|
|
290
108
|
|
|
291
|
-
// KV 읽기
|
|
292
109
|
app.get("/cache/:key", async (c) => {
|
|
293
|
-
const
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if (!value) {
|
|
297
|
-
return c.json({ error: "Not found" }, 404);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
return c.json({ key, value: JSON.parse(value) });
|
|
110
|
+
const value = await c.env.KV.get(c.req.param("key"));
|
|
111
|
+
return value ? c.json(JSON.parse(value)) : c.json({ error: "Not found" }, 404);
|
|
301
112
|
});
|
|
302
113
|
|
|
303
|
-
// KV 쓰기
|
|
304
114
|
app.put("/cache/:key", async (c) => {
|
|
305
|
-
const key = c.req.param("key");
|
|
306
115
|
const body = await c.req.json();
|
|
307
|
-
|
|
308
|
-
// TTL 설정 (초 단위)
|
|
309
|
-
await c.env.KV.put(key, JSON.stringify(body), {
|
|
310
|
-
expirationTtl: 3600, // 1시간
|
|
311
|
-
});
|
|
312
|
-
|
|
116
|
+
await c.env.KV.put(c.req.param("key"), JSON.stringify(body), { expirationTtl: 3600 });
|
|
313
117
|
return c.json({ success: true });
|
|
314
118
|
});
|
|
315
|
-
|
|
316
|
-
export default app;
|
|
317
119
|
```
|
|
318
120
|
|
|
319
|
-
### R2
|
|
121
|
+
### R2
|
|
320
122
|
|
|
321
123
|
```typescript
|
|
322
|
-
|
|
323
|
-
import { Hono } from "hono";
|
|
324
|
-
|
|
325
|
-
type Bindings = {
|
|
326
|
-
BUCKET: R2Bucket;
|
|
327
|
-
};
|
|
328
|
-
|
|
124
|
+
type Bindings = { BUCKET: R2Bucket };
|
|
329
125
|
const app = new Hono<{ Bindings: Bindings }>();
|
|
330
126
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const body = await c.req.arrayBuffer();
|
|
335
|
-
|
|
336
|
-
await c.env.BUCKET.put(filename, body, {
|
|
337
|
-
httpMetadata: {
|
|
338
|
-
contentType: c.req.header("Content-Type") || "application/octet-stream",
|
|
339
|
-
},
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
return c.json({ success: true, filename });
|
|
127
|
+
app.post("/upload/:name", async (c) => {
|
|
128
|
+
await c.env.BUCKET.put(c.req.param("name"), await c.req.arrayBuffer());
|
|
129
|
+
return c.json({ success: true });
|
|
343
130
|
});
|
|
344
131
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const object = await c.env.BUCKET.get(filename);
|
|
349
|
-
|
|
350
|
-
if (!object) {
|
|
351
|
-
return c.json({ error: "Not found" }, 404);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
c.header("Content-Type", object.httpMetadata?.contentType || "application/octet-stream");
|
|
355
|
-
return c.body(object.body);
|
|
132
|
+
app.get("/download/:name", async (c) => {
|
|
133
|
+
const obj = await c.env.BUCKET.get(c.req.param("name"));
|
|
134
|
+
return obj ? c.body(obj.body) : c.json({ error: "Not found" }, 404);
|
|
356
135
|
});
|
|
357
|
-
|
|
358
|
-
export default app;
|
|
359
136
|
```
|
|
360
137
|
|
|
361
138
|
---
|
|
362
139
|
|
|
363
|
-
##
|
|
364
|
-
|
|
365
|
-
### wrangler.toml에서 설정
|
|
366
|
-
|
|
367
|
-
```toml
|
|
368
|
-
# wrangler.toml
|
|
369
|
-
[vars]
|
|
370
|
-
NODE_ENV = "production"
|
|
371
|
-
API_BASE_URL = "https://api.example.com"
|
|
372
|
-
|
|
373
|
-
# 환경별 설정
|
|
374
|
-
[env.staging.vars]
|
|
375
|
-
NODE_ENV = "staging"
|
|
376
|
-
API_BASE_URL = "https://staging-api.example.com"
|
|
377
|
-
|
|
378
|
-
[env.production.vars]
|
|
379
|
-
NODE_ENV = "production"
|
|
380
|
-
API_BASE_URL = "https://api.example.com"
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### 시크릿 설정 (CLI)
|
|
140
|
+
## 시크릿
|
|
384
141
|
|
|
385
142
|
```bash
|
|
386
|
-
# 시크릿 추가
|
|
387
143
|
wrangler secret put API_SECRET
|
|
388
|
-
wrangler secret put DATABASE_URL
|
|
389
|
-
|
|
390
|
-
# 시크릿 목록
|
|
391
144
|
wrangler secret list
|
|
392
|
-
|
|
393
|
-
# 시크릿 삭제
|
|
394
|
-
wrangler secret delete API_SECRET
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
### 코드에서 사용
|
|
398
|
-
|
|
399
|
-
```typescript
|
|
400
|
-
// src/server.ts
|
|
401
|
-
import { Hono } from "hono";
|
|
402
|
-
|
|
403
|
-
type Bindings = {
|
|
404
|
-
API_SECRET: string;
|
|
405
|
-
NODE_ENV: string;
|
|
406
|
-
};
|
|
407
|
-
|
|
408
|
-
const app = new Hono<{ Bindings: Bindings }>();
|
|
409
|
-
|
|
410
|
-
app.get("/config", (c) => {
|
|
411
|
-
return c.json({
|
|
412
|
-
environment: c.env.NODE_ENV,
|
|
413
|
-
hasSecret: !!c.env.API_SECRET,
|
|
414
|
-
});
|
|
415
|
-
});
|
|
416
|
-
|
|
417
|
-
export default app;
|
|
418
145
|
```
|
|
419
146
|
|
|
420
147
|
---
|
|
421
148
|
|
|
422
|
-
##
|
|
423
|
-
|
|
424
|
-
### Workers 커스텀 도메인
|
|
149
|
+
## D1 마이그레이션
|
|
425
150
|
|
|
426
|
-
```
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
{ pattern = "api.example.com/*", zone_name = "example.com" }
|
|
430
|
-
]
|
|
431
|
-
|
|
432
|
-
# 또는
|
|
433
|
-
[triggers]
|
|
434
|
-
routes = [
|
|
435
|
-
"api.example.com/*"
|
|
436
|
-
]
|
|
151
|
+
```bash
|
|
152
|
+
wrangler d1 migrations create my-database create_users
|
|
153
|
+
wrangler d1 migrations apply my-database
|
|
437
154
|
```
|
|
438
155
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
156
|
+
```sql
|
|
157
|
+
-- migrations/0001_create_users.sql
|
|
158
|
+
CREATE TABLE users (
|
|
159
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
160
|
+
name TEXT NOT NULL,
|
|
161
|
+
email TEXT UNIQUE NOT NULL
|
|
162
|
+
);
|
|
163
|
+
```
|
|
444
164
|
|
|
445
165
|
---
|
|
446
166
|
|
|
447
|
-
## CI/CD
|
|
448
|
-
|
|
449
|
-
### GitHub Actions (Workers)
|
|
450
|
-
|
|
451
|
-
```yaml
|
|
452
|
-
# .github/workflows/cloudflare-workers.yml
|
|
453
|
-
name: Deploy to Cloudflare Workers
|
|
454
|
-
|
|
455
|
-
on:
|
|
456
|
-
push:
|
|
457
|
-
branches: [main]
|
|
458
|
-
|
|
459
|
-
jobs:
|
|
460
|
-
deploy:
|
|
461
|
-
runs-on: ubuntu-latest
|
|
462
|
-
|
|
463
|
-
steps:
|
|
464
|
-
- uses: actions/checkout@v4
|
|
465
|
-
|
|
466
|
-
- name: Setup Node.js
|
|
467
|
-
uses: actions/setup-node@v4
|
|
468
|
-
with:
|
|
469
|
-
node-version: "20"
|
|
470
|
-
cache: "yarn"
|
|
471
|
-
|
|
472
|
-
- name: Install dependencies
|
|
473
|
-
run: yarn install --frozen-lockfile
|
|
474
|
-
|
|
475
|
-
- name: Build
|
|
476
|
-
run: yarn build
|
|
477
|
-
|
|
478
|
-
- name: Deploy to Cloudflare Workers
|
|
479
|
-
uses: cloudflare/wrangler-action@v3
|
|
480
|
-
with:
|
|
481
|
-
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
### GitHub Actions (Pages)
|
|
167
|
+
## CI/CD
|
|
485
168
|
|
|
486
169
|
```yaml
|
|
487
|
-
# .github/workflows/cloudflare
|
|
488
|
-
name: Deploy to Cloudflare
|
|
170
|
+
# .github/workflows/cloudflare.yml
|
|
171
|
+
name: Deploy to Cloudflare
|
|
489
172
|
|
|
490
173
|
on:
|
|
491
174
|
push:
|
|
@@ -494,172 +177,35 @@ on:
|
|
|
494
177
|
jobs:
|
|
495
178
|
deploy:
|
|
496
179
|
runs-on: ubuntu-latest
|
|
497
|
-
|
|
498
180
|
steps:
|
|
499
181
|
- uses: actions/checkout@v4
|
|
500
|
-
|
|
501
|
-
- name: Setup Node.js
|
|
502
|
-
uses: actions/setup-node@v4
|
|
182
|
+
- uses: actions/setup-node@v4
|
|
503
183
|
with:
|
|
504
184
|
node-version: "20"
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
-
|
|
508
|
-
run: yarn install --frozen-lockfile
|
|
509
|
-
|
|
510
|
-
- name: Build
|
|
511
|
-
run: yarn build
|
|
512
|
-
|
|
513
|
-
- name: Deploy to Cloudflare Pages
|
|
514
|
-
uses: cloudflare/pages-action@v1
|
|
185
|
+
- run: yarn install --frozen-lockfile
|
|
186
|
+
- run: yarn build
|
|
187
|
+
- uses: cloudflare/wrangler-action@v3
|
|
515
188
|
with:
|
|
516
189
|
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
517
|
-
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
|
518
|
-
projectName: my-hono-app
|
|
519
|
-
directory: .output/public
|
|
520
|
-
branch: main
|
|
521
|
-
```
|
|
522
|
-
|
|
523
|
-
---
|
|
524
|
-
|
|
525
|
-
## 성능 최적화
|
|
526
|
-
|
|
527
|
-
### 캐싱 설정
|
|
528
|
-
|
|
529
|
-
```typescript
|
|
530
|
-
// src/server.ts
|
|
531
|
-
import { Hono } from "hono";
|
|
532
|
-
import { cache } from "hono/cache";
|
|
533
|
-
|
|
534
|
-
const app = new Hono();
|
|
535
|
-
|
|
536
|
-
// 캐시 미들웨어
|
|
537
|
-
app.use(
|
|
538
|
-
"/api/public/*",
|
|
539
|
-
cache({
|
|
540
|
-
cacheName: "hono-cache",
|
|
541
|
-
cacheControl: "max-age=3600", // 1시간
|
|
542
|
-
})
|
|
543
|
-
);
|
|
544
|
-
|
|
545
|
-
// 또는 수동으로 Cache API 사용
|
|
546
|
-
app.get("/cached-data", async (c) => {
|
|
547
|
-
const cacheKey = new Request(c.req.url);
|
|
548
|
-
const cache = caches.default;
|
|
549
|
-
|
|
550
|
-
// 캐시 확인
|
|
551
|
-
let response = await cache.match(cacheKey);
|
|
552
|
-
if (response) {
|
|
553
|
-
return response;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
// 데이터 가져오기
|
|
557
|
-
const data = await fetchData();
|
|
558
|
-
|
|
559
|
-
// 응답 생성 및 캐시
|
|
560
|
-
response = c.json(data);
|
|
561
|
-
response.headers.set("Cache-Control", "max-age=3600");
|
|
562
|
-
|
|
563
|
-
c.executionCtx.waitUntil(cache.put(cacheKey, response.clone()));
|
|
564
|
-
|
|
565
|
-
return response;
|
|
566
|
-
});
|
|
567
|
-
|
|
568
|
-
export default app;
|
|
569
|
-
```
|
|
570
|
-
|
|
571
|
-
### Smart Placement
|
|
572
|
-
|
|
573
|
-
```toml
|
|
574
|
-
# wrangler.toml
|
|
575
|
-
# Smart Placement: 데이터 소스에 가까운 위치에서 실행
|
|
576
|
-
[placement]
|
|
577
|
-
mode = "smart"
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
---
|
|
581
|
-
|
|
582
|
-
## 로컬 개발
|
|
583
|
-
|
|
584
|
-
### Wrangler Dev
|
|
585
|
-
|
|
586
|
-
```bash
|
|
587
|
-
# 로컬 개발 서버
|
|
588
|
-
wrangler dev
|
|
589
|
-
|
|
590
|
-
# D1 로컬 모드
|
|
591
|
-
wrangler dev --local --persist
|
|
592
|
-
|
|
593
|
-
# 특정 포트
|
|
594
|
-
wrangler dev --port 3000
|
|
595
|
-
```
|
|
596
|
-
|
|
597
|
-
### Miniflare (고급)
|
|
598
|
-
|
|
599
|
-
```typescript
|
|
600
|
-
// miniflare.config.ts
|
|
601
|
-
import { Miniflare } from "miniflare";
|
|
602
|
-
|
|
603
|
-
const mf = new Miniflare({
|
|
604
|
-
script: ".output/server/index.mjs",
|
|
605
|
-
modules: true,
|
|
606
|
-
d1Databases: ["DB"],
|
|
607
|
-
kvNamespaces: ["KV"],
|
|
608
|
-
r2Buckets: ["BUCKET"],
|
|
609
|
-
});
|
|
610
190
|
```
|
|
611
191
|
|
|
612
192
|
---
|
|
613
193
|
|
|
614
194
|
## 문제 해결
|
|
615
195
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
|
619
|
-
|
|
620
|
-
|
|
|
621
|
-
| "D1 not found" | 바인딩 설정 오류 | wrangler.toml 확인 |
|
|
622
|
-
| "Compatibility date" 오류 | 날짜 형식 오류 | YYYY-MM-DD 형식 확인 |
|
|
623
|
-
| Node.js API 오류 | 호환성 플래그 누락 | `nodejs_compat` 플래그 추가 |
|
|
624
|
-
|
|
625
|
-
### 디버깅
|
|
196
|
+
| 문제 | 해결 |
|
|
197
|
+
|------|------|
|
|
198
|
+
| Worker size limit | externals 설정, minify |
|
|
199
|
+
| D1 not found | wrangler.toml 바인딩 확인 |
|
|
200
|
+
| Node.js API 오류 | `nodejs_compat` 플래그 |
|
|
626
201
|
|
|
627
202
|
```bash
|
|
628
|
-
# 로그
|
|
629
|
-
wrangler
|
|
630
|
-
|
|
631
|
-
# 배포 상태 확인
|
|
632
|
-
wrangler deployments list
|
|
633
|
-
|
|
634
|
-
# 설정 검증
|
|
635
|
-
wrangler deploy --dry-run
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
### 번들 크기 최적화
|
|
639
|
-
|
|
640
|
-
```typescript
|
|
641
|
-
// nitro.config.ts
|
|
642
|
-
import { defineNitroConfig } from "nitro/config";
|
|
643
|
-
|
|
644
|
-
export default defineNitroConfig({
|
|
645
|
-
preset: "cloudflare_module",
|
|
646
|
-
compatibilityDate: "2024-09-19",
|
|
647
|
-
|
|
648
|
-
// 외부 패키지 제외
|
|
649
|
-
externals: ["@prisma/client"],
|
|
650
|
-
|
|
651
|
-
// 압축
|
|
652
|
-
minify: true,
|
|
653
|
-
});
|
|
203
|
+
wrangler tail # 실시간 로그
|
|
204
|
+
wrangler deploy --dry-run # 검증
|
|
654
205
|
```
|
|
655
206
|
|
|
656
207
|
---
|
|
657
208
|
|
|
658
209
|
## 관련 문서
|
|
659
210
|
|
|
660
|
-
- [배포 가이드
|
|
661
|
-
- [Docker 배포](./docker.md)
|
|
662
|
-
- [Railway 배포](./railway.md)
|
|
663
|
-
- [Vercel 배포](./vercel.md)
|
|
664
|
-
- [Cloudflare Workers 공식 문서](https://developers.cloudflare.com/workers/)
|
|
665
|
-
- [Cloudflare Pages 공식 문서](https://developers.cloudflare.com/pages/)
|
|
211
|
+
- [배포 가이드](./index.md)
|