主流的解决方案
1. MSW (Mock Service Worker)
定义 MOCK 数据
import { rest } from 'msw'
export const handlers = [
// 模拟获取动物声音列表
rest.get('/api/animals', (req, res, ctx) => {
return res(
ctx.json([
{ id: 1, name: 'Cat', sound: 'meow.mp3' },
{ id: 2, name: 'Dog', sound: 'woof.mp3' }
])
)
})
// 模拟获取单个动物声音
rest.get('/api/animals/:id', (req, res, ctx) => {
const { id } = req.params
return res(
ctx.json({
id: parseInt(id),
name: 'Cat',
sound: 'meow.mp3'
})
)
})
]
引用 Mock 数据
import { setupWorker } from 'msw'
import { handlers } from './handlers'
// 只在开发环境启用
if (process.env.NODE_ENV === 'development') {
const worker = setupWorker(...handlers)
worker.start()
}
2. Mock.js
适合快速模拟数据:
import Mock from 'mockjs'
// 配置拦截 ajax 请求的响应时间
Mock.setup({
timeout: '200-600'
})
// 模拟获取动物列表
Mock.mock('/api/animals', 'get', {
'code': 200,
'data|1-10': [{
'id|+1': 1,
'name|1': ['Cat', 'Dog', 'Bird'],
'sound': '@word.mp3'
}]
})
// 区分环境
if (process.env.NODE_ENV === 'development') {
require('./mock')
}
3. JSON Server
适合快速搭建完整的 REST API:
{
"animals": [
{
"id": 1,
"name": "Cat",
"sound": "meow.mp3"
},
{
"id": 2,
"name": "Dog",
"sound": "woof.mp3"
}
]
}
启动 JSON Server:
# 安装
npm install -g json-server
# 启动服务
json-server --watch mock/db.json --port 3000
这几个方案的优缺点
MSW
优点:
- 可以精确模拟网络状态和延迟
- 基于 Service Worker,可以拦截网络请求
缺点:
- 配置相对复杂,需要了解 Service Worker
- 需要子解 MSW 的 API,学习成本较高
- 不能直接 faker 数据,需要引入别的库实现
- 需要修改代码才能切换真实接口
- 需要编写代码实现 mock 数据;
Mock.js
优点:
- 上手简单,只需要配置拦截规则
- 中文文档完善,适合国内开发者
- 数据模板功能强大,可以生成各种格式数据
- 无需启动服务器,直接拦截 Ajax 请求
缺点:
- 需要修改代码才能切换真实接口
- 需要子解 Mock.js 的 API,学习成本较高
- 需要编写代码实现 mock 数据;
3. JSON Server
优点:
- 零代码即可搭建完整的 REST API
- 支持标准的 RESTful 操作
- 可以直接使用 JSON 文件作为数据源
- 适合前端快速原型开发
缺点:
- 需要单独启动服务
- 功能较为简单,不支持复杂逻辑
- 对于单独要某几个接口 mock 数据比较麻烦
- 需要修改配置才能切换真实接口
- 无法 faker数据
我们为什么要 mock 数据,现有方案存在的问题
先看看我们为什么要用 mock 数据,一般有以下几种情况
- 开发中在后端接口还没开发完成,让前端能提前做接口的测试,而不用依赖后端;
- 在线上或测试环境的接口数据引起错误时,能快速把数据复制下来,作为 mock 数据,快速还原错误场景;
- 在后端的环境出现错误时,能速切换到 mock 数据,以防因后端环境影响前端开发
- 某一些场景与这次开发无关的接口,通过 MOCK 数据绕开一些复杂操作才能返回目标数据的接口
基于以上需要,在这解决方案中,我更喜欢的解决方案是JSON Server,因为 MOCK 数据只是开发流程中为了提效一个环节,应该尽可能简单,并且要完全模拟请求;
对于Mock.js,MSW 都是通过请求的拦截,并非实际的请求,并且这两个都有一定的上手门;faker数据也有一定的上手门槛,需要了解相关的编写方式;
而JSON Server可以说无上手门槛,并且是真实的请求,但缺点也很明显无法faker数据,这对于需要模似大量数场景很有必要如要一次返回 1000 条不同的数据,不可能复制数据再一条条去改得不一样,需要单独启动服务;对同一个接口,根据不同的请求数据,返回不同的数据;
而且以上的方案都有一个很大的缺点是: 无法快切换 mock 数据,都需要改动代码或者切换配置,这个看似简单的操作,很多时候对编码很不友好,
- 会打断编码的连贯性,
- 需要花时间去改对应的代码,
- 不直观,你不知哪些接口是用了 mock 数据,哪些是没有,要看代码或者配置
上面提到还有一个重要的场景,就是“在线上或测试环境的接口数据引起错误时,能快速把数据复制下来,作为 mock 数据,快速还原错误场景;”,以上的方案都没有对这个场景有很好的优化方案,必须在浏览器中去复制数据到 mock 的工具中;
我希望优雅的方式
基于以上的分析我希望的 mock 数据工具能实现以下几点
- 无上手门槛
- 支持无门槛的快速 faker 数据
- 能一目了然的知道哪些接口用了mock数据
- 能快速切换 mock 数据,还是真实接口请求,并且支持单独某几个接口的切换
- 支持接口数据,直接导入到 mock 数据;
- 支持同一个接口,根据不同的请求数据,返回不同的数据;
- 无入侵,与规模代码完全分离
mocxykit的解决方案
mocxykit,可以完成实现我上面的希望,mocykit 本身是devServer 的插件,支持express, vite, webpack 及 rsbuild,可借助项目本身的 sever 实现 mock 数据;
先让我们把mocxykit 集成到项目中;
安装mocxykit
首先先安装这个插件
npm install mocxykit --save-dev
然后以 vite 为例,改变vite.config.js(如果没有这个文件,可以在根目录创建下) 的配制,添加这个插件
import { defineConfig } from 'vite'
import { viteProxyMockPlugin } from 'mocxykit'
export default defineConfig({
plugins: [
viteProxyMockPlugin()
]
})
可视化的解决方案
启动项目,在浏览器上访问项目,这个时候就会看到项目的右下角多了一个(proxy&mock 配制)按钮
点击这个按钮,就能看到到一个可视化的 mock 配置界面
这里我们需要配置一个全局代理,让在非 mock 数据时,接口请求到代理到指定的域名,(在项目中的接口请求不用指定域名,直接请求接口 url);
在这个界面中我们可以随时切换,mock 数据,还是请求真实接口;
通过点击 新增 MOCK 数据或者设置按钮,我们可以直接配置 MOCK 数据;
可视化解决了以下问题
- 无上手门槛
- 能一目了然的知道哪些接口用了mock数据
- 能快速切换 mock 数据,还是直实接口请求,并且支持单独某几个接口的切换
根据不同的请求数据,返回不同的数据;
点击修改入参,还能实现配制入参,在根据不同的请求数据,返回不同的数据
无门槛的快速 faker 数据
勾选返回随机数据,他会根据你配置的 mock 数据的,可指定要返回随机数据的字段,条数,判断你的每个字段的数据类型,返回随机数据;
- 自动识别数据类型(如邮箱、手机号、URL等)并生成对应格式的随机数据
- 支持中英文混合数据的智能生成
- 通过特殊语法控制数组长度:
data.list<100>生成100条随机数据 - 支持多字段随机化:
data.list,page.total - 自动保持字符串格式:数字字符串保持位数,字母数字混合保持格式
接口数据,直接转换为 MOCK数据;
mocxy 会记录,最近请求的接口数据
点击导入数据,就可把接口数据导入为 mock 数据;
总结:
mocxykit 完全实现易用,无入侵,高效,mock数据作为开发重要的一环,但同时也不应有过多的心智负担,毕竟它只是在开发环间的数据,应该怎么快怎么来;