# 静态资源处理

URL: https://caijiao.org/koa/middleware/static
Source: docs/koa/middleware/static.md
Description: 了解如何在 Koa 中处理静态资源，包括如何服务静态文件和配置文件夹路径等。

在现代 Web 开发中，静态资源的管理是一个非常重要的部分。[Koa](/koa/) 本身不提供内建的静态资源处理功能，但可以通过中间件来轻松实现。常用的静态资源处理中间件是 `koa-static`。

## 1. 安装静态资源中间件

首先，我们需要安装 `koa-static`，它是 Koa 用来处理静态文件请求的中间件。

```bash
npm install koa-static
````

### 示例：安装并使用 `koa-static`

```js
const Koa = require('koa');
const static = require('koa-static');
const path = require('path');
const app = new Koa();

// 使用 koa-static 中间件来服务静态文件
app.use(static(path.join(__dirname, 'public')));

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});
```

在这个例子中，所有位于 `public` 目录下的文件都可以通过访问 `http://localhost:3000/文件名` 来获取。

## 2. 配置静态资源路径

在上面的示例中，我们使用 `koa-static` 中间件将 `public` 文件夹作为静态资源的根目录。你可以根据需要配置其他文件夹或者自定义静态资源的路径。

### 示例：自定义静态资源路径

```js
app.use(static(path.join(__dirname, 'assets'))); // 静态文件服务目录设置为 assets
```

此时，`assets` 文件夹中的所有文件都可以通过 `http://localhost:3000/文件名` 进行访问。

## 3. 路由与静态资源结合

如果你需要将静态资源处理与其他路由逻辑结合使用，可以将静态资源中间件放在应用的适当位置。通常情况下，静态资源中间件会在其他路由之前进行处理，以确保静态文件能够正确响应。

### 示例：路由和静态资源混合使用

```js
app.use(static(path.join(__dirname, 'public')));

app.use((ctx) => {
  ctx.body = 'Hello Koa!';
});
```

此时，如果请求访问的文件存在于 `public` 文件夹中，将返回静态文件；否则，将返回路由处理的内容。

## 4. 设置缓存控制

为了提高性能，我们可以为静态资源设置缓存控制。通过设置 `koa-static` 中间件的 `maxAge` 选项，可以指定缓存时间（单位：毫秒）。

### 示例：设置静态资源缓存控制

```js
app.use(static(path.join(__dirname, 'public'), {
  maxAge: 60 * 60 * 24 * 30,  // 设置缓存时间为 30 天
}));
```

通过设置 `maxAge`，浏览器在请求相同资源时会使用缓存，减少网络请求次数，提升性能。

## 5. 处理资源版本化

在生产环境中，为了防止浏览器缓存问题，可以通过文件版本化（如加上哈希值）来确保每次更新时，浏览器能够请求到最新的文件。

### 示例：通过文件版本化进行处理

你可以使用构建工具（如 Webpack、Vite 等）自动为静态文件生成版本号或哈希值，并将文件引用中的路径做相应修改。

```html
<script src="assets/main.abc123.js"></script>  <!-- main.js 通过构建工具生成的带有哈希值的文件 -->
```

这样可以确保每次静态资源更新时，浏览器会重新请求文件，而不是使用缓存中的旧版本。

## 6. 错误处理

如果请求的静态资源不存在，`koa-static` 会返回 404 错误。在某些情况下，你可能希望自定义 404 错误页面或进行其他错误处理。

### 示例：自定义 404 错误页面

```js
app.use(static(path.join(__dirname, 'public')));

app.use((ctx) => {
  ctx.status = 404;
  ctx.body = 'Static resource not found';
});
```

在这个示例中，如果请求的静态资源不存在，将会返回一个自定义的 404 错误页面。

## 7. 总结

通过使用 `koa-static` 中间件，Koa 可以方便地处理静态资源。你可以根据需求自定义静态资源的目录、设置缓存策略，并与其他路由逻辑进行结合。对于静态资源的版本化和错误处理，也有简单的配置方式来优化应用的性能和用户体验。

静态资源的管理是现代 Web 应用开发中不可忽视的一部分，合理配置静态资源能够提高应用的响应速度，减少不必要的资源加载和请求。
