Static Assets
env.ASSETS
把 public/ 整個目錄放上 Cloudflare 的邊緣網路。
HTML、CSS、JS 直接從離使用者最近的節點送出。
// wrangler.jsonc
"assets": {
"directory": "./public",
"run_worker_first": ["/api/*"]
}
單檔 25 MiB · 免費方案 20,000 個檔案
Cloudflare Workers · D1 · R2
你正在看的這一頁、等一下輸入的待辦、上傳的那張圖,都由同一支 Worker 決定去向。 下面這條軌跡記錄每一次真實請求:它經過哪些綁定、各花幾毫秒、在哪個節點執行。
在下方 Demo 操作,這裡會即時記錄每一次請求。
路徑
wrangler.jsonc 裡只寫了一行 run_worker_first: ["/api/*"]。
這一行就是下面所有分岔的來源 —— 符合的走 Worker,不符合的直接由邊緣節點送出檔案。
GET /
瀏覽器 靜態資產
路徑不符合 /api/*,邊緣節點直接送出 public/ 裡的檔案。
Worker 沒有被呼叫 —— 不佔用呼叫次數,也沒有冷啟動。
GET /api/todos
瀏覽器 Worker D1
Worker 用 prepare().bind().all() 查出這個帳號的待辦。
D1 是跑在 Cloudflare 上的 SQLite,語法就是你熟悉的那個 SQL。
PUT /api/todos/:id/image
瀏覽器 Worker D1 R2
先查 D1 確認這筆待辦是你的,圖片本體才寫進 R2,最後把物件鍵回填 D1。 二進位檔案不要塞進資料庫 —— D1 單列上限 2 MB,R2 單物件上限 5 TiB。
GET /api/images/*
瀏覽器 Worker R2
Bucket 全程保持私有。圖片一律由 Worker 從 R2 讀出來再回傳,
不需要開啟 r2.dev 公開網址。
Demo
每個動作都是一次真實請求。做完馬上往上看 Edge Trace, 對照這次走的是 D1、R2,還是兩個都走。
待辦與圖片都會標上你的 Google 帳號編號,各自分開存放。
清單是空的。
在上面輸入第一筆待辦,D1 就會多一列資料。
綁定
綁定(binding)是 Worker 取用雲端資源的方式。在 wrangler.jsonc 宣告,
在程式裡就變成 env 上的一個物件 —— 沒有連線字串,也沒有金鑰要保管。
env.ASSETS
把 public/ 整個目錄放上 Cloudflare 的邊緣網路。
HTML、CSS、JS 直接從離使用者最近的節點送出。
// wrangler.jsonc
"assets": {
"directory": "./public",
"run_worker_first": ["/api/*"]
}
單檔 25 MiB · 免費方案 20,000 個檔案
env.DB
Cloudflare 託管的 SQLite。適合存結構化、查得到、量不大的資料 —— 這裡存的是待辦文字與完成狀態。
await env.DB
.prepare('SELECT * FROM todos WHERE user_id = ?')
.bind(userId)
.all();
免費方案 500 MB · 單列上限 2 MB
env.BUCKET
相容 S3 的物件儲存,沒有流量傳出費用。 適合圖片、影片、備份 —— 任何不該塞進資料庫的東西。
await env.BUCKET.put(key, file, {
httpMetadata: {
contentType: file.type
}
});
單物件 5 TiB · 物件鍵長度 1024 bytes
部署
以下五步有先後順序:資源要先存在,設定檔才填得完;設定檔填完,Cloudflare 才接得上你的 repo。
01
npx wrangler d1 create todo-db
npx wrangler r2 bucket create todo-images
R2 需要先在 Cloudflare 後台啟用(要綁付款方式,免費額度仍然免費)。D1 不用。
02
// wrangler.jsonc
"d1_databases": [{
"binding": "DB",
"database_name": "todo-db",
"database_id": "上一步印出來的那串 UUID"
}]
R2 沒有 id,用 bucket 名稱對應就行。 不想把 UUID 寫進檔案的話,第 05 步的組建變數也可以代勞。
03
npm run db:remote
# 等同 npx wrangler d1 migrations apply DB --remote
少了 --remote 就只會套用到本機那份 SQLite,線上依然是空的 —— 這是最常見的錯誤。
指令裡的 DB 是 binding 名稱,不是資料庫名稱,所以你改資料庫名字時這行不用跟著改。
04
git init && git add . && git commit -m "init"
git remote add origin <你的 repo>
git push -u origin main
.gitignore 已經擋掉 .wrangler/ 與 .dev.vars。
05
後台 Workers & Pages → Create → Workers → Import a repository,
選好 repo 後 build 指令留空,
部署指令改成 npm run deploy、版本指令改成 npm run upload。
接好之後,每次 push 到 main 都會自動部署。
這兩個指令一定要改,是這裡最容易漏掉的一步。Cloudflare 預設的
npx wrangler deploy 會直接呼叫 wrangler,不觸發 npm 的
predeploy 掛勾 —— 設定檢查與組建變數注入都不會執行,
結果就是變數明明設好了,部署卻還是失敗在 database_id。
同一頁的 Build variables and secrets 可以設
D1_DATABASE_ID、D1_DATABASE_NAME、R2_BUCKET_NAME、
CF_WORKER_NAME、GOOGLE_CLIENT_ID,
部署時會自動填進 wrangler.jsonc,repo 裡就不必放自己的值。
GOOGLE_CLIENT_ID 要走這條路而不是後台的
Variables and Secrets(執行時那一區)—— 只要
wrangler.jsonc 的 vars 還留著那一行,
每次部署都會把後台設的值蓋回去。