使用Bun构建CloudflareWorkers BunCloudflareWorkers

这个技能专注于使用Bun作为运行时和工具链来开发、测试和部署Cloudflare Workers应用,涵盖项目设置、基本Worker、存储绑定(如KV、D1、R2)、框架集成(如Hono)、测试和生产构建。适用于边缘计算、JavaScript/TypeScript开发和Serverless部署场景。关键词:Bun, Cloudflare Workers, 边缘部署, Serverless, 开发工具, 存储绑定, 测试, 生产构建。

Serverless 0 次安装 0 次浏览 更新于 3/8/2026

名称: Bun Cloudflare Workers 描述: 当用户询问关于"使用Bun的Cloudflare Workers"、“将Bun部署到Workers”、“使用Bun的wrangler”、“边缘部署”、"Bun到Cloudflare"或使用Bun构建和部署应用到Cloudflare Workers时,应使用此技能。

Bun Cloudflare Workers

使用Bun进行开发,构建和部署Cloudflare Workers。

快速开始

# 创建新的Workers项目
bunx create-cloudflare my-worker
cd my-worker

# 安装依赖
bun install

# 开发
bun run dev

# 部署
bun run deploy

项目设置

package.json

{
  "scripts": {
    "dev": "wrangler dev",
    "deploy": "wrangler deploy",
    "build": "bun build src/index.ts --outdir=dist --target=browser"
  },
  "devDependencies": {
    "@cloudflare/workers-types": "^4.20250906.0",
    "wrangler": "^4.54.0"
  }
}

wrangler.toml

name = "my-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"

# 使用Bun进行本地开发
[dev]
local_protocol = "http"

# 绑定
[[kv_namespaces]]
binding = "KV"
id = "xxx"

[[d1_databases]]
binding = "DB"
database_name = "my-db"
database_id = "xxx"

基本Worker

// src/index.ts
export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const url = new URL(request.url);

    if (url.pathname === "/") {
      return new Response("来自Cloudflare Workers的问候!");
    }

    if (url.pathname === "/api/data") {
      return Response.json({ message: "Hello" });
    }

    return new Response("未找到", { status: 404 });
  },
};

interface Env {
  KV: KVNamespace;
  DB: D1Database;
}

使用Hono

// src/index.ts
import { Hono } from "hono";

type Bindings = {
  KV: KVNamespace;
  DB: D1Database;
};

const app = new Hono<{ Bindings: Bindings }>();

app.get("/", (c) => c.text("Hello Hono!"));

app.get("/api/users", async (c) => {
  const users = await c.env.DB.prepare("SELECT * FROM users").all();
  return c.json(users.results);
});

app.post("/api/users", async (c) => {
  const { name } = await c.req.json();
  await c.env.DB.prepare("INSERT INTO users (name) VALUES (?)").bind(name).run();
  return c.json({ success: true });
});

export default app;

KV存储

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);
    const key = url.searchParams.get("key");

    if (request.method === "GET" && key) {
      const value = await env.KV.get(key);
      return Response.json({ key, value });
    }

    if (request.method === "PUT" && key) {
      const value = await request.text();
      await env.KV.put(key, value, { expirationTtl: 3600 });
      return Response.json({ success: true });
    }

    return new Response("错误请求", { status: 400 });
  },
};

D1数据库

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    // 查询
    const { results } = await env.DB.prepare(
      "SELECT * FROM users WHERE active = ?"
    ).bind(1).all();

    // 插入
    const info = await env.DB.prepare(
      "INSERT INTO users (name, email) VALUES (?, ?)"
    ).bind("Alice", "alice@example.com").run();

    // 事务
    const batch = await env.DB.batch([
      env.DB.prepare("INSERT INTO users (name) VALUES (?)").bind("Bob"),
      env.DB.prepare("INSERT INTO users (name) VALUES (?)").bind("Charlie"),
    ]);

    return Response.json(results);
  },
};

持久对象

// src/counter.ts
export class Counter {
  private state: DurableObjectState;
  private value = 0;

  constructor(state: DurableObjectState) {
    this.state = state;
    this.state.blockConcurrencyWhile(async () => {
      this.value = (await this.state.storage.get("value")) || 0;
    });
  }

  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);

    if (url.pathname === "/increment") {
      this.value++;
      await this.state.storage.put("value", this.value);
    }

    return Response.json({ value: this.value });
  }
}

// src/index.ts
export { Counter } from "./counter";

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const id = env.COUNTER.idFromName("global");
    const stub = env.COUNTER.get(id);
    return stub.fetch(request);
  },
};
# wrangler.toml
[[durable_objects.bindings]]
name = "COUNTER"
class_name = "Counter"

[[migrations]]
tag = "v1"
new_classes = ["Counter"]

R2存储

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);
    const key = url.pathname.slice(1);

    if (request.method === "GET") {
      const object = await env.BUCKET.get(key);
      if (!object) {
        return new Response("未找到", { status: 404 });
      }
      return new Response(object.body, {
        headers: { "Content-Type": object.httpMetadata?.contentType || "application/octet-stream" },
      });
    }

    if (request.method === "PUT") {
      await env.BUCKET.put(key, request.body, {
        httpMetadata: { contentType: request.headers.get("Content-Type") || undefined },
      });
      return Response.json({ success: true });
    }

    return new Response("方法不允许", { status: 405 });
  },
};

使用Bun开发

本地开发

# 使用wrangler运行(使用Bun进行TypeScript)
bun run dev

# 或直接
bunx wrangler dev

使用Bun测试

// src/index.test.ts
import { describe, test, expect } from "bun:test";

// 模拟worker
const worker = {
  async fetch(request: Request) {
    return new Response("Hello");
  },
};

describe("Worker", () => {
  test("返回hello", async () => {
    const request = new Request("http://localhost/");
    const response = await worker.fetch(request);
    expect(await response.text()).toBe("Hello");
  });
});

使用Miniflare测试

import { Miniflare } from "miniflare";

const mf = new Miniflare({
  script: await Bun.file("./dist/index.js").text(),
  kvNamespaces: ["KV"],
});

const response = await mf.dispatchFetch("http://localhost/");
console.log(await response.text());

生产构建

// build.ts
await Bun.build({
  entrypoints: ["./src/index.ts"],
  outdir: "./dist",
  target: "browser", // Workers使用浏览器API
  minify: true,
  sourcemap: "external",
});
bun run build.ts
bunx wrangler deploy

环境变量

# wrangler.toml
[vars]
API_URL = "https://api.example.com"

# 秘密(通过CLI设置)
# wrangler secret put API_KEY
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    console.log(env.API_URL);    // 来自vars
    console.log(env.API_KEY);    // 来自secrets
    return new Response("OK");
  },
};

计划Worker(Cron)

export default {
  async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext): Promise<void> {
    console.log("Cron触发于:", event.scheduledTime);
    // 执行计划任务
    await env.DB.prepare("DELETE FROM logs WHERE created_at < ?")
      .bind(Date.now() - 7 * 24 * 60 * 60 * 1000)
      .run();
  },

  async fetch(request: Request, env: Env): Promise<Response> {
    return new Response("OK");
  },
};
# wrangler.toml
[triggers]
crons = ["0 * * * *"]  # 每小时

常见错误

错误 原因 修复
Bun API不可用 Workers使用V8 仅使用Web API
模块未找到 构建问题 检查打包器配置
脚本过大 超过10MB 优化打包
CPU时间超限 执行时间过长 优化或使用队列

API兼容性

Workers支持Web API,不支持Bun特定API:

可用 不可用
fetch() Bun.file()
Response Bun.serve()
Request bun:sqlite
URL bun:ffi
crypto fs
TextEncoder child_process

何时加载参考

加载references/bindings.md当:

  • 高级KV/D1/R2模式
  • 队列worker
  • 服务绑定

加载references/performance.md当:

  • 打包优化
  • 减少冷启动
  • 缓存策略