Mirage JS
面向前端开发的客户端 Mock 服务器库
面向前端开发的客户端 Mock 服务器库,在浏览器或测试环境中拦截网络请求并返回模拟数据。提供类似后端 ORM 的模型、工厂和关系定义,曾是 Ember/React 生态流行的 API Mock 方案;MSW 2.x 兴起后新项目更常选择 MSW,但 Mirage 在遗留项目和需要关系型假数据的场景仍有价值。
Mirage JS 客户端 Mock 服务器技术调研
Mirage JS 是面向前端开发的客户端 Mock 服务器库,在浏览器或测试环境中拦截网络请求并返回模拟数据。它提供类似后端 ORM 的模型、工厂和关系定义,曾是 Ember/React 生态流行的 API Mock 方案;MSW 2.x 兴起后,新项目更常选择 MSW,但 Mirage 在遗留项目和需要关系型假数据的场景仍有价值。
一、 基本信息
| 维度 | 关键指标 / 描述 |
|---|---|
| 技术标签 | API Mock / 假数据 / 客户端服务器 / 测试 |
| 开发商 | Mirage JS 开源社区 |
| 官方网站 | https://miragejs.com/ |
| GitHub 仓库 | miragejs/miragejs |
| npm 包 | miragejs |
| 许可协议 | MIT License |
| 首次发布 | 2019 年(前身 Pretender + Ember CLI Mirage) |
| 当前版本 | Mirage JS 0.1.x(维护模式,非活跃大版本迭代) |
| 生态成熟度 | 中(被 MSW 逐步替代,仍有存量项目) |
二、 技术定位与简介
Mirage JS 在应用内启动一个 轻量 Mock 服务器:
- 使用 Pretender 拦截
XMLHttpRequest和fetch。 - 通过 路由处理器 定义 REST 端点行为。
- 通过 Model、Factory、Serializer 管理假数据与关系。
- 支持 belongsTo、hasMany 等关系,适合模拟复杂 CRUD。
与 MSW 相比,Mirage 更偏向「内存数据库 + REST 路由」范式,而非纯 handler 函数;学习曲线略高,但关系型数据场景表达力强。
三、 快速上手安装说明
1. 安装
pnpm add -D miragejs2. 基础 Server 定义
// src/mirage/server.ts
import { createServer, Model } from 'miragejs'
type User = { id: string; name: string; email: string }
export function makeServer({ environment = 'development' } = {}) {
return createServer({
environment,
models: {
user: Model.extend<Partial<User>>({}),
},
seeds(server) {
server.create('user', { id: '1', name: 'Alice', email: '[email protected]' })
server.create('user', { id: '2', name: 'Bob', email: '[email protected]' })
},
routes() {
this.namespace = 'api'
this.get('/users', (schema) => schema.all('user'))
this.get('/users/:id', (schema, request) => {
return schema.find('user', request.params.id)
})
this.post('/users', (schema, request) => {
const attrs = JSON.parse(request.requestBody)
return schema.create('user', attrs)
})
},
})
}3. 在开发环境启动
// main.ts
if (import.meta.env.DEV) {
const { makeServer } = await import('./mirage/server')
makeServer()
}4. 测试环境
let server: ReturnType<typeof makeServer>
beforeEach(() => {
server = makeServer({ environment: 'test' })
})
afterEach(() => {
server.shutdown()
})四、 核心特性
1. 内存数据存储
Schema 管理 models,支持 CRUD 与关系。
2. Factory 与 Fixture
import { Factory } from 'miragejs'
factory: Factory.extend({
name: (i) => `User ${i}`,
email: (i) => `user${i}@test.com`,
})3. Serializer
控制 API 响应 JSON 结构(JSON:API 风格或自定义)。
4. 关系模型
belongsTo、hasMany 模拟关联查询。
5. 路由 DSL
RESTful 路由声明式定义,支持嵌套路由。
6. 环境区分
development / test 环境不同 seeds 与配置。
7. 与 Pretender 集成
底层拦截 XHR/fetch,应用无感知。
五、 适用场景
1. 黄金适用场景
- 遗留项目已使用 Mirage,继续维护。
- 需要内存 CRUD 与关系型假数据。
- Ember 生态项目(历史渊源深)。
- 演示应用需要可交互的假后端。
- 原型阶段快速搭建 REST API 行为。
2. 局限适用场景
- 新项目优先 MSW(更现代、同构、社区活跃)。
- 仅需静态 Mock 响应(MSW 更简单)。
- GraphQL 为主(MSW graphql 支持更好)。
- 需要真实独立 HTTP 进程(json-server)。
六、 技术亮点
1. 关系型假数据
比简单 stub 更接近真实 REST 后端行为。
2. 声明式路由 DSL
REST 资源路由表达清晰。
3. 测试友好
server.shutdown() 隔离测试,seeds 重置状态。
4. 框架无关
可用于 React、Vue、Angular 等。
5. 历史积淀
大量教程和 Ember 生态实践可参考。
七、 核心概念与架构
digraph Mirage_Architecture {
rankdir=LR
node [shape=box, style="rounded,filled", fillcolor="#f0f9ff"]
App [label="Application", fillcolor="#bae6fd"]
Pretender [label="Pretender\n(Intercept)"]
Router [label="Route Handlers"]
Schema [label="Schema\n(Models/DB)"]
Factory [label="Factories/Seeds"]
App -> Pretender
Pretender -> Router
Router -> Schema
Factory -> Schema
Schema -> App
}八、 技术局限与边界
- 社区活跃度下降:MSW 成为主流,新特性少。
- 包体积:比 MSW 更重(含 ORM 层)。
- fetch 拦截演进:MSW 在网络层更彻底。
- 学习曲线:Model/Factory/Serializer 概念多。
- 与真实 API 行为差异:内存 DB 无法模拟所有后端逻辑。
- TypeScript 类型:需额外配置获得良好类型体验。
九、 生态地图
| 类别 | 说明 |
|---|---|
| 底层 | Pretender |
| 前身 | Ember CLI Mirage |
| 替代 | MSW、json-server |
| 测试 | Jest、Vitest、Cypress |
| 框架 | React、Vue、Ember |
十、 生态集成
| 方向 | 说明 |
|---|---|
| Vitest/Jest | makeServer({ environment: 'test' }) 每用例隔离。 |
| Cypress | 可在 support 文件启动 Mirage。 |
| Create React App | 历史教程常见 Mirage 集成。 |
| 迁移到 MSW | 逐步将 routes 转为 MSW handlers。 |
十一、 开发与工程化
1. 迁移评估
新项目直接用 MSW;存量 Mirage 可渐进迁移。
2. 目录结构
src/mirage/
server.ts
models/
factories/
serializers/
routes/3. 与真实 API 对齐
定期对照 OpenAPI 更新 models 字段,防止 Mock 漂移。
十二、 性能与安全
- 内存数据,性能通常足够开发/测试。
- 勿在生产启用 Mirage。
- seeds 数据勿含真实 PII。
server.shutdown()防止测试间状态泄漏。
十三、 技术对比
| 工具 | 优势 | 局限 | 适合 |
|---|---|---|---|
| Mirage JS | 关系型假 DB、REST DSL | 维护放缓 | 遗留/关系 Mock |
| MSW | 现代、同构、活跃 | 无内置 ORM | 新项目首选 |
| json-server | 真实 HTTP、零代码 | 功能简单 | 快速原型 |
| Apifox Mock | 文档驱动 | 需平台 | 团队协作 |
十四、 最佳实践
- 新项目优先 MSW,除非强依赖 Mirage ORM。
- 测试每个用例
shutdown()重置 server。 - Factory 生成数据保持与 API 契约字段一致。
- 复杂业务逻辑在 route handler 显式实现,勿过度依赖 ORM 魔法。
- 规划从 Mirage 到 MSW 的迁移路径。
- 开发环境条件启动,生产 tree-shake。
- Serializer 与真实 API 响应格式保持一致。
十五、 学习与社区资源
- 官方文档:https://miragejs.com/docs/
- GitHub:https://github.com/miragejs/miragejs
- 迁移讨论:社区 MSW 迁移指南与博客文章