# vite-plugin-automock 配置指南

这份文档只解释“怎么配”和“配置之间怎么相互影响”。API 用法和 mock 文件格式见 README。

## 推荐先从最小配置开始

大多数开发期录制 mock 的项目只需要：

```ts
import { defineConfig } from 'vite'
import { automock } from 'vite-plugin-automock'

export default defineConfig({
  plugins: [
    automock({
      proxyBaseUrl: 'https://api.example.com',
      pathRewrite: (path) => path.replace(/^\/api/, ''),
    }),
  ],
})
```

这套配置会处理默认的 `/api` 前缀：

1. 如果本地存在启用的 mock 文件，直接返回 mock。
2. 如果没有命中 mock，请求会代理到 `proxyBaseUrl`。
3. 如果代理响应是 JSON，会生成本地 mock 文件；非 JSON/下载流会直接透传，不自动捕获。

不要同时给同一个前缀配置 Vite `server.proxy`。如果使用 `proxyBaseUrl`，代理由 automock 处理。

## 配置分层

### 基础路径

| 配置 | 类型 | 默认值 | 作用 |
| --- | --- | --- | --- |
| `apiPrefix` | `string` | `'/api'` | 插件处理的请求路径前缀。只匹配完整路径段，例如 `/api` 和 `/api/users`，不会匹配 `/apiary`。 |
| `mockDir` | `string` | `'mock'` | mock 文件目录。相对路径基于运行 Vite 的当前工作目录。 |
| `pathRewrite` | `(path: string) => string` | `(path) => path` | 转发到真实后端前改写请求路径。常用于把 `/api/users` 转成 `/users`。 |
| `proxyBaseUrl` | `string` | 无 | 真实后端地址。只有需要代理或自动捕获时才需要。 |

### 开发期行为开关

| 配置 | 类型 | 默认值 | 作用 |
| --- | --- | --- | --- |
| `enabled` | `boolean` | `true` | 总开关。为 `false` 时插件直接放行请求，不读取 mock、不代理、不捕获。 |
| `proxy` | `boolean` | `true` | mock 未命中时是否代理到 `proxyBaseUrl`。需要同时配置 `proxyBaseUrl`。 |
| `capture` | `boolean` | `true` | 代理 JSON 响应是否保存为本地 mock。需要 `proxy=true` 且配置 `proxyBaseUrl`。 |

当前没有独立的“只录制但不命中已有 mock”模式，因为 `enabled=false` 是总开关。如果需要这个能力，建议后续单独设计一个比 `enabled` 更明确的选项。

### 可视化面板

| 配置 | 类型 | 默认值 | 作用 |
| --- | --- | --- | --- |
| `inspector` | `boolean \| InspectorOptions` | `false` | 是否启用可视化 mock 管理面板。 |
| `inspector.route` | `string` | `'/__mock/'` | 面板访问路径。 |
| `inspector.enableToggle` | `boolean` | `true` | 是否允许在面板里切换 mock 文件的 `enable` 字段。 |

示例：

```ts
automock({
  proxyBaseUrl: 'https://api.example.com',
  inspector: {
    route: '/__mock/',
    enableToggle: true,
  },
})
```

### 生产构建 mock

生产构建 mock 由两个部分组成：

1. Vite 插件在构建时生成 `mock-data.json`。
2. 浏览器端通过 `vite-plugin-automock/client` 初始化 Axios 拦截器。

| 配置 | 类型 | 默认值 | 作用 |
| --- | --- | --- | --- |
| `productionMock` | `boolean \| 'auto'` | `false` | 是否给客户端拦截器注入启用状态，并允许构建 mock bundle。 |
| `bundleMockData` | `boolean` | `true` | `productionMock` 启用时，是否生成 mock 数据包。 |
| `bundleOutputPath` | `string` | `'public/mock-data.json'` | mock 数据包输出路径。相对路径基于当前工作目录，也支持绝对路径。 |

`productionMock` 的语义：

| 值 | 行为 |
| --- | --- |
| `false` 或不配置 | 不启用客户端 mock，不生成 `mock-data.json`。 |
| `true` | 显式启用客户端 mock，并在构建时生成 `mock-data.json`。 |
| `'auto'` | 在非 `production` mode 启用，在 `production` mode 关闭。适合 `vite build --mode staging` 这类内部环境。 |

生产 mock 示例：

```ts
// vite.config.ts
automock({
  mockDir: 'mock',
  productionMock: true,
  bundleMockData: true,
  bundleOutputPath: 'public/mock-data.json',
})
```

```ts
// src/main.ts
import axios from 'axios'
import { initMockInterceptor } from 'vite-plugin-automock/client'

await initMockInterceptor(axios)
```

注意：动态 mock 例如 `data: () => ({ ... })` 可以在开发期 middleware 中运行，但不会进入生产 `mock-data.json`，因为函数无法安全序列化。

## 常见场景

### 默认开发模式：mock 优先，未命中就代理并捕获

```ts
automock({
  proxyBaseUrl: 'https://api.example.com',
  pathRewrite: (path) => path.replace(/^\/api/, ''),
})
```

### 离线 mock 模式：只用本地 mock，不访问后端

```ts
automock({
  mockDir: 'mock',
  proxy: false,
  capture: false,
})
```

如果请求没有命中 mock，会交给后续 Vite middleware 处理。

### 只使用 Vite 自己的代理

```ts
automock({
  enabled: false,
})
```

然后在 Vite `server.proxy` 里配置真实代理。这个模式不会读取本地 mock，也不会自动捕获后端响应。

### 带面板的开发模式

```ts
automock({
  proxyBaseUrl: 'https://api.example.com',
  inspector: true,
})
```

启动 Vite 后访问 `/__mock/`。

### 内部预发环境启用 mock，正式生产关闭

```ts
automock({
  mockDir: 'mock',
  productionMock: 'auto',
})
```

`vite build --mode staging` 会启用，`vite build --mode production` 会关闭。

## 配置之间的关系

- `enabled=false` 优先级最高，会跳过插件全部处理。
- `proxy=false` 只影响未命中 mock 后是否代理，不影响已启用 mock 的返回。
- `capture=false` 只影响代理响应是否保存，不影响代理本身。
- `capture=true` 但没有 `proxyBaseUrl` 时不会捕获，因为没有插件代理请求。
- `productionMock` 只影响客户端拦截器和构建期 bundle，不影响开发服务器 middleware 是否返回 mock。
- `bundleMockData=true` 只有在 `productionMock` 解析为启用时才会生效。
- `inspector` 只在开发服务器中可用，不参与生产客户端拦截。

## 可评估的精简候选

这些不是本次变更要删除的功能，只是为了后续决策时更容易看清复杂度来源：

1. `enabled`、`proxy`、`capture` 三个开关容易被理解成完全独立，但 `enabled` 实际是总开关。
2. `productionMock`、`bundleMockData`、客户端 Axios 拦截器是一整套生产 mock 能力，如果项目只需要开发期 mock，可以考虑弱化或拆出文档。
3. `initMockInterceptorForPureHttp` 是面向特定封装的适配层，可以评估是否还需要作为核心 API 暴露。
4. 二进制 mock 对下载、图片、文档接口有价值，但会增加 mock 文件管理复杂度。
5. 可视化 inspector 很方便，但配置、模板和 API 较多，可以考虑作为可选高级能力呈现。

## 排查清单

- 请求没有命中 mock：检查 URL 的 pathname 是否在 `apiPrefix` 下，mock 文件是否位于 `mockDir/<path>/<method>.js`。
- 请求被错误代理：确认没有同时配置同前缀的 Vite `server.proxy` 和 automock `proxyBaseUrl`。
- 没有生成 `mock-data.json`：确认 `productionMock` 不是 `false`，且 `bundleMockData=true`。
- 生产拦截器没有生效：确认应用入口调用了 `initMockInterceptor(axios)`，并且浏览器能访问 `/mock-data.json`。
- 动态 mock 没有进入生产 bundle：这是预期行为，动态函数只适合开发期 middleware。
