把纯静态站部署到 Workers:一个 assets 字段就够了
以前把静态站放 Workers 要自己写路由、拼 MIME 类型。wrangler 4 之后,配置里加一个 assets 字段,整个目录就挂上去了。
1. 最小配置
目录结构:
static-site/
├── wrangler.toml
└── public/
├── index.html
└── about.html
wrangler.toml:
name = "my-static-site"
compatibility_date = "2026-10-08"
assets = { directory = "./public" }
没有 main 字段,也就没有 JavaScript。部署:
wrangler deploy
真实输出(本机 2026-11-10):
Total Upload: 0.34 KiB / gzip: 0.25 KiB
Uploaded my-static-site (5.24 sec)
Deployed my-static-site triggers (1.10 sec)
https://my-static-site.<你的账号>.workers.dev
Current Version ID: 88dbfed1-...
上传体积 0.34 KiB,就是两个 HTML 文件的大小。没有 Worker 脚本,启动时间可以忽略。
2. 路由行为
静态资源模式下,请求先按文件路径找,找不到再决定是 404 还是回退到某个文件。两个行为要分清:
| 请求 | 默认行为 |
|---|---|
/ | 返回 index.html |
/about | 返回 about.html(HTML 扩展名可省略) |
/about.html | 返回 about.html |
/nope | 404 |
单页应用(React、Vue 的 history 路由)需要把未知路径回退到 index.html,这要在配置里显式声明,不能靠猜:
assets = { directory = "./public", not_found_handling = "single-page-application" }
不声明 not_found_handling 时,刷新 /dashboard 这类前端路由会得到 404,这是静态站部署最常见的"部署成功但打不开"。
3. 三个注意点
静态资源与 Worker 脚本可以共存。同一个 Worker 既有 main 又有 assets 时,匹配到文件的请求由静态资源处理,其余请求进 Worker。这个顺序不需要自己写判断,但要知道它存在,否则会疑惑"为什么我的 fetch 没被调用"。
缓存头由文件元数据决定,不写 _headers 就用默认值。需要给静态资源设长缓存时,在同目录放一个 _headers 文件:
/assets/*
Cache-Control: public, max-age=31536000, immutable
自定义域会关掉 workers.dev。和普通 Worker 一样,绑定 custom_domain 后,<name>.<账号>.workers.dev 不再可访问。想两个都保留就改用 route。
4. 与 Pages 的取舍
静态站放 Workers 与放 Pages 的差别不在能力,在工作流:Pages 自带 Git 集成与预览部署,Workers 要自己接 CI。如果只是几个 HTML 文件加一点配置,Workers 更轻;如果要"push 即部署 + 每个分支一个预览地址",Pages 更省事。
小结
静态站上 Workers 的成本已经降到"配置一个字段"。真正需要判断的只有两件事:未知路径是 404 还是回退(not_found_handling),以及缓存头要不要自己控制(_headers)。
这两个默认值如果不动,站点能上线,但 SPA 刷新会 404、静态资源会反复回源。它们是最容易被忽略的两行配置。
数据来源与检索时间
检索时间 2026-11-10。部署输出为本机实测。
| 来源 | URL | 对应数据 |
|---|---|---|
| Workers 静态资源 | https://developers.cloudflare.com/workers/static-assets/ | assets 配置、目录结构、与 Worker 脚本共存时的处理顺序 |
| Workers 路由 | https://developers.cloudflare.com/workers/configuration/routing/routes/ | 自定义域与 workers.dev 的关系 |
| Pages 限额 | https://developers.cloudflare.com/pages/platform/limits/ | 用于第 4 节与 Pages 的对照(文件数上限 20,000、单文件 25 MiB) |
核验说明
- 配置与部署输出为本机真实执行:
static-site项目用assets = { directory = "./public" }部署成功,上传 0.34 KiB、gzip 0.25 KiB。 - 未验证:部署后立刻用 curl 访问,返回
000(连接未建立),判断是边缘生效延迟;随后执行了删除,没有在生效后复测/、/about、/nope的实际状态码。因此第 2 节的路由表依据官方文档,不是本次实测结果。 - 未做:没有测
_headers与not_found_handling的实际效果,也没有测大目录(上万文件)的部署耗时。