尝试 Dynamic Workers playground ↗ 以编写或从 GitHub 导入代码、在运行时打包它、在 Dynamic Worker 中执行它,并查看实时日志。
- 运行时打包 — 使用
@cloudflare/worker-bundler↗ 解析 npm 依赖项并在 Worker 内部编译 TypeScript - 动态执行 — 将打包的代码加载到独立的 Dynamic Worker 中
- 缓存 — 当源代码未更改时,重用以前打包的 Workers
- 实时输出 — 将响应体、控制台日志、执行计时和打包元数据流式传输回客户端
该 playground 使用 @cloudflare/worker-bundler ↗ 来编译 TypeScript,解析 npm 依赖项,并生成 Worker Loader 可以执行的模块。
将源文件和 package.json 传递给 createWorker(),它会解析依赖项并返回准备好作为 Dynamic Worker 加载的打包模块:
import { createWorker } from "@cloudflare/worker-bundler";
const { mainModule, modules, warnings } = await createWorker({
files: {
"src/index.ts": userCode,
"package.json": JSON.stringify({
dependencies: { hono: "^4.0.0" },
}),
},
bundle: true,
minify: false,
});import { createWorker } from "@cloudflare/worker-bundler";
const { mainModule, modules, warnings } = await createWorker({
files: {
"src/index.ts": userCode,
"package.json": JSON.stringify({
dependencies: { hono: "^4.0.0" },
}),
},
bundle: true,
minify: false,
});env.LOADER.load() 每次调用都会创建一个新的 Dynamic Worker。为了避免重新打包未更改的代码,请使用 env.LOADER.get(id, callback) 代替。在缓存命中时,运行时将返回一个现有的 Worker;而在未命中时,将调用您的 callback 来构建一个:
const worker = env.LOADER.get(workerId, async () => {
// This callback only runs on cache miss
const { mainModule, modules } = await createWorker({ files });
return {
mainModule,
modules,
compatibilityDate: "2026-05-01",
tails: [contextExports.DynamicWorkerTail({ props: { workerId } })],
};
});
const response = await worker.getEntrypoint().fetch(request);const worker = env.LOADER.get(workerId, async () => {
// This callback only runs on cache miss
const { mainModule, modules } = await createWorker({ files });
return {
mainModule,
modules,
compatibilityDate: "2026-05-01",
tails: [
contextExports.DynamicWorkerTail({ props: { workerId } }),
],
};
});
const response = await worker.getEntrypoint().fetch(request);在 playground 中,您可以看到实际效果 — 运行同一个 Dynamic Worker 两次,第二次请求会显示缓存的结果,其冷启动时间为 0 毫秒,因为构建和加载阶段被完全跳过。
当您在 playground 中运行代码时,Dynamic Worker 的控制台输出会实时流回浏览器。在底层,这是通过 Tail Worker 管道工作的:
- 一个 Tail Worker (
DynamicWorkerTail) 捕获来自 Dynamic Worker 的console.log输出。 - 日志被转发到
LogSessionDurable Object。 - 该 Durable Object 通过 WebSocket 将它们流式传输给客户端。
要进行这种连接,请在创建 Dynamic Worker 时将 Tail Worker 包含在 tails 数组中:
const worker = env.LOADER.get(workerId, async () => ({
mainModule,
modules,
compatibilityDate: "2026-05-01",
tails: [contextExports.DynamicWorkerTail({ props: { workerId } })],
}));const worker = env.LOADER.get(workerId, async () => ({
mainModule,
modules,
compatibilityDate: "2026-05-01",
tails: [contextExports.DynamicWorkerTail({ props: { workerId } })],
}));有关如何从 Dynamic Workers 捕获和流式传输日志的更多信息,请参阅使用 Dynamic Workers 的可观测性。
克隆代码库并启动开发服务器:
npm install
npm run dev