• 使用 roadhog 的请求代理功能
    • 引入 Mock.js
    • 添加跨域请求头
  • 合理的拆分你的 mock 文件
  • 如何模拟延迟
    • 手动添加 setTimeout 模拟延迟
    • 使用插件模拟延迟
  • 生成 API 文档
    • 联调

    Mock 数据是前端开发过程中必不可少的一环,是分离前后端开发的关键链路。通过预先跟服务器端约定好的接口,模拟请求数据甚至逻辑,能够让前端开发独立自主,不会被服务端的开发所阻塞。

    在 Ant Design Pro 中,因为我们底层的工具是 roadhog,而它自带了代理请求功能,通过代理请求就能够轻松处理数据模拟的功能。

    使用 roadhog 的请求代理功能

    在通过配置 .roadhogrc.mock.js 来处理代理请求,支持基于 require 动态分析的实时刷新,支持 ES6 语法,以及友好的出错提示,详情参看 roadhog。

    1. export default {
    2. // 支持值为 Object 和 Array
    3. 'GET /api/users': { users: [1, 2] },
    4. // GET POST 可省略
    5. '/api/users/1': { id: 1 },
    6. // 支持自定义函数,API 参考 express@4
    7. 'POST /api/users/create': (req, res) => { res.end('OK'); },
    8. // Forward 到另一个服务器
    9. 'GET /assets/*': 'https://assets.online/',
    10. // Forward 到另一个服务器,并指定子路径
    11. // 请求 /someDir/0.0.50/index.css 会被代理到 https://g.alicdn.com/tb-page/taobao-home, 实际返回 https://g.alicdn.com/tb-page/taobao-home/0.0.50/index.css
    12. 'GET /someDir/(.*)': 'https://g.alicdn.com/tb-page/taobao-home',
    13. };

    当客户端(浏览器)发送请求,如:GET /api/users,那么本地启动的 roadhog dev 会跟此配置文件匹配请求路径以及方法,如果匹配到了,就会将请求通过配置处理,就可以像样例一样,你可以直接返回数据,也可以通过函数处理以及重定向到另一个服务器。

    比如定义如下映射规则:

    1. 'GET /api/currentUser': {
    2. name: 'momo.zxy',
    3. avatar: imgMap.user,
    4. userid: '00000001',
    5. notifyCount: 12,
    6. },

    访问的本地 /api/users 接口:

    请求头

    Mock 和联调 - 图1

    返回的数据

    Mock 和联调 - 图2

    引入 Mock.js

    Mock.js 是常用的辅助生成模拟数据的第三方库,当然你可以用你喜欢的任意库来结合 roadhog 构建数据模拟功能。

    1. import mockjs from 'mockjs';
    2. export default {
    3. // 使用 mockjs 等三方库
    4. 'GET /api/tags': mockjs.mock({
    5. 'list|100': [{ name: '@city', 'value|1-100': 50, 'type|0-2': 1 }],
    6. }),
    7. };

    添加跨域请求头

    设置 response 的请求头即可:

    1. 'POST /api/users/create': (req, res) => {
    2. ...
    3. res.setHeader('Access-Control-Allow-Origin', '*');
    4. ...
    5. },

    合理的拆分你的 mock 文件

    对于整个系统来说,请求接口是复杂并且繁多的,为了处理大量模拟请求的场景,我们通常把每一个数据模型抽象成一个文件,统一放在 mock 的文件夹中,然后再在 .roadhog.mock.js 中引入。

    Mock 和联调 - 图3

    .roadhog.mock.js 的样例如下:

    1. import mockjs from 'mockjs';
    2. // 引入分离的 mock 文件
    3. import { getRule, postRule } from './mock/rule';
    4. import { getActivities, getNotice, getFakeList } from './mock/api';
    5. import { getFakeChartData } from './mock/chart';
    6. import { getProfileBasicData } from './mock/profile';
    7. import { getProfileAdvancedData } from './mock/profile';
    8. import { getNotices } from './mock/notices';
    9. const proxy = {
    10. 'GET /api/fake_list': getFakeList,
    11. 'GET /api/fake_chart_data': getFakeChartData,
    12. 'GET /api/profile/basic': getProfileBasicData,
    13. 'GET /api/profile/advanced': getProfileAdvancedData,
    14. 'GET /api/notices': getNotices,
    15. };
    16. export default proxy;

    如何模拟延迟

    为了更加真实的模拟网络数据请求,往往需要模拟网络延迟时间。

    手动添加 setTimeout 模拟延迟

    你可以在重写请求的代理方法,在其中添加模拟延迟的处理,如:

    1. 'POST /api/forms': (req, res) => {
    2. setTimeout(() => {
    3. res.send('Ok');
    4. }, 1000);
    5. },

    使用插件模拟延迟

    上面的方法虽然简便,但是当你需要添加所有的请求延迟的时候,可能就麻烦了,不过可以通过第三方插件来简化这个问题,如:roadhog-api-doc。

    1. import { delay } from 'roadhog-api-doc';
    2. const proxy = {
    3. 'GET /api/project/notice': getNotice,
    4. 'GET /api/activities': getActivities,
    5. 'GET /api/rule': getRule,
    6. 'GET /api/tags': mockjs.mock({
    7. 'list|100': [{ name: '@city', 'value|1-100': 50, 'type|0-2': 1 }]
    8. }),
    9. 'GET /api/fake_list': getFakeList,
    10. 'GET /api/fake_chart_data': getFakeChartData,
    11. 'GET /api/profile/basic': getProfileBasicData,
    12. 'GET /api/profile/advanced': getProfileAdvancedData,
    13. 'POST /api/register': (req, res) => {
    14. res.send({ status: 'ok' });
    15. },
    16. 'GET /api/notices': getNotices,
    17. };
    18. // 调用 delay 函数,统一处理
    19. export default delay(proxy, 1000);

    生成 API 文档

    在跟服务端联调开发的时候,往往需要约定接口,包含路径,方法,参数,返回值等信息,roadhog-api-doc 提供通过 .roadhog.mock.js 自动生成文档的功能,安装使用详见:roadhog-api-doc。

    而相关的文档信息,同样需要按照 roadhog-api-doc 提供的方式写到 .roadhog.mock.js 中。

    1. import { postRule } from './mock/rule';
    2. import { format } from 'roadhog-api-doc';
    3. const proxy = {
    4. 'GET /api/currentUser': {
    5. // 接口描述
    6. $desc: "获取当前用户接口",
    7. // 接口参数
    8. $params: {
    9. pageSize: {
    10. desc: '分页',
    11. exp: 2,
    12. },
    13. },
    14. // 接口返回
    15. $body: {
    16. name: 'momo.zxy',
    17. avatar: imgMap.user,
    18. userid: '00000001',
    19. notifyCount: 12,
    20. },
    21. },
    22. 'POST /api/rule': {
    23. $params: {
    24. pageSize: {
    25. desc: '分页',
    26. exp: 2,
    27. },
    28. },
    29. $body: postRule,
    30. },
    31. };
    32. // format 函数用于保证本地的模拟正常,如果写了文档,这个函数转换是必要的
    33. export default format(proxy);

    生成的结果如下:

    Mock 和联调 - 图4

    联调

    当本地开发完毕之后,如果服务器的接口满足之前的约定,那么只需要关闭 mock 数据或者代理到服务端的真实接口地址即可。

    1. $ npm run start:no-proxy