初面网初面网

Serve

bun可以开启服务。用bun.serve开启。

const server = Bun.serve({
  port: 8080, // defaults to $BUN_PORT, $PORT, $NODE_PORT otherwise 3000
  // port: 0, // random port
  hostname: "mydomain.com", // defaults to "0.0.0.0"
  // `routes` requires Bun v1.2.3+
  routes: {
    // Static routes
    "/api/status": new Response("OK"),

    // Dynamic routes
    "/users/:id": req => {
      return new Response(`Hello User ${req.params.id}!`);
    },

    // Per-HTTP method handlers
    "/api/posts": {
      GET: () => new Response("List posts"),
      POST: async req => {
        const body = await req.json();
        return Response.json({ created: true, ...body });
      },
    },

    // Wildcard route for all routes that start with "/api/" and aren't otherwise matched
    "/api/*": Response.json({ message: "Not found" }, { status: 404 }),

    // Redirect from /blog/hello to /blog/hello/world
    "/blog/hello": Response.redirect("/blog/hello/world"),

    // Serve a file by lazily loading it into memory
    "/favicon.ico": Bun.file("./favicon.ico"),
  },

  // (optional) fallback for unmatched routes:
  // Required if Bun's version < 1.2.3
  fetch(req) {
    return new Response("Not Found", { status: 404 });
  },
});

console.log(`Server running at ${server.url}`);

其他几种设置Port的方式

  • --port CLI
bun --port=4002 server.ts
  • BUN_PORT 环境变量
BUN_PORT=4002 bun server.ts
  • PORT 环境变量
PORT=4002 bun server.ts
  • NODE_PORT 环境变量
NODE_PORT=4002 bun server.ts

HTTP/3 (QUIC)

实验性。可能会变动。

Bun.serve({
  tls: {
    key: Bun.file("./key.pem"),
    cert: Bun.file("./cert.pem"),
  },
  http3: true, 
  fetch(req) {
    return new Response("Hello over HTTP/3!");
  },
});

启用http3后,服务器将在同一端口上同时通过TCP(HTTP/1.1)和UDP(HTTP/3)进行通信。HTTP/1.1响应中包含Alt-Svc头部信息,用于标识HTTP/3服务端点,使具备相应能力的客户端能够自动升级。

仅支持 HTTP/3(完全不使用 TCP 监听器)时,请设置 http1: false:

Bun.serve({
  tls: {
    key: Bun.file("./key.pem"),
    cert: Bun.file("./cert.pem"),
  },
  http3: true,
  http1: false, // 添加这行
  fetch(req) {
    return new Response("HTTP/3 only");
  },
});

idleTimeout

连续x秒内无操作就关闭连接。默认是10秒。

要配置此选项,需设置 idleTimeout 字段(单位:秒)。最大值为255,当取值为0时会完全禁用超时功能。

Bun.serve({
  // 30 seconds (default is 10)
  idleTimeout: 30,

  fetch(req) {
    return new Response("Bun!");
  },
});

导出默认配置

import type { Serve } from "bun";

export default {
  fetch(req) {
    return new Response("Bun!");
  },
} satisfies Serve.Options<undefined>;

路由热重载

const server = Bun.serve({
  routes: {
    "/api/version": () => Response.json({ version: "1.0.0" }),
  },
});

// Deploy new routes without downtime
server.reload({
  routes: {
    "/api/version": () => Response.json({ version: "2.0.0" }),
  },
});

服务生命周期函数

  • stop()、reload()
const server = Bun.serve({
  fetch(req) {
    return new Response("Hello!");
  },
});

// Gracefully stop the server (waits for in-flight requests)
await server.stop();

// Force stop and close all active connections
await server.stop(true);
  • ref() 和 unref()

控制服务器是否保持Bun进程运行

// Don't keep process alive if server is the only thing running
server.unref();

// Restore default behavior - keep process alive
server.ref();
  • reload()

无需重启更新处理程序

const server = Bun.serve({
  routes: {
    "/api/version": Response.json({ version: "v1" }),
  },
  fetch(req) {
    return new Response("v1");
  },
});

// Update to new handler
server.reload({
  routes: {
    "/api/version": Response.json({ version: "v2" }),
  },
  fetch(req) {
    return new Response("v2");
  },
});

这种方法只能让 fetcherrorrouteswebsocket 更新。

单请求控制

const server = Bun.serve({
  async fetch(req, server) {
    // 将此请求的静默时间设置为最多60秒,而非默认的10秒
    server.timeout(req, 60);

    // 若发送主体所需时间超过60秒,请求将被中止
    await req.text();

    return new Response("Done!");
  },
});

想让一个请求长期有效要用两参数的 timeout

Bun.serve({
  routes: {
    "/events": (req, server) => {
    // 禁用此流式响应的空闲超时机制。
    // 否则,若无字节传输,则连接将被关闭。
    // 发送时间为 10 秒(默认值为 idleTimeout)。
      server.timeout(req, 0);

      return new Response(
        async function* () {
          yield "data: hello\n\n";
          // 事件可能零星发生,且连接不会被断开
        },
        { headers: { "Content-Type": "text/event-stream" } },
      );
    },
  },
});

获得IP

const server = Bun.serve({
  fetch(req, server) {
    const address = server.requestIP(req);
    if (address) {
      return new Response(`Client IP: ${address.address}, Port: ${address.port}`);
    }
    return new Response("Unknown client");
  },
});

更新于 2026/7/20