# 静态文件服务

URL: https://caijiao.org/hono/04-middleware/04-static-files
Source: docs/hono/04-middleware/04-static-files.md
Description: 学习 Hono 在 Node.js 和 Cloudflare Workers 中处理静态文件的方式，以及 serveStatic 的注意事项。

Hono 可以服务静态文件，但具体方式取决于运行时。Node.js 使用 `@hono/node-server/serve-static`，Cloudflare Workers 推荐使用平台的 Static Assets。

## Node.js serveStatic

目录示例：

```text
my-app/
├─ public/
│  ├─ favicon.ico
│  └─ hello.txt
└─ src/
   └─ index.ts
```

代码：

```ts
import { serve } from '@hono/node-server'
import { serveStatic } from '@hono/node-server/serve-static'
import { Hono } from 'hono'

const app = new Hono()

app.use('/static/*', serveStatic({ root: './public' }))
app.use('/favicon.ico', serveStatic({ path: './public/favicon.ico' }))

serve(app)
```

访问 `/static/hello.txt` 会读取本地文件。

## 路径解析注意事项

`root` 相对的是当前工作目录 `process.cwd()`，不是源文件所在目录。如果你从不同目录启动 Node.js 进程，文件路径可能出错。

更稳定的写法是基于 `import.meta.url`：

```ts
import { fileURLToPath } from 'node:url'
import { serveStatic } from '@hono/node-server/serve-static'

const publicRoot = fileURLToPath(new URL('../public/', import.meta.url))

app.use('/static/*', serveStatic({ root: publicRoot }))
```

## Cloudflare Workers 静态资源

Workers 项目推荐使用平台静态资源能力。在 `wrangler.jsonc` 中配置：

```jsonc
{
  "name": "my-hono-worker",
  "main": "src/index.ts",
  "compatibility_date": "2026-09-29",
  "assets": {
    "directory": "public"
  }
}
```

然后把文件放到 `public/`：

```text
public/
├─ favicon.ico
└─ static/
   └─ hello.txt
```

静态资源会由 Workers 平台处理，Hono 继续负责 API 路由。

## API 与静态文件边界

建议把 API 和静态资源路径分开：

```text
/api/*       Hono API
/static/*    静态资源
/favicon.ico 静态图标
```

不要把所有请求都交给 Hono 再手写文件读取逻辑。能交给平台或静态资源服务器处理的内容，应优先交给它们处理。

## 缓存建议

- 带 hash 的静态资源可以设置长缓存。
- HTML 入口文件通常使用短缓存或不缓存。
- API 响应缓存要结合用户身份、权限和数据更新频率设计。

如果只是构建 API 服务，静态文件支持通常不是重点。需要完整前端构建时，可以考虑 Hono + Vite 或把前端单独部署。
