跳转到内容
搜索文档

本地开发

最后更新 查看 MarkdownAgent 设置

你可以在部署到 Cloudflare 网络之前,在自己的本地机器上构建、运行和测试 Worker 代码。这得益于 Miniflare——一个使用与生产环境相同的运行时 workerd 来执行 Worker 代码的模拟器。

默认情况下,Worker 的绑定(binding)连接到本地模拟资源,但可配置为通过远程绑定(remote bindings)与真实的生产资源交互。

核心概念

Worker 执行与绑定(Bindings)

开发 Workers 时,理解两个不同的概念很重要:

启动本地开发服务器

你可以通过以下方式启动本地开发服务器:

  1. Cloudflare Workers CLI Wrangler,使用内置 wrangler dev 命令。
npx wrangler dev
  1. Vite,使用 Cloudflare Vite 插件
npx vite dev

Wrangler 和 Cloudflare Vite 插件底层都使用 Miniflare,并由 Cloudflare 团队开发和维护。关于何时使用 Wrangler 与 Vite 的指南,请参阅 在 Wrangler 与 Vite 之间选择

默认行为

默认情况下,运行 wrangler dev / vite dev(使用 Vite 插件 时)意味着:

  • Worker 代码在本地机器上运行。
  • Wrangler 配置 中 Worker 绑定的所有资源都在本地模拟。
  • 本地 workerd 运行时使用 TZ=UTC,因此 Worker 内的 DateIntl API 使用 UTC,与生产 Cloudflare 运行时一致,不受机器时区影响。

本地开发期间的绑定

绑定(Bindings) 是允许 Worker 与各种 Cloudflare 资源交互的接口(如 KV 命名空间R2 存储桶D1 数据库QueuesDurable Objects 等)。在 Worker 代码中,这些通过 env 对象访问(例如 env.MY_KV)。

在本地开发期间,Worker 代码使用与已部署环境完全相同的 API 调用(例如 env.MY_KV.put())与这些绑定交互。这些本地资源初始为空,但你可以按 添加本地数据 中的说明填充数据。

  • 默认情况下,绑定连接到本地资源模拟AI 绑定(binding) 除外,AI 模型始终在远程运行)。
  • 你可以覆盖此默认行为,通过远程绑定(remote bindings)按绑定连接到远程资源。这样可以在 Worker 代码仍在本地运行的同时连接到真实的生产资源。
  • 使用 wrangler dev 时,可以通过提供 --local 标志(即 wrangler dev --local)临时禁用所有远程绑定(remote bindings)(仅连接到本地资源)

远程绑定

远程绑定(Remote bindings) 是在本地开发期间配置为连接到已部署的远程资源,而不是本地模拟资源的绑定。远程绑定由 WranglerCloudflare Vite 插件@cloudflare/vitest-pool-workers 包支持。你可以在绑定定义中设置 remote: true 来配置远程绑定。

配置示例

{
	"name": "my-worker",
	// Set this to today's date
	"compatibility_date": "2026-08-17",

	"r2_buckets": [
		{
			"bucket_name": "screenshots-bucket",
			"binding": "screenshots_bucket",
			"remote": true,
		},
	],
}
name = "my-worker"
# Set this to today's date
compatibility_date = "2026-08-17"

[[r2_buckets]]
bucket_name = "screenshots-bucket"
binding = "screenshots_bucket"
remote = true

配置远程绑定时,Worker 仍然在本地执行,只有绑定连接的底层资源发生变化。对于所有标记为 remote: true 的绑定,Miniflare 会将其操作(例如 env.MY_KV.put())路由到已部署的资源。其他未明确配置 remote: true 的绑定继续使用默认的本地模拟。

与环境集成

远程绑定可与 Workers 环境 很好地配合使用。为保护生产数据,你可以创建开发或 staging 环境,并在 Wrangler 配置 中指定与生产环境不同的资源。

例如:

{
	"name": "my-worker",
	// Set this to today's date
	"compatibility_date": "2026-08-17",

	"env": {
		"production": {
			"r2_buckets": [
				{
					"bucket_name": "screenshots-bucket",
					"binding": "screenshots_bucket",
				},
			],
		},
		"staging": {
			"r2_buckets": [
				{
					"bucket_name": "preview-screenshots-bucket",
					"binding": "screenshots_bucket",
					"remote": true,
				},
			],
		},
	},
}
name = "my-worker"
# Set this to today's date
compatibility_date = "2026-08-17"

[[env.production.r2_buckets]]
bucket_name = "screenshots-bucket"
binding = "screenshots_bucket"

[[env.staging.r2_buckets]]
bucket_name = "preview-screenshots-bucket"
binding = "screenshots_bucket"
remote = true

使用上述配置运行 wrangler dev -e staging(或 CLOUDFLARE_ENV=staging vite dev)意味着:

  • Worker 代码在本地运行
  • 所有对 env.screenshots_bucket 的调用将使用 preview-screenshots-bucket 资源,而不是生产环境的 screenshots-bucket

推荐的远程绑定

我们建议将特定绑定配置为连接到其远程对应资源。这些服务通常依赖 Cloudflare 的网络基础设施或具有无法完全在本地模拟的复杂后端。

以下绑定建议在 Wrangler 配置中设置 remote: true

与真实的无头浏览器交互以进行渲染。Browser Run 目前没有本地模拟。

{
	"browser": {
		"binding": "MY_BROWSER",
		"remote": true
	},
}
[browser]
binding = "MY_BROWSER"
remote = true

使用部署在 Cloudflare 网络上的实际 AI 模型进行推理。Workers AI 目前没有本地模拟。

{
	"ai": {
		"binding": "AI",
		"remote": true
	},
}
[ai]
binding = "AI"
remote = true

连接到生产 Vectorize 索引以进行准确的向量搜索和相似度操作。Vectorize 目前没有本地模拟。

{
	"vectorize": [
		{
			"binding": "MY_VECTORIZE_INDEX",
			"index_name": "my-prod-index",
			"remote": true
		}
	],
}
[[vectorize]]
binding = "MY_VECTORIZE_INDEX"
index_name = "my-prod-index"
remote = true

mTLS

验证证书交换和验证流程是否按预期工作。mTLS 绑定目前没有本地模拟。

{
	"mtls_certificates": [
		{
			"binding": "MY_CLIENT_CERT_FETCHER",
			"certificate_id": "<YOUR_UPLOADED_CERT_ID>",
			"remote": true
			}
	]
}
[[mtls_certificates]]
binding = "MY_CLIENT_CERT_FETCHER"
certificate_id = "<YOUR_UPLOADED_CERT_ID>"
remote = true

连接到高保真版本的 Images API,并验证所有转换是否按预期工作。Cloudflare Images 的本地模拟功能有限,仅支持部分特性

{
	"images": {
		"binding": "IMAGES" ,
		"remote": true
	}
}
[images]
binding = "IMAGES"
remote = true

Workers for Platforms 用户可以在 dispatch namespace 绑定定义中配置 remote: true

{
	"dispatch_namespaces": [
		{
			"binding": "DISPATCH_NAMESPACE",
			"namespace": "testing",
			"remote":true
		}
	]
}
[[dispatch_namespaces]]
binding = "DISPATCH_NAMESPACE"
namespace = "testing"
remote = true

这允许你在本地运行 dynamic dispatch Worker,同时连接到远程 dispatch namespace 绑定。这样你可以针对真实、已部署的 user Workers 测试核心调度逻辑的更改。

不支持的远程绑定

某些绑定在本地开发期间不支持远程连接(即 remote: true)。这些将始终使用本地模拟或本地值。

如果在 Wrangler 配置中为以下任何不支持的绑定类型指定 remote: true,Cloudflare 会发出错误。请参阅远程绑定支持和不支持的所有绑定

  • Durable Objects:未来可能支持 Durable Objects 的远程连接,但目前始终本地运行。不过,可以将 Durable Objects 与远程绑定结合使用。请参阅下方的 将远程资源与 Durable Objects 和 Workflows 配合使用

  • Workflows:未来可能支持 Workflows 的远程连接,但目前仅本地运行。不过,可以将 Workflows 与远程绑定结合使用。请参阅下方的 将远程资源与 Durable Objects 和 Workflows 配合使用

  • 环境变量(vars:环境变量旨在在本地开发与已部署环境之间保持不同。它们可在本地轻松配置(例如在 .dev.vars 文件中或直接在 Wrangler 配置中)。

  • Secrets:与环境变量类似,出于安全原因,secrets 在本地开发与已部署环境中预期具有不同的值。使用 .dev.vars 进行本地 secret 管理。

  • Static Assets 静态资源在开发期间始终从本地磁盘提供,以获得速度和对更改的直接反馈。

  • Version Metadata:由于 Worker 代码在本地运行,与特定已部署版本关联的版本元数据(如 commit hash、版本标签)不适用或不准确。

  • Analytics Engine:本地开发会话通常不会直接向生产 Analytics Engine 贡献数据。

  • Hyperdrive:正在积极开发中,但目前不受支持。

  • Rate Limiting:本地开发会话通常不应共享或影响已部署 Workers 的速率限制。速率限制逻辑应针对本地模拟进行测试。

将远程资源与 Durable Objects 和 Workflows 配合使用

虽然 Durable Object 和 Workflow 绑定目前无法设为远程,但你仍可在本地开发期间使用它们,并让它们与远程资源交互。

有两种推荐模式:

  • 本地 Durable Objects/Workflows 配合远程绑定:

    Wrangler 配置 中启用远程绑定时,本地运行的 Durable Objects 和 Workflows 可以访问远程资源。这样,这些绑定虽然在本地运行,但在本地开发期间仍可与远程资源交互。

  • 通过 service binding 访问远程 Durable Objects/Workflows:

    要与远程 Durable Object 或 Workflow 实例交互,请部署定义这些资源的 Worker。然后,在本地 Worker 中配置指向已部署 Worker 的远程 service binding。 本地 Worker 将能够与远程已部署 Worker 交互,后者再与远程 Durable Objects/Workflows 通信。通过此方法,你可以通过远程 service binding 创建通信通道,在本地开发期间将已部署 Worker 用作远程绑定的代理接口。

重要注意事项

  • Cloudflare Access:如果 Worker 受 Cloudflare Access 保护,Wrangler 在连接远程绑定时必须通过 Access 进行身份验证。请参阅 连接到受 Access 保护的 Workers

  • 数据修改:对远程连接绑定的操作(写入、删除、更新)将影响目标 Cloudflare 资源(无论是 preview 还是生产)中的实际数据。

  • 计费:通过这些连接与远程 Cloudflare 服务的交互将产生这些服务的标准运营成本(如 KV 操作、R2 存储/操作、AI 请求、D1 使用)。

  • 网络延迟:这些远程连接绑定的操作会有网络延迟,因为它们涉及通过互联网通信。

连接到受 Access 保护的 Workers

如果你的 Worker 部署在 Cloudflare Access 应用之后——例如,如果账户上的 *.workers.dev 子域受 Access 保护,或者你在 Worker 的自定义路由上设置了 Access 策略——Wrangler 在连接远程绑定时必须通过 Access 进行身份验证。

有两种方式可以对 Access 进行身份验证:

  • 交互式登录(本地开发):如果你定义了接受用户登录的策略,Wrangler 会在浏览器中启动交互式 cloudflared access login 流程。除了登录正确的账户外,无需额外设置。如果策略仅允许 service token 身份验证,Wrangler 将跳过交互式流程并抛出错误,提示需要 service token 凭据。

  • Service token(CI / 非交互式环境):在 CI/CD 流水线和其他非交互式上下文中,或策略仅允许 service token 身份验证时,Wrangler 无法通过浏览器触发交互式流程。必须通过 Cloudflare Access service token 进行身份验证。如果在非交互式环境中未配置 service token,Wrangler 将抛出错误,而不是尝试交互式流程。

设置 service token 身份验证:

  1. 创建 service token。

    在 Cloudflare 仪表板中,前往 Zero Trust > Access > Service Auth(服务身份验证) > Service Tokens(服务令牌) 并创建新 token。完整参考请参阅 Service tokens。系统会显示 Client ID(客户端 ID)Client Secret(客户端密钥)——请妥善保存,因为 secret 不会再次显示。

  2. 为保护 Worker 的 Access 应用添加 Service Auth 策略。

    打开现有的 Access 应用(已覆盖 Worker 的主机名——通常是 *.<account>.workers.dev 的通配符应用,或保护自定义域的应用),并附加新策略:

    • Action(操作):Service Auth
    • Include(包含):你创建的 service token,或 "Any Access Service Token"(如果你希望允许任何 service token 访问 Worker)。
  3. 向 Wrangler 暴露凭据。

    在运行 Wrangler 的环境中设置 CLOUDFLARE_ACCESS_CLIENT_IDCLOUDFLARE_ACCESS_CLIENT_SECRET 系统环境变量

    export CLOUDFLARE_ACCESS_CLIENT_ID=<CLIENT_ID>
    export CLOUDFLARE_ACCESS_CLIENT_SECRET=<CLIENT_SECRET>

    在 CI 中,将值存储为 secrets,并在运行 Wrangler 的步骤中将其作为环境变量暴露。

API

Wrangler 提供编程工具,帮助工具作者在通过 Miniflare 运行 Workers 代码时支持远程绑定连接。

主要 API 包括:

startRemoteProxySession

此函数为给定的一组绑定启动代理会话。它接受控制会话行为的选项,包括带有 Cloudflare 账户 ID 和 API token 的 auth 选项,用于远程绑定访问。

它返回包含以下内容的对象:

  • ready Promise<void>:会话就绪时 resolve。
  • dispose () => Promise<void>:停止会话。
  • updateBindings (bindings: StartDevWorkerInput['bindings']) => Promise<void>:更新会话绑定。
  • remoteProxyConnectionString remoteProxyConnectionString:传递给 Miniflare 以进行远程绑定访问的字符串。

unstable_convertConfigBindingsToStartWorkerBindings

unstable_readConfig 工具返回 Unstable_Config 对象,其中包含配置文件中绑定的定义。但这些绑定定义 无法直接用于 startRemoteProxySession。不过,使用 unstable_readConfig 读取绑定声明然后 传递给 startRemoteProxySession 非常方便,因此 wrangler 提供了 unstable_convertConfigBindingsToStartWorkerBindings,这是一个简单的工具,用于将 Unstable_Config 对象中的绑定转换为可传递给 startRemoteProxySession 的结构。

maybeStartOrUpdateRemoteProxySession

此包装器简化了代理会话管理。它接受:

  • 包含以下之一的对象:
    • Wrangler 配置文件的路径和潜在的目标环境
    • Worker 的名称及其使用的绑定
  • 当前代理会话详情(如果没有,此参数可设为 null 或不提供)。
  • 可能用于远程代理会话的 auth 数据。

它返回已启动或更新的代理会话详情对象,如果不需要代理会话则返回 null

该函数:

  • 根据第一个参数准备代理会话的输入参数。
  • 如果没有要使用的远程绑定(也没有预先存在的代理会话),则返回 null,表示不需要代理会话。
  • 如果提供了现有代理会话的详情,则相应地更新代理会话。
  • 否则启动新的代理会话。
  • 返回代理会话详情(之后可作为第二个参数传递给 maybeStartOrUpdateRemoteProxySession)。

示例

以下是将 Miniflare 与 maybeStartOrUpdateRemoteProxySession 配合使用以提供带远程绑定的本地 dev 会话的基本示例。此示例使用单个硬编码的 KV 绑定。

import { Miniflare, MiniflareOptions } from "miniflare";
import { maybeStartOrUpdateRemoteProxySession } from "wrangler";

let mf;

let remoteProxySessionDetails = null;

async function startOrUpdateDevSession() {
	remoteProxySessionDetails = await maybeStartOrUpdateRemoteProxySession(
		{
			bindings: {
				MY_KV: {
					type: "kv_namespace",
					id: "kv-id",
					remote: true,
				},
			},
		},
		remoteProxySessionDetails,
	);

	const miniflareOptions = {
		scriptPath: "./worker.js",
		kvNamespaces: {
			MY_KV: {
				id: "kv-id",
				remoteProxyConnectionString:
					remoteProxySessionDetails?.session.remoteProxyConnectionString,
			},
		},
	};

	if (!mf) {
		mf = new Miniflare(miniflareOptions);
	} else {
		mf.setOptions(miniflareOptions);
	}
}

// ... tool logic that invokes `startOrUpdateDevSession()` ...

// ... once the dev session is no longer needed run
// `remoteProxySessionDetails?.session.dispose()`
import { Miniflare, MiniflareOptions } from "miniflare";
import { maybeStartOrUpdateRemoteProxySession } from "wrangler";

let mf: Miniflare | null;

let remoteProxySessionDetails: Awaited<
	ReturnType<typeof maybeStartOrUpdateRemoteProxySession>
> | null = null;

async function startOrUpdateDevSession() {
	remoteProxySessionDetails = await maybeStartOrUpdateRemoteProxySession(
		{
			bindings: {
				MY_KV: {
					type: "kv_namespace",
					id: "kv-id",
					remote: true,
				},
			},
		},
		remoteProxySessionDetails,
	);

	const miniflareOptions: MiniflareOptions = {
		scriptPath: "./worker.js",
		kvNamespaces: {
			MY_KV: {
				id: "kv-id",
				remoteProxyConnectionString:
					remoteProxySessionDetails?.session.remoteProxyConnectionString,
			},
		},
	};

	if (!mf) {
		mf = new Miniflare(miniflareOptions);
	} else {
		mf.setOptions(miniflareOptions);
	}
}

// ... tool logic that invokes `startOrUpdateDevSession()` ...

// ... once the dev session is no longer needed run
// `remoteProxySessionDetails?.session.dispose()`

wrangler dev --remote(旧版)

与 Miniflare 驱动的本地开发不同,Wrangler 还通过 wrangler dev --remote 提供完全远程的开发模式。远程开发受 Vite 插件支持

npx wrangler dev --remote

远程开发期间,所有 Worker 代码都会上传到 Cloudflare 基础设施上的临时 preview 环境,保存代码更改时会自动上传。

使用远程开发时,所有绑定自动连接到其远程资源。与本地开发不同,你无法配置绑定使用本地模拟——它们将始终使用 Cloudflare 网络上的已部署资源。

何时使用远程开发

  • 对于大多数开发任务,最高效、最有生产力的体验是本地开发,并在需要时使用远程绑定(remote bindings)
  • 你可能希望使用 wrangler dev --remote 来测试高度特定于 Cloudflare 网络、无法充分在本地模拟或通过远程绑定测试的特性或行为。

注意事项

  • 由于每次更改都需要上传/部署步骤,迭代速度明显慢于本地开发。

限制

  • 使用 --remote 标志运行远程开发会话时,每个 zone 强制执行 50 个路由的限制。更多信息请参阅 Workers 平台限制

这篇文档对您有帮助吗?