wrangler dev 与调试:本地跑起来和线上不一样的地方
读完这一篇,你能把 Worker 在本地跑起来、看懂启动日志和每条请求的两行输出、知道本地状态存在哪个目录、改代码不用重启,以及遇到最常见的那个 compatibility date 报错时怎么改。第 4、5 节的报错原文和日志路径来自 2026-11-10 本机三次 wrangler dev 的真实输出,wrangler 版本 4.146.0。
1. 两种模式
wrangler dev 默认跑本地模式:在本机起一个 workerd 实例,你的代码真的在这个运行时里执行,但请求不出网、数据不落远端。
wrangler dev # 本地模式,默认
wrangler dev --remote # 请求打到线上边缘,用真实环境
两者的差别值得分清:
| 本地模式 | --remote | |
|---|---|---|
| 运行时 | 本机 workerd 二进制 | Cloudflare 边缘 |
| 绑定数据 | 本地模拟存储 | 真实的 KV / R2 / D1 |
request.cf | 简化值或缺失 | 完整 |
| 网络 | 出站受限 | 正常 |
| 启动速度 | 1 秒级 | 需要建立会话,慢 |
日常写代码用本地,排查"线上才复现"的问题用 --remote。绑定数据是两套,本地写的 KV 线上读不到,这一点在 59-workers-kv-tutorial.md 里已经踩过。
2. 常用参数
wrangler dev --port 8788 --local
wrangler dev --port 8789 --persist-to .wrangler/alt
wrangler dev --test-scheduled
--port 指定端口,默认 8787,同时起多个 Worker 时要改。--persist-to 换一个状态目录,用来做"干净的初始数据"对比。--test-scheduled 打开定时任务的手动触发入口,见 63-workers-cron-triggers.md。
断点调试要指定 inspector 端口:
wrangler dev --inspector-port 9229
然后在浏览器打开 chrome://inspect,配置 localhost:9229 就能看到 Worker 的脚本并下断点。这比 console.log 反复加删高效,尤其是排查异步时序问题。
3. 启动日志怎么读
正常启动长这样:
⛅️ wrangler 4.146.0 (update available 4.159.0)
───────────────────────────────────────────────
⎔ Starting local server...
[wrangler:info] Ready on http://127.0.0.1:8788
Ready 这一行出现之后才能发请求,脚本里写 Start-Sleep 8 之类固定等待容易在慢机器上失败,正确做法是轮询这个 URL 直到有响应。
每条请求有两到三行输出,来源不同:
<-- GET /api/hello/world?q=1
--> GET /api/hello/world?q=1 200 1ms
[wrangler:info] GET /api/hello/world 200 OK (51ms)
<-- 和 --> 是我的应用里 logger() 中间件打印的(Hono 的格式,见 58-hono-on-workers.md),末尾的 1ms 是 fetch 处理函数内部耗时。[wrangler:info] 那一行是 wrangler 自己加的,括号里的 51ms 是整个请求的墙钟时间,包含排队和序列化。
两个数字差很多时说明时间花在框架之外,比如大 body 读取或流式输出。这个对照很有用,比单看一个数字能定位得多。
4. 本地状态在哪
本地模拟的 KV、R2、D1、DO 数据都落在项目目录下:
.wrangler\state\v3\
D1 的库文件在这个目录的 d1 子目录里,wrangler d1 execute --local 也会操作它。想重置数据,停掉 dev 服务后把 .wrangler 整个删掉即可——下一次启动会是空状态。
这个目录不该提交到 Git,.gitignore 里加一行 .wrangler/。它也可能变得很大,长期开发后偶尔清一次。
5. 三个真遇到的报错
第一个是 compatibility date 超前。配置里写 2026-11-01 时启动失败:
X [ERROR] service core:user:cf58-hono: This Worker requires compatibility date
"2026-11-01", but the newest date supported by this server binary is "2026-10-08".
原因是本机的 workerd 二进制比线上边缘旧,支持的日期上限更低。改成本机支持的那一天即可,报错里直接给了答案。这个错误只影响本地,同样的配置 wrangler deploy 到线上是能成功的——所以"本地起不来、线上正常"并不矛盾。
第二个是日志文件路径。启动失败时 wrangler 会在末尾提示:
🪵 Logs were written to "C:\Users\<用户名>\.wrangler\logs\wrangler-2026-11-10_06-44-39_673.log"
终端里被截断的堆栈去这个文件里能看到全文。多个 Agent 并行部署时日志会混在一起,按时间戳找最新的那个。
第三个是端口占用。--port 8787 已被别的进程占住时,启动会失败并提示端口不可用。解决办法是换端口,或者先找到占用进程结束它。并行开发时给每个项目分配固定端口(8788、8789)能省不少事。
6. 热重载与重启
本地模式下改 src/index.js 会触发热重载,不用手动重启,终端里会打印重新构建的信息。但有三类改动不会热重载,需要 Ctrl+C 重启:
wrangler.toml里的绑定、变量、cron 配置- 新增的依赖(
npm install之后) compatibility_date/compatibility_flags
改了 wrangler.toml 之后如果行为没变,先看一眼终端有没有重新构建,别急着怀疑代码。
7. 常见问题
问:本地 dev 里 request.cf 是 undefined,代码报错? 答:本地模式下 cf 可能是简化值或不存在,代码里用可选链加兜底。要真实值就 --remote,或者部署后测。
问:怎么在本地模拟多次请求之间的状态? 答:本地状态是持久的,写在 .wrangler\state 下,重启 dev 服务数据还在。要"每次从空开始"就换 --persist-to 目录或用完删掉 .wrangler。
问:wrangler dev 能起多个 Worker 吗? 答:同时起多个要不同端口和不同状态目录。需要 Worker 之间互相调用时,用 service binding 在配置里声明,本地会一起路由。
小结
wrangler dev 的核心认识是"本地不等于线上":运行时是同一个 workerd,但版本可能更旧,绑定数据是另一套,cf 对象不完整。把这三点记住,能解释大部分"本地好好的、线上不对"或者反过来"线上能跑、本地报错"的现象。
日常姿势是:--port 固定端口避免冲突,看 Ready 行确认启动,用 <-- / --> 和 [wrangler:info] 两组日志对照耗时,报错全文去 .wrangler\logs 里翻。部署上线的流程见 53-first-free-site-with-workers.md,线上日志的查看方式见 66-workers-observability.md。
数据来源与检索时间
检索时间 2026-11-10。启动日志、报错原文、日志路径均为本机真实执行结果。
| 来源 | URL | 对应数据 |
|---|---|---|
| 本地开发概览 | https://developers.cloudflare.com/workers/local-development/ | 本地模式与 --remote 的差异、绑定数据隔离(未抓取) |
| Wrangler dev 命令 | https://developers.cloudflare.com/workers/wrangler/commands/#dev | --port / --persist-to / --inspector-port 参数(页面正文未完整提取,仅取入口) |
| 调试 Workers | https://developers.cloudflare.com/workers/observability/devtools/ | chrome://inspect 断点调试(未抓取) |
核验说明
- 真做了:本机三次
wrangler dev启动(_cf58src8788、_cf60src8789、_cf61src8790),记录到Ready on http://127.0.0.1:<port>行、[wrangler:info]请求日志格式与耗时、.wrangler\state\v3下的本地状态目录结构(D1 库文件在d1子目录)。 - 第 5 节第一个报错为原文:首次用
compatibility_date = "2026-11-01"启动_cf58src时触发,改成2026-10-08后启动成功;同一天该日期配置在wrangler deploy上是成功的。 - 日志文件路径
C:\Users\<用户名>\.wrangler\logs\wrangler-2026-11-10_06-44-39_673.log为真实输出,用户名已替换占位。 --inspector-port与chrome://inspect的断点流程、热重载的三类例外依据文档与既有经验,没有实际下过断点,也没有逐项验证哪类改动不触发热重载。- 未做:没有测
--remote模式,没有测多 Worker 的 service binding,没有测--persist-to的目录切换效果。