mswjs:在浏览器和 Node 环境中轻松做 API Mocking

mswjs 是一个同时兼容浏览器和 Node 的 API mocking 库,帮助开发者在 API 还没 ready 的情况下,通过 mock 数据进行完美开发。
mswjs 原理(浏览器端)是使用 Service Worker API 拦截(网络层)实际请求实现 API 的请求、响应模拟。
官网地址:https://mswjs.io/
下面我们会创建一个 Next.js 项目,来演示 mwsjs 的使用。
定义 mocks
按照约定,我们将 mock 定义放在 src/mocks
目录中:
Mocking API
mwsjs 支持两种类型的 API Mock,一个是 REST API,一个是 GraphQL API。如果你知道两者的区别,或者压根就不知道 GraphQL,也没有关系,无脑看成 REST API 就行,因为我们 99.9% 的项目都是用 REST API。
我们编辑 handlers.js
:
rest
就是一个服务器(类似 express()
),用于处理请求和响应,我们下面分别介绍。
Request handler
假设我们要做一个基础的登录功能。需要准备两个接口:
POST /login
:登录使用GET /user
:现在登录用户信息
先创建请求处理器 Request handler,使用 rest[METHOD]
方式:
handlers.js
文件是通过一个叫 handlers
的命名导出暴露拦截的/要 Mock 的请求的。
Response resolver
前一步已经做到请求拦截了,这一步我们在 Mock 响应数据:
响应回调函数接受 3 个参数:
req
:匹配请求的信息res
:用于创建模拟响应的功能函数ctx
:包含一系列用于设置模拟响应的状态码、头部、正文等功能的函数
整合
当然,上面这些约定 Mocking API 写好之后,并不会自动生效,我们还需要整合到现有项目中。
当然,这块我们根据浏览器端、Node 端分别介绍。
浏览器端
准备
Mock Service Worker 在客户端是通过 Service Worker 做请求拦截的,因此这块我们要单独启动个服务器服务 来自 mwsjs Service Worker 文件中的代码请求 。
这块代码不需要我们手写,直接使用 npx msw init <PUBLIC_DIR> --save
指令就可以了。这里的 <PUBLIC_DIR>
就是指项目的静态资源的存放目录,对 Next.js 来说,就是项目跟路径下的 public/
目录:
执行完成后,会在 public/
下,看到多出一个 mockServiceWorker.js
文件。mockServiceWorker.js
不需要我们做任何修改,放在这里就行了。这个 worker 脚本会被注入到浏览器网页中,用于拦截请求。
注意,这里的 --save
是必须的,这个选项会在 package.json
文件中写一个 msw
字段。
这样日后更新 msw 包的时候,public/
目录下的 worker 脚本会自动更新。
配置 worker
接下来在创建 src/mocks/browser.js
文件:
这一步将我们定义的 handlers 绑定到 mws 上(这时候定义的 Mock API 才与 mws 有了联系)。
我们导出 worker
实例。
启动 worker
worker
实例准备好后,就要在合适的时机启动 worker 了(worker.start()
):
对 Next.js 项目而言,我们在 pages/_app.tsx
中引入:
我们只在开发环境下才进行 API Mock。现在,localhost:3000 打开网页,看见下面的打印结果就说明接入成功了。

然后添加按钮,模拟登录:
发现接口 Mock 成功了!

Node 端
配置服务器
创建src/mocks/server.js文件:
setupServer()
使用之前定义好的 handlers
创建一个服务器。
需要注意的是,非 DOM 环境下的请求 URL 都必须使用绝对地址(absolute request URLs)。
在我们创建的 Next.js 项目中,默认会有一个src/pages/api/hello.ts的 API 路由。我们可以利用它来作为我们测试后端接口请求的方式:
或者借助 axios:
注意,不要使用 Fetch API!mwsjs 是通过拦截 Node 的 http
/https
module 实现 API Mocking 的,因此 Node 中原生支持的 fetch API 会 Mock 失败的。
启动服务器
在pages/_app.tsx中引入:
浏览器访问 http://localhost:3000/api/hello 就能看到正确的 Mock 数据了。

区分 dev/prod 环境
目前我们的代码在开发(development,对应next dev)和生产环境(production,对应next start)都会启用 API Mocking,这不是我们想要的。
因此,我们需要控制只在开发环境进行 API Mocking,我们可以借助Next.js 的环境文件支持。
首先,在项目根目录下创建两个文件:.env.development和.env.production:
Next.js 会将 NEXT_PUBLIC_
做前缀的环境变量,在浏览器和 Node 环境中都设置。如上所示,开发环境我们启用 mwsjs,生产环境则禁用 mwsjs。
接下来调整一下 pages/_app.tsx
中的代码,判断仅在 API Mocking 启用的情况下,引入 mwsjs 配置。
当然,如果感觉 _app.tsx
中的代码很多,也可以将 initMocks
函数放到 mocks/index.js
文件中:
然后修改 pages/_app.tsx
文件:
还是一样的效果。
好了,关于 mwsjs 的介绍就到这里啦,感谢各位的阅读!
参考链接
https://mswjs.io/docs/getting-started/install
https://www.geeksforgeeks.org/node-js-https-request-function/
https://github.com/vercel/next.js/blob/canary/examples/with-msw
https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables