第一個 Worker:從建立到部署上線 | Cloudflare 完整教學

2026/08/02
第一個 Worker:從建立到部署上線 | Cloudflare 完整教學

上一篇我們鳥瞰了整片地圖,這一篇正式動手。我們會用 npm create cloudflare 建立專案,看懂 export default 裡的 fetch handler,用 wrangler dev 在本地跑起來,最後把你的第一個 Cloudflare Worker 部署到全球邊緣網路,並觀察每一個進來的 request

前言

本篇要做的事只有一句話:從零建立一個 Cloudflare Worker,讓它在本地跑起來,再部署到全球邊緣網路上線。

如果你曾經架過傳統伺服器,大概記得那套流程:租一台機器、裝作業系統、設定 Nginx、開防火牆、綁網域、還要煩惱擴展。Cloudflare Workers 把這一切壓縮成兩行指令——wrangler dev 在本地開發、wrangler deploy 上線。這就像從「自己蓋一間店面、拉水電、請店員」變成「走進共享廚房,插上電就能開始出餐」:基礎設施早就替你準備好,你只要專心寫回應請求的邏輯。

上一篇《開發者平台總覽》是廣度優先的地圖,這一篇則是實作優先的第一步。讀完本篇,你會掌握:

  • npm create cloudflare(C3)或 wrangler init 建立一個 Worker 專案,看懂它產生的檔案結構
  • export default { fetch } 這個進入點的每個參數是什麼、怎麼運作
  • wrangler dev 在本地即時開發、除錯,再用 wrangler deploy 一鍵上線
  • 寫出基礎路由(依路徑回不同內容)並觀察 request 上的邊緣中繼資料

核心概念

一個 Worker 專案長什麼樣

用 C3 建立完專案後,你會得到一個結構非常精簡的目錄。核心其實只有三個東西:

my-first-worker/
├── src/
│   └── index.ts          ← 你的 Worker 程式碼(fetch handler 在這)
├── wrangler.jsonc        ← 設定檔:名稱、進入點、相容性日期、Bindings
├── package.json          ← 依賴與 npm scripts
├── tsconfig.json         ← TypeScript 設定
└── worker-configuration.d.ts  ← 自動生成的型別(Env 介面等)

比起傳統後端專案動輒數十個資料夾,這裡乾淨得驚人。原因很簡單:作業系統、HTTP 伺服器、路由框架、程序管理——這些在傳統架構要你自己組裝的東西,Cloudflare 的執行環境全都內建了。你唯一需要關心的,是 src/index.ts 裡「請求進來後要回什麼」。

請求生命週期:一個 request 怎麼被處理

在寫程式之前,先在腦中建立一張請求流動的圖。當使用者對你的 Worker 發出一個 HTTP 請求時,大致經過這幾步:

使用者發出請求
      │
      ▼
┌─────────────────────────────────────────────┐
│  Cloudflare 邊緣網路                          │
│  ① 請求抵達離使用者最近的 PoP 節點            │
│  ② 路由系統匹配到你的 Worker                  │
│  ③ 重用現有 Isolate(熱啟動)                 │
│     或建立新的 Isolate(冷啟動 < 1ms)        │
│                    │                          │
│                    ▼                          │
│  ④ Runtime 呼叫你的 fetch handler:           │
│     fetch(request, env, ctx)                  │
│         │                                     │
│         ├─ 讀 request(URL、method、headers)  │
│         ├─ 執行你的邏輯(路由、查資料...)      │
│         └─ return new Response(...)           │
│                    │                          │
│                    ▼                          │
│  ⑤ 回應即刻串流回使用者                        │
└─────────────────────────────────────────────┘

整個過程的重點是第 ④ 步:Runtime 傳給你三個參數 requestenvctx,你回傳一個 Response,就這樣。 你不需要處理 socket、不需要解析 HTTP 協定、不需要啟動伺服器——這些底層工作 Cloudflare 都做完了,遞到你手上的已經是一個乾淨的標準 Web Request 物件。

三個關鍵術語

  • fetch handler:處理 HTTP 請求的進入點函式,也是最常用的 handler。除了 fetch,Workers 還有 scheduled(Cron 定時)、queue(消費佇列)、email(收信)等 handler,後續文章會逐一介紹。
  • wrangler:Cloudflare 官方 CLI 工具,負責建立、開發、部署與管理 Worker。你會反覆用到 wrangler devwrangler deploy
  • compatibility_date:設定檔裡的相容性日期,決定你的 Worker 使用哪個版本的 runtime 行為,是確保部署穩定可重現的關鍵。

實作範例

概念講完,我們正式動手。整個流程分成四步:建立專案 → 寫 fetch handler → 本地開發 → 部署上線。

步驟一:建立專案

開啟終端機,執行官方推薦的 C3(create-cloudflare)指令。這是 2026 年建立 Worker 專案的標準方式:

# 建立一個名為 my-first-worker 的 Worker 專案
npm create cloudflare@latest my-first-worker

指令會進入互動式選單,第一個 Worker 建議這樣選:

  • What would you like to start with? → 選 Hello World example(最乾淨的起點)
  • Which template would you like to use? → 選 Worker only
  • Which language do you want to use? → 選 TypeScript
  • Do you want to deploy your application? → 先選 No,我們稍後手動部署

C3 會自動安裝依賴、初始化 Git、並產生標準的 wrangler.jsonc

如果你偏好更精簡的方式,也可以在既有的空目錄裡用舊的 wrangler init 指令。不過 C3 範本更完整、預設值更貼近 2026 年的最佳實踐,新專案一律建議用 npm create cloudflare

步驟二:看懂並改寫 fetch handler

打開 src/index.ts,把內容改成下面這個帶基礎路由的版本。這段程式碼示範了 fetch handler 的完整樣貌:

// src/index.ts
// export default 匯出一個物件,裡面的 fetch 就是處理 HTTP 請求的進入點。
// 這是 ES Modules 語法,也是 Cloudflare 官方唯一推薦的寫法。

export default {
  // 三個參數:
  //   request — 進來的 HTTP 請求(標準 Web Request 物件)
  //   env     — 所有 Bindings 的入口(KV、D1、AI... 都掛在這,本篇還沒用到)
  //   ctx     — 執行上下文,可用 ctx.waitUntil() 跑背景任務
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    // 用標準的 URL 物件解析請求網址,取出路徑
    const url = new URL(request.url);

    // 路由一:首頁,回傳一段純文字
    if (url.pathname === "/") {
      return new Response("Hello from the edge! 你好,你的第一個 Worker 上線了。", {
        headers: { "Content-Type": "text/plain; charset=utf-8" },
      });
    }

    // 路由二:/api/hello,回傳 JSON,並觀察這次請求的邊緣中繼資料
    if (url.pathname === "/api/hello") {
      const data = {
        message: "Hello, Worker!",
        method: request.method,          // 請求方法:GET / POST...
        colo: request.cf?.colo ?? "unknown", // 處理此請求的 PoP 代碼(如 TPE)
        country: request.cf?.country ?? "unknown", // 使用者所在國家
        timestamp: new Date().toISOString(),
      };
      return new Response(JSON.stringify(data, null, 2), {
        headers: { "Content-Type": "application/json; charset=utf-8" },
      });
    }

    // 其他路徑:回傳 404
    return new Response("Not Found", { status: 404 });
  },
} satisfies ExportedHandler<Env>;

逐段拆解:

  • export default { ... }:這是 ES Modules 語法。舊的 Service Worker 寫法(addEventListener('fetch', ...))官方已標示為棄用(Deprecated),新專案一律用這種。
  • async fetch(request, env, ctx)fetch 是處理 HTTP 請求的 handler。request 是標準的 Web Requestenv 是所有 Bindings 的入口、ctx 用來跑背景任務。
  • new URL(request.url):用瀏覽器與 Node 通用的標準 URL 物件解析網址,url.pathname 就是路徑。所謂「路由」的本質,就是根據 pathnamerequest.method 決定回什麼——一開始不需要任何框架,幾個 if 就夠了。
  • request.cf?.colo:Cloudflare 在每個請求上附帶的中繼資料,colo 是處理這次請求的 PoP 代碼。這正是「邊緣運算」最直接的證據:你的程式碼真的在離使用者最近的節點上執行。request.cf 還帶有 countrycitytimezone 等豐富資訊,非常適合做地區化邏輯。
  • satisfies ExportedHandler<Env>:讓 TypeScript 幫你檢查 handler 的型別簽名是否正確,同時保留完整的 IntelliSense 自動補全。

步驟三:設定檔 wrangler.jsonc

打開 C3 產生的 wrangler.jsonc。2026 年 Cloudflare 已全面改用 wrangler.jsonc(取代舊的 wrangler.toml),支援註解、可讀性更好。內容大致如下:

{
  // $schema 提供編輯器自動補全與驗證
  "$schema": "./node_modules/wrangler/config-schema.json",
  // Worker 的名稱,也會成為預設網址的一部分
  "name": "my-first-worker",
  // 進入點:指向你的 fetch handler 檔案
  "main": "src/index.ts",
  // compatibility_date 決定 Worker 使用的 runtime 行為版本
  // 新專案建議設為建立當天的日期,C3 會自動填好
  "compatibility_date": "2026-08-02",
  // 開啟可觀測性,之後在 Dashboard 就能看到結構化日誌
  "observability": { "enabled": true }
}

其中 compatibility_date 是新手最容易忽略、卻最重要的一行。它像是替你的 Worker「凍結」了一個 runtime 行為的版本:Cloudflare 之後即使更新執行環境,你的 Worker 也會依照這個日期的行為運作,不會某天突然壞掉。

步驟四:本地開發與部署上線

先在本地把 Worker 跑起來。在專案目錄執行:

# 本地開發:在 http://localhost:8787 模擬完整的 Workers 執行環境
npx wrangler dev

wrangler dev 底層使用一個叫 Miniflare 的模擬器,能在你自己的電腦上重現完整的 Workers 執行環境。啟動後打開瀏覽器造訪 http://localhost:8787/,你會看到首頁那段歡迎文字;再造訪 http://localhost:8787/api/hello,就能看到 JSON 回應。這個階段改任何程式碼都會即時生效、不會動到線上資源,是寫程式與除錯的主場。

在終端機的互動視窗裡,按 b 可以自動開啟瀏覽器、按 d 開啟遠端除錯器、按 l 切換本地/遠端模式。確認一切正常後,只要一行指令就能部署到全球:

# 部署到 Cloudflare 全球邊緣網路
npx wrangler deploy

第一次執行 deploy 時,wrangler 會引導你用瀏覽器登入 Cloudflare 帳號授權(OAuth)。授權完成後,它會打包你的 Worker、上傳,並回傳一個 *.workers.dev 的網址,例如:

# 部署成功後的輸出(示意)
Total Upload: 1.23 KiB / gzip: 0.58 KiB
Uploaded my-first-worker (2.34 sec)
Deployed my-first-worker triggers (0.31 sec)
  https://my-first-worker.<你的子網域>.workers.dev

打開那個網址,你的第一個 Worker 就同時活在全球 330+ 個節點上了——不需要設定伺服器、不需要選區域、不需要配置負載平衡。造訪 /api/hello,看看 colo 欄位顯示的節點代碼,那就是此刻替你服務的邊緣節點。

常見錯誤與最佳實踐

第一次寫 Worker,最常踩的幾個坑如下。先認得它們,能省下大把除錯時間。

坑一:忘記或亂設 compatibility_date

如果 wrangler.jsonc 缺少 compatibility_date,部署時 wrangler 會警告;而如果你隨手填一個很舊的日期,某些現代 API 可能無法使用。正確做法是設為專案建立當天的日期(C3 會自動幫你填),需要新功能時再依官方指引往後調整。

坑二:搞混「本地」與「遠端」。

wrangler dev 預設是本地模式,KV、D1 等資源都是 Miniflare 的本地模擬版,資料不會同步到線上。很多新手在本地寫入了資料,卻到線上找不到,就是這個原因。反過來,wrangler deploy 動到的是正式資源。心法很簡單:開發階段一切在本地,deploy 才碰真實環境。 若真要在本地連到遠端資源測試,才用 wrangler dev --remote

坑三:以為模組層級變數能保存狀態。

因為承載 Worker 的 Isolate 隨時可能被回收重建,模組層級的可變變數不可靠

// ❌ 危險:requestCount 可能在任意請求後被重置為 0
let requestCount = 0;

export default {
  async fetch(): Promise<Response> {
    requestCount++; // 這個數字完全不可信
    return new Response(`Count: ${requestCount}`);
  },
};
// ✅ 正確:持久狀態要存進 KV、D1 或 Durable Objects
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const count = parseInt((await env.COUNTERS.get("requests")) ?? "0") + 1;
    await env.COUNTERS.put("requests", String(count));
    return new Response(`Count: ${count}`);
  },
};

反過來說,不可變的常數(例如編譯好的正規表達式、設定物件)放在模組層級是安全且推薦的,能跨請求重用、提升效能。這一點會在下一篇《V8 Isolates 執行模型》詳細展開。

坑四:fetch handler 沒有回傳 Response

fetch 必須回傳一個 Response(或 Promise<Response>)。忘記 return、或在某條路由分支沒有回應,執行期就會拋錯。養成習慣:每一條路由分支都明確 return,並在最後補一個預設的 404 回應當作兜底。

一條實用的入門心法:把 Worker 想成一個「輸入 Request、輸出 Response」的純函式。 只要每次請求都能穩定地由 request 算出 Response、不依賴任何跨請求的可變狀態,你的 Worker 就會既好懂又可靠。

小結

這一篇,我們把上一篇《開發者平台總覽》的地圖化為實際行動,完整走過建立並部署第一個 Worker 的流程:

  • npm create cloudflare(C3)建立專案,看懂 src/index.tswrangler.jsonc 的角色。
  • 寫出 export default { fetch } 進入點,用幾個 if 就實現了基礎路由,並透過 request.cf.colo 觀察處理請求的邊緣節點。
  • wrangler dev 在本地即時開發,再用 wrangler deploy 一鍵把 Worker 推上全球 330+ 個節點。
  • 認得四個新手常見坑,並建立「Worker 是 Request 進、Response 出的純函式」這個關鍵心智模型。

你或許會好奇:為什麼 Worker 的冷啟動可以小於 1ms?為什麼模組層級變數不可靠?這一切的答案都藏在它的執行模型裡。下一篇《V8 Isolates 執行模型》,我們會拆開 Workers 的引擎蓋,看看 V8 Isolates 到底是什麼、它如何做到近乎零的冷啟動,以及這個模型帶來哪些你必須知道的行為與限制。

想深入官方細節,可以隨時參考 Cloudflare Workers 官方入門指南。準備好了嗎?我們下一篇深入引擎內部。

BenZ Software Developer

熱愛技術的軟體開發者,在這裡分享程式開發經驗與學習筆記。

本週主打

AI 自動化入門包

你每天手動在做的那些煩事,其實 AI 可以自己跑。這份給你 10 個照著做就會的自動化工作流 + 50 個複製即用的提示詞,不用會寫程式。

看看這個產品 →