Wrangler 提供 API,用于以编程方式与 Cloudflare Workers 交互。
experimental_generateTypes- 根据 Worker 配置生成 TypeScript 类型定义。unstable_startWorker- 启动服务器,用于针对 Worker 运行集成测试。unstable_dev- 启动服务器,用于针对 Worker 运行端到端(e2e)或集成测试。getPlatformProxy- 获取代理和值,用于在 Node.js 进程中模拟 Cloudflare Workers 平台。
根据 Worker 配置生成 TypeScript 类型定义。此 API 使用与 wrangler types CLI 命令相同的核心逻辑,因此 CLI 与程序化 API 的输出保持一致。
与 CLI 命令不同,experimental_generateTypes 不会自动写入磁盘。相反,它将生成的类型内容作为结构化字符串返回,供你按需处理。
import { experimental_generateTypes } from "wrangler";
const result = await experimental_generateTypes(options);optionsobjectoptional-
可选的 options 对象,镜像
wrangler typesCLI 标志:-
configstring | string[]要使用的 Wrangler 配置文件路径。可以是数组,用于多配置类型解析。
-
envstring要为其生成类型的 Wrangler 环境名称。
-
envFilestring[]推断本地变量和密钥时加载的
.env文件路径。 -
envInterfacestring生成的环境接口名称。默认为
Env。 -
includeEnvboolean是否在输出中包含环境和绑定(binding)类型。默认为
true。 -
includeRuntimeboolean是否在输出中包含运行时类型。默认为
true。 -
pathstring生成的类型声明文件路径。默认为
worker-configuration.d.ts。 -
strictVarsboolean是否为变量生成严格的字面量和联合类型。默认为
true。
-
-
experimental_generateTypes() 返回一个 Promise,解析为包含以下字段的对象:
-
contentstring- 组合后的格式化输出,包含所有生成的部分,包括头部以及环境和运行时类型。
-
envstring | null- 生成的环境和绑定类型,或在排除环境类型时为
null。
- 生成的环境和绑定类型,或在排除环境类型时为
-
pathstring- 与此生成运行关联的目标声明文件路径。
-
runtimestring | null- 生成的运行时类型,或在排除运行时类型时为
null。
- 生成的运行时类型,或在排除运行时类型时为
你可以使用 experimental_generateTypes 以编程方式生成类型并自行写入磁盘,或将其传递给其他工具:
import { experimental_generateTypes } from "wrangler";
import * as fs from "node:fs";
const result = await experimental_generateTypes({
config: "wrangler.json",
includeRuntime: true,
includeEnv: true,
});
// Write the combined content to the path specified in options
fs.writeFileSync(result.path, result.content, "utf-8");仅生成环境类型而不生成运行时类型:
const result = await experimental_generateTypes({
includeRuntime: false,
});为特定环境生成类型并使用自定义接口名称:
const result = await experimental_generateTypes({
env: "staging",
envInterface: "StagingEnv",
path: "./types/staging.d.ts",
});此 API 暴露 Wrangler 开发服务器的内部机制,允许你自定义其运行方式。例如,你可以使用 unstable_startWorker() 针对 Worker 运行集成测试。此示例使用 node:test,但应适用于任何测试框架:
import assert from "node:assert";
import test, { after, before, describe } from "node:test";
import { unstable_startWorker } from "wrangler";
describe("worker", () => {
let worker;
before(async () => {
worker = await unstable_startWorker({ config: "wrangler.json" });
});
test("hello world", async () => {
assert.strictEqual(
await (await worker.fetch("http://example.com")).text(),
"Hello world",
);
});
after(async () => {
await worker.dispose();
});
});启动 HTTP 服务器以测试 Worker。
调用后,unstable_dev 将返回一个 fetch() 函数,用于调用 Worker 而无需知道地址或端口,以及一个 stop() 函数用于关闭 HTTP 服务器。
默认情况下,unstable_dev 针对本地服务器执行集成测试。如果你希望对预览 Worker 执行 e2e 测试,在调用 unstable_dev() 函数时在 options 对象中传入 local: false。请注意,e2e 测试可能比集成测试慢得多。
const worker = await unstable_dev(script, options);scriptstring- 包含 Worker 脚本路径的字符串,相对于 Worker 项目根目录。
optionsobjectoptional- 可选的 options 对象,包含
wrangler dev配置设置。 - 在
options内包含experimental对象以访问实验性功能,例如disableExperimentalWarning。- 将
disableExperimentalWarning设置为true以禁用 Wrangler 关于使用unstable_前缀 API 的警告。
- 将
- 可选的 options 对象,包含
unstable_dev() 返回包含以下方法的对象:
-
fetch()Promise<Response> -
stop()Promise<void>- 关闭开发服务器。
启动每个测试套件时,使用 beforeAll() 函数启动 unstable_dev()。beforeAll() 函数用于最小化开销:启动开发服务器需要几百毫秒,为每个单独测试启动和停止会迅速累积,拖慢测试速度。
在每个测试用例中,调用 await worker.fetch(),并检查响应是否符合预期。
要完成测试套件,在 afterAll 函数中调用 await worker.stop()。
const { unstable_dev } = require("wrangler");
describe("Worker", () => {
let worker;
beforeAll(async () => {
worker = await unstable_dev("src/index.js", {
experimental: { disableExperimentalWarning: true },
});
});
afterAll(async () => {
await worker.stop();
});
it("should return Hello World", async () => {
const resp = await worker.fetch();
const text = await resp.text();
expect(text).toMatchInlineSnapshot(`"Hello World!"`);
});
});import { unstable_dev } from "wrangler";
import type { UnstableDevWorker } from "wrangler";
describe("Worker", () => {
let worker: UnstableDevWorker;
beforeAll(async () => {
worker = await unstable_dev("src/index.ts", {
experimental: { disableExperimentalWarning: true },
});
});
afterAll(async () => {
await worker.stop();
});
it("should return Hello World", async () => {
const resp = await worker.fetch();
const text = await resp.text();
expect(text).toMatchInlineSnapshot(`"Hello World!"`);
});
});你可以测试调用其他 Worker 的 Worker。在以下示例中,我们将调用其他 Worker 的 Worker 称为父 Worker,被调用的 Worker 称为子 Worker。
如果过早关闭子 Worker,父 Worker 将不知道子 Worker 存在,测试将失败。
import { unstable_dev } from "wrangler";
describe("multi-worker testing", () => {
let childWorker;
let parentWorker;
beforeAll(async () => {
childWorker = await unstable_dev("src/child-worker.js", {
config: "src/child-wrangler.toml",
experimental: { disableExperimentalWarning: true },
});
parentWorker = await unstable_dev("src/parent-worker.js", {
config: "src/parent-wrangler.toml",
experimental: { disableExperimentalWarning: true },
});
});
afterAll(async () => {
await childWorker.stop();
await parentWorker.stop();
});
it("childWorker should return Hello World itself", async () => {
const resp = await childWorker.fetch();
const text = await resp.text();
expect(text).toMatchInlineSnapshot(`"Hello World!"`);
});
it("parentWorker should return Hello World by invoking the child worker", async () => {
const resp = await parentWorker.fetch();
const parsedResp = await resp.text();
expect(parsedResp).toEqual("Parent worker sees: Hello World!");
});
});import { unstable_dev } from "wrangler";
import type { UnstableDevWorker } from "wrangler";
describe("multi-worker testing", () => {
let childWorker: UnstableDevWorker;
let parentWorker: UnstableDevWorker;
beforeAll(async () => {
childWorker = await unstable_dev("src/child-worker.js", {
config: "src/child-wrangler.toml",
experimental: { disableExperimentalWarning: true },
});
parentWorker = await unstable_dev("src/parent-worker.js", {
config: "src/parent-wrangler.toml",
experimental: { disableExperimentalWarning: true },
});
});
afterAll(async () => {
await childWorker.stop();
await parentWorker.stop();
});
it("childWorker should return Hello World itself", async () => {
const resp = await childWorker.fetch();
const text = await resp.text();
expect(text).toMatchInlineSnapshot(`"Hello World!"`);
});
it("parentWorker should return Hello World by invoking the child worker", async () => {
const resp = await parentWorker.fetch();
const parsedResp = await resp.text();
expect(parsedResp).toEqual("Parent worker sees: Hello World!");
});
});getPlatformProxy 函数提供一种获取代理(指向本地 workerd 绑定)和 Cloudflare Workers 特定值模拟的方法,允许在 Node.js 进程中模拟这些功能。
获取平台代理的一个常见用例是在面向 Workers 但在 Workers 运行时之外运行的应用程序中模拟绑定(binding)(例如,在 Node.js 中运行的框架本地开发服务器),或用于测试目的(例如,确保代码正确与某种类型的绑定交互)。
const platform = await getPlatformProxy(options);optionsobjectoptional- 可选的 options 对象,包含绑定偏好:
-
environmentstring要使用的环境。
-
configPathstring要使用的配置文件路径。
如果未指定路径,默认行为是从当前目录沿文件系统向上搜索要使用的 Wrangler 配置文件。
注意: 此字段是可选的,但如果指定了路径,它必须指向文件系统上的有效文件。
-
persistboolean |{ path: string }指示是否以及在何处持久化绑定数据。如果为
true或undefined,默认使用与 Wrangler 相同的位置,以便数据可以在 Wrangler 和调用方之间共享。如果为false,不会从文件系统读取或写入数据。注意: 如果你使用
wrangler的--persist-to选项,请注意此选项在底层会添加名为v3的子目录,而getPlatformProxy的persist不会。例如,如果你运行wrangler dev --persist-to ./my-directory,要使用getPlatformProxy复用相同位置,必须指定:persist: { path: "./my-directory/v3" }。 remoteBindingsboolean optional (default: `true`)是否启用远程绑定。
-
- 可选的 options 对象,包含绑定偏好:
getPlatformProxy() 返回一个 Promise,解析为包含以下字段的对象。
-
envRecord<string, unknown>- 包含绑定代理的对象,使用方式与生产绑定相同。这与作为 modules 格式 Worker 第二个参数传递的
env对象的形状匹配。这些代理指向在workerd内运行的绑定实现。 - TypeScript 提示:
getPlatformProxy<Env>()是泛型函数。你可以将绑定记录的形状作为类型参数传递,以获取没有unknown值的正确类型。
- 包含绑定代理的对象,使用方式与生产绑定相同。这与作为 modules 格式 Worker 第二个参数传递的
-
cfIncomingRequestCfProperties read-onlyRequest的cf属性的模拟,包含与生产环境中类似的数据。
-
ctxobject- 包含
waitUntil和passThroughOnException函数实现的模拟对象,这些函数不执行任何操作。
- 包含
-
cachesobject- Workers
caches运行时 API 的模拟。 - 目前,所有缓存操作都不执行任何操作。更准确的模拟即将推出。
- Workers
-
dispose()() =>Promise<void>- 终止底层
workerd进程。 - 在程序不再需要平台代理后调用此函数。如果你运行可以无限期使用代理的长运行进程(例如开发服务器),则无需调用此函数。
- 终止底层
getPlatformProxy 函数使用 Wrangler 配置文件 中找到的绑定。例如,如果你在 Wrangler 配置文件中设置了环境变量配置:
{
"vars": {
"MY_VARIABLE": "test"
}
}[vars]
MY_VARIABLE = "test"你可以通过如下导入 getPlatformProxy 来访问绑定:
import { getPlatformProxy } from "wrangler";
const { env } = await getPlatformProxy();要访问 MY_VARIABLE 绑定的值,在代码中添加以下内容:
console.log(`MY_VARIABLE = ${env.MY_VARIABLE}`);这将打印以下输出:MY_VARIABLE = test。
Wrangler 配置文件 中找到的所有支持绑定都可通过 env 使用。
getPlatformProxy 支持的绑定包括:
-
-
要将 Durable Object 绑定与
getPlatformProxy一起使用,请始终指定script_name。例如,
getPlatformProxy读取的 Wrangler 配置文件中可能有以下绑定。{ "durable_objects": { "bindings": [ { "name": "MyDurableObject", "class_name": "MyDurableObject", "script_name": "external-do-worker" } ] } }[[durable_objects.bindings]] name = "MyDurableObject" class_name = "MyDurableObject" script_name = "external-do-worker"你需要在另一个 Worker 中声明 Durable Object
"MyDurableObject",本示例中称为external-do-worker。./external-do-worker/src/index.tsts export class MyDurableObject extends DurableObject { // Your DO code goes here } export default { fetch() { // Doesn't have to do anything, but a DO cannot be the default export return new Response("Hello, world!"); }, };该 Worker 还需要如下所示的 Wrangler 配置文件:
{ "name": "external-do-worker", "main": "src/index.ts", "compatibility_date": "XXXX-XX-XX" }name = "external-do-worker" main = "src/index.ts" compatibility_date = "XXXX-XX-XX"如果你未将 Durable Object 与 RPC 一起使用,可以在框架开发服务器旁运行单独的 Wrangler dev 会话。
否则,你可以构建应用程序并在同一 Wrangler dev 会话中运行两个 Worker。
如果你使用 Pages,运行:
npx wrangler pages dev -c path/to/pages/wrangler.jsonc -c path/to/external-do-worker/wrangler.jsoncyarn wrangler pages dev -c path/to/pages/wrangler.jsonc -c path/to/external-do-worker/wrangler.jsoncpnpm wrangler pages dev -c path/to/pages/wrangler.jsonc -c path/to/external-do-worker/wrangler.jsonc如果你使用带 Assets 的 Workers,运行:
npx wrangler dev -c path/to/workers-assets/wrangler.jsonc -c path/to/external-do-worker/wrangler.jsoncyarn wrangler dev -c path/to/workers-assets/wrangler.jsonc -c path/to/external-do-worker/wrangler.jsoncpnpm wrangler dev -c path/to/workers-assets/wrangler.jsonc -c path/to/external-do-worker/wrangler.jsonc
-