搭一个Mock Server,再也不用等后台接口了

6,894 阅读4分钟

Mock Server

以前开发项目就是切好图等待后台将接口给我们,在进行数据交互、业务逻辑。 想在接口没号之前就进行业务逻辑的编写就得自己写假数据。

Mock的几种方式

前端中写死数据

自己写大量的假数据,很耗时间。对接接口时又得全部删除。

复用率底,成本高

代理工具拦截

利用 fiddlerCharles 拦截网络请求的能力,将请求拦截到后,将响应数据替换成我们的Mock 数据。

配置繁琐,不变复用,成本也高 复用率底,成本高

Mock Server

利用Node起一个服务接受Http请求,在使用Mock.js生成假数据。在利用Webpackwebpack-dev-serverProxy代理,将接口代理到启的Mock服务上。

用Express来搭建服务,简单便捷,复用率高,成本低

搭建项目

新建一个Mock文件夹在项目根目录下因为得用到Node依赖,或者单独搭一个Mock的项目。这里我就放在项目根目录下了。

Mock/data/getUserInfo.js

把接口请求配置放在data下,存放接口返回数据

module.exports = {
  code: 0,
  message: "success",
  data: {
    name: "Alice",
    mobile: "182xxxx9999",
    age: 30
  }
};

Mock/api.js 存放接口API地址

let api = {
    getUserInfo: "/api/getUserInfo"
};
module.exports = api;

Mock/config.js 整合API地址与返回数据

const api = {
  getUserInfo: "/api/getUserInfo"
};
const getUserInfo = require("./data/getUserInfo.js");

const config = [
  {
    method: "get",
    url: api.getUserInfo,
    data: getUserInfo
  }
];
module.exports = config;

Mock/server.js Mock/server.js创建一个server.js

const express = require("express");

const bodyParser = require("body-parser");
const multipart = require("connect-multiparty");

const config = require("./config");
const app = express();
const multipartMiddleware = multipart();

const Mock = require("mockjs");
const mock = (data, params) => {
  if (Object.prototype.toString.call(data) === "[object Object]") {
    return Mock.mock(data);
  } else if (typeof data === "function") {
    return Mock.mock(data(params));
  } else {
    return "error: data shold be an object or a function.";
  }
};

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

config.forEach(({ method, url, data }) => {
  if (method === "get") {
    app.get(url, (req, res) => {
      res.json(mock(data, req.query));
    });
  } else if (method === "post") {
    app.post(url, multipartMiddleware, (req, res) => {
      res.json(mock(data, req.body));
    });
  } else if (method === "jsonp") {
    app.get(url, (req, res) => {
      const query = req.query;

      const mockData = JSON.stringify(mock(data, req.query));

      const callback =
        "typeof " +
        query.callback +
        ' === "function" && ' +
        query.callback +
        "(" +
        mockData +
        ")";

      res.send(callback);
    });
  }
});

let port = 8081;
process.argv.forEach((arg, index, arr) => {
  if (arg === "--port") {
    port = arr[index + 1] || 8081;
    return false;
  }
});

module.exports = app.listen(port, () => {
  console.log("Mock Server listening on http://localhost:" + port);
});

Mock.js

用来生成假数据的JS,这样你就不用手动去添加那些数据了

npm install -save-dev mockjs

官方文档 详细规则可以看文档,我们只需要用到生成假数据的功能,拦截 Ajax 请求的工作就交给Node了

Mock/data/getUserInfo.js

module.exports = {
  code: 0,
  message: "success",
  data: {
    name: "@cname",
    mobile: /^1[385]\d{9}$/,
    "age|18-50": 1,
    "orders|5-10": [
      {
        id: "@id",
        from: "@county(true)",
        to: "@county(true)"
      }
    ]
  }
};

你也可以直接在项目中使用

    const Mock = require("mockjs");
    let data = Mock.mock({
      code: 0,
      message: "success",
      data: {
        name: "@cname",
        mobile: /^1[385]\d{9}$/,
        "age|18-50": 1,
        "orders|5-10": [
          {
            id: "@id",
            from: "@county(true)",
            to: "@county(true)"
          }
        ]
      }
    });
    console.log(data)

具体的配置可以查看官网,还是挺简单的

bodyParser

node的中间件,用来解析请求体

npm install --save-dev bodyParser

请求的格式由头部信息context-type决定

application/json JSON格式

application/octet-stream Raw格式(二进制)

text/plain text格式(文本)

application/x-www-form-urlencoded urlencoded(URL编码)

属性 默认值默认值 作用 JSON raw(二进制) text(文本) urlencoded(URL编码)
inflate true 压缩Body
limit 100kb 控制请求体大小
revier JSON.parse的第二个参数
strict true true只接受数组或对象,false接受JSON.parse转换的值
type application/octet-stream 确定解析的媒体类型
verify 获取解析报错信息
defaultCharset utf-8 编码格式
extended 100 false使用queststring解析URL,true使用qs解析URL
parometerlimit 100 允许URL中参数最大字节数量
const express = require("express");

const bodyParser = require("body-parser");
const multipart = require("connect-multiparty");

const app = express();

配置方式一

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

配置方式二

let urlencodedParser = bodyParser.urlencoded({ extended: false })

app.post('/api',urlencodedParser,function(req,res){...})

配置方式三

app.use(bodyParser.json({ type:'text/plain' }));
app.use(bodyParser.raw({ type:'application/vn.custom-type' }));
app.use(bodyParser.text({ type:'text/html' }));

还可以使用body或co-body的npm替换bodyParser

connect-multiparty

node的中间件,用来保存上传文件

npm install --save-dev connect-multiparty

这个就比较简单了,用来保存上传文件。

但是它会在服务器上创建一个临时文件,且不会删除。可以使用multiparty替换。

不过connect-multiparty配置简单,开启Mock够用了。

好了,你开启这个mock,在利用webpack-dev-server的Proxy代理到这个端口就可实现本地的Mock 服务了

"node ./mock/server.js"

最后在推荐个插件concurrently

两个进程无法使用&同时启动的,就需要开两个cmd分别打开。 我们使用concurrently来同时打开两个进程

npm install -D concurrently

  "scripts": {
    "start": "webpack-dev-server",
    "mock": "node ./mock/server.js",
    "dev": "concurrently \"npm run start\" \"npm run mock\""
  }
  注意""的转义

参考极客时间的《透视前端工程化》,8错的Webpack教学,适合从头搭一遍。

最近在迭代公司的项目,现在大家开发要有模块化意识。不然接手老代码,真的难受,光看他这个业务逻辑我就看了两个小时。