简介

Mirage 是一个 JavaScript 库,可以让前端开发者模拟后端 API。

与其他模拟库不同,Mirage 使得轻松地重现动态场景变得容易,而这类场景通常只能在使用真实的生产服务器时才能实现。


几乎所有 JavaScript 应用程序都与 HTTP API 交互。当您在开发过程中需要使用动态服务器数据时,您有几个选择

  1. 代理到您实际后端的本地或托管版本。 如果您已经拥有 API,这可能行得通,但您通常没有。即使您有 API,您也经常希望使用与实时 API 上不同的服务器状态。

  2. 注释掉应用程序的网络请求并用虚拟数据替换它们。 这是最快的选择,但它迫使您在以后处理网络问题,那时您已经编写了大量应用程序代码。

  3. 使用客户端拦截器来处理应用程序的网络请求。 一些 HTTP 客户端带有模拟适配器(例如,axios-mock-adapter 可用于模拟使用 axios 进行的请求),并且还有一些独立工具,例如 Pretender,您可以使用它们来拦截应用程序的网络请求在浏览器中。 这是最灵活的方法,但它要求您在每个项目中从头开始,并将跨应用程序强制执行约定留给您。

Mirage 的构建是为了解决这些问题。它是一个在客户端运行的伪造服务器,可以在开发和测试中使用,并且它包含足够的约定,可以帮助您快速启动和运行。

工作原理

Mirage 运行在浏览器中。它会拦截 JavaScript 应用程序发出的任何 XMLHttpRequestfetch 请求,并允许您模拟响应。这意味着您可以像与真实服务器通信一样开发和测试应用程序。

假设我们正在处理这个 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 请求
  • 数据库模型 用于存储数据和定义关系
  • 工厂Fixture 用于模拟数据,以及
  • 序列化器 用于格式化 HTTP 响应

帮助您快速配置模拟服务器。