简介
Mirage 是一个可让前端开发人员模拟后端 API 的 JavaScript 库。
与其他模拟库不同,Mirage 使重建动态 场景变得容易,动态场景通常仅在实际 生产环境中才可能出现。
几乎所有的 JavaScript 应用程序都需要与 HTTP API 进行交互。在开发过程中需要使用动态服务器数据时,通常有几种选择:
为后端服务做一个本地或托管版本的代理。如果您已经有一套 API 了,就可以这样做,但通常是没有。即使这样做,很多时候您还需要使用与实际 API 上不同的服务器状态。
注释掉应用程序的网络请求代码部分,并用虚拟数据填充。这是最快的选择,但是在您已经编写了很多应用程序代码之后,它会迫使您直接处理网络问题。
使用客户端拦截器处理应用程序的网络请求。一些 HTTP 客户端附带了模拟适配器(例如 axios-mock-adapter 可用于模拟由 axios 发出的网络请求),还有诸如 Pretender 之类的独立工具,可用于在浏览器中拦截应用程序的网络请求。这是最灵活的方法,但是它要求你的每个项目从一开始就要引入这些工具,然后由您自己来在整个应用程序中实施某些功能。
Mirage 旨在解决这些问题。它是在客户端中运行的伪服务器,可以在开发和测试中使用,并且其自带来了足够多的常用功能以使您快速启动并运行。
工作原理
Mirage 在浏览器中运行。它拦截您的 JavaScript 应用程序发出的任何 XMLHttpRequest
或 fetch
发出的请求,并允许您模拟这些请求所对应的响应结果。这意味着您可以像在与真实服务器对话一样开发和测试您的应用程序。
假设我们正在编写这个 React 组件:
// App.js
import React, { useState, useEffect } from "react"
export function App() {
let [users, setUsers] = useState([])
useEffect(() => {
fetch("/api/users")
.then((response) => response.json())
.then((json) => setUsers(json))
}, [])
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
我们使用一个简单的 Mirage 路由处理器来处理 /api/users
所发出的网络请求,如下所示:
// App.js
import React, { useState, useEffect } from "react"
import { createServer } from "miragejs"
createServer({
routes() {
this.get("/api/users", () => [
{ id: "1", name: "Luke" },
{ id: "2", name: "Leia" },
{ id: "3", name: "Anakin" },
])
},
})
export function App() {
let [users, setUsers] = useState([])
useEffect(() => {
fetch("/api/users")
.then((response) => response.json())
.then((json) => setUsers(json))
}, [])
return (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
重要的是,由于 Mirage 模拟的是 HTTP 部分,而不是您的应用程序用于发出网络请求的 JavaScript 代码,因此您无需修改 UI 代码即可了解您的应用程序是在与 Mirage 对话还是与实际的生产后端对话。
除了拦截 HTTP 请求外,Mirage 还提供了一个模拟数据库和一系列辅助函数,可以轻松地模拟动态的后端服务。
Mirage 借鉴了典型服务器端框架的概念,例如:
- 处理 HTTP 请求的 路由(routes)
- 数据库(database) 和 数据模型(models) 用于存储数据和定义数据之间的关系
- 用于 stubbing data 的 工厂函数(factories) 和 fixtures
- 用于格式化 HTTP 响应的 序列化程序(serializers)
帮助您快速配置模拟服务器。