前端工程化之数据mock
在next.js中使用msw (mock server worker)进行数据mock
在开发的过程中,需要与服务端对接,这个工作流程通常是前端-服务端协定协议,服务端根据协议开发接口,前端模拟协议进行开发内容。这个过程中前端需要模拟服务端数据,模拟服务端数据的过程就叫做Mock;常见的库是Mock Server Workder下面简称MSW;
补充知识:Next.js 使用React技术栈,支持服务端渲染(SSR)与前端渲染(CSR);
那么我们Mock数据的时候就要针对这2种情况进行mock;
MSW依然提供了2种平台下的mock方式,底层逻辑都是拦截对应平台http请求,然后模拟发送数据;
Handlers概念
Handlers 是模拟浏览器请求的返回值逻辑;类似于下面这样;
import { HttpResponse, http } from "msw"
const mocks = [
http.get('http://api.example.com/user', () => { // 模拟获取用户数据
return HttpResponse.json({
id: '15d42a4d-1948-4de4-ba78-b8a893feaf45',
firstName: 'John',
})
})
]
export default mocks;
浏览器
Mock数据
import { setupWorker } from 'msw/browser'; // 这是msw提供的浏览器端mock
import handlers from '../handlers';
export const setupMock = () => {
setupWorker(...handlers).start();
}
浏览器端mock记得要初始化一下 npx msw init <PUBLIC_DIR>
; 由于浏览器端的原理是使用Server Worker来实现,所以要有一个Worker的执行文件,这个初始化动作就是配置了Worker的初始化文件。
在next.js入口启动mock
// app/layout.tsx
import { setupMock } from '../mock/setup';
...
setupMock(); // 启用mock
...
使用Mock数据
'use client' // 在next.js中使用到BOM、DOM等方法均要声明use client告知next.js这是使用在客户端的
import axios from 'axios'; // 选择使用axios是为了下面Node端的时候避免一个坑,下面介绍
import React from 'react';
async function getUser() {
return (await axios.get('http://api.example.com/user')).data;
}
const Button:React.FC<{}> = ()=>{
return <button onClick={getUser}>get user</button>; // 这里使用了onClick是浏览器事件,所以上面要声明use client
}
Node
mock数据
import { setupServer } from 'msw/node';
import handlers from '../handlers';
export const setupMock = () => {
setupServer(...handlers).listen();
}
在next.js入口启动mock
同浏览器中,不重复了
使用Mock数据
// app/page.tsx
import axios from 'axios';
async function getUser() {
return (await axios.get('http://api.example.com/user')).data
}
export default async function Home() {
const res = await getUser(); // Next.js 服务端渲染预先获取服务端数据
const id = res.id;
return <div>{id}</div>
}
注意,不要使用 Fetch API!mws 是通过拦截 Node 的 http
/https
module 实现 API Mocking 的,因此 Node 中原生支持的 fetch API 会 Mock 失败的。这里是借助axios解决这个问题
Next.js 方案总和
需要有一个中间文件来总和服务端于浏览器的情况,让业务开发不需要考虑环境的影响。
// 开发环境(development)下默认为 YES; 非开发环境下默认为 NO;
const { NODE_ENV, USE_MOCK = NODE_ENV === 'development' ? 'YES' : 'NO' } = process.env;
// 总和setupMock;判断当前的环境使用不同的mock方式
export async function setupMock() {
if (USE_MOCK === 'YES') {
const { setupMock } =
typeof window !== 'undefined' ?
await import('./setupBrower') : await await import('./setupNode');
setupMock();
console.log('MSW: OPEN')
}
}
入口中使用
// app/layout.tsx
import { setupMock } from '../mock/setup';
...
await setupMock(); // 启用mock; 这里记得await 因为在上总和的部分使用了 import()按需加载所要的文件,所以要等待初始化结束
...
MSW的使用介绍与前端Mock数据的内容到此结束,谢谢观看;
- Handlers概念
- 浏览器
- Mock数据
- 使用Mock数据
- Node
- mock数据
- 使用Mock数据
- 入口中使用