---
title: "把纯静态站部署到 Workers：一个 assets 字段就够了"
date: 2026-11-10
slug: static-site-on-workers-assets
canonical: https://kernelranch.com/blog/2026/11/static-site-on-workers-assets
markdown_url: https://kernelranch.com/blog/2026/11/static-site-on-workers-assets.md
tags: ["cloudflare", "workers", "static-site", "wrangler", "deploy"]
---以前把静态站放 Workers 要自己写路由、拼 MIME 类型。wrangler 4 之后，配置里加一个 `assets` 字段，整个目录就挂上去了。

## 1. 最小配置

目录结构：

```
static-site/
├── wrangler.toml
└── public/
    ├── index.html
    └── about.html
```

`wrangler.toml`：

```toml
name = "my-static-site"
compatibility_date = "2026-10-08"
assets = { directory = "./public" }
```

没有 `main` 字段，也就没有 JavaScript。部署：

```bash
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`，这要在配置里显式声明，不能靠猜：

```toml
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` 的实际效果，也没有测大目录（上万文件）的部署耗时。
