使用 mock 开发的优点
- 不依赖后端进度。只要根据需求与后端列出接口,约定好接口内容就能开发。
- 职责分明。随着前端的发展,业务逻辑部分也开始放在客户端。这就不可避免的可能会与后端同学产生冲突,在约定接口内容后有利于提前化解这样的问题,避免撕 X。提高工作效率。
- 独立运行。即使没有后台服务也能打开项目。避免以后想看项目,启动都是报错的问题。
使用 Express 来实现 Mock Server
// 引入node的path
var path = require("path")
// 引入node的文件模块
var fs = require("fs")
// 引入mockJs
var mock = require("mockjs")
// 构建express应用
var app = require("express")()
/* process.argv返回一个数组,其中包含当启动 Node.js 进程时传入的命令行参数。
第一个元素是 node.exe 执行文件的路径
第二个元素将是正在执行的 JavaScript 文件的路径(这个是配置在npm script 中的mockServer.js的路径)
第三个是npm script 里面配置的mockServer的端口号
*/
var port = process.argv[2] || 8000
// 监听启动端口
app.listen(port, function() {
console.info("Mock server is listening at " + port)
})
// webpackServer是否开启代理
const prefix = process.env.NODE_ENV != "production" ? "/api" : ""
// 获取同一文件夹下的api.json
var apiPath = path.join(__dirname, "./api.json")
// 读取api.json里面的接口内容
var api = {}
function getApis() {
fs.readFile(apiPath, "utf-8", function(_, content) {
api = JSON.parse(content)
})
}
// 监听api.json变化
fs.watchFile(apiPath, function(curr) {
getApis()
})
getApis()
// 支持callback
app.set("jsonp callback name", "callback")
// 使用中间件对获取的api.json内容进行处理返回
app.use(function(req, res) {
var data
var delay = 0
for (var group in api) {
if (
api[group].find(function(reqData) {
if (reqData.regexp) {
if (!new RegExp(reqData.url).test(req.originalUrl)) {
return false
}
} else if (req.originalUrl !== prefix + reqData.url) {
return false
}
var apiRes = reqData.res
data = reqData.mock !== false ? mock.mock(apiRes) : apiRes
delay = reqData.delay || 0
return true
}) !== undefined
) {
break
}
}
// CORS 跨域
res.set("Access-Control-Allow-Origin", "*")
res.set("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS")
res.set(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept, Authorization"
)
// 返回处理过的数据
data !== undefined
? setTimeout(() => res.jsonp(data), delay)
: res.sendStatus(404)
})
在 api.json 写入 mock:
{
"登录模块": [
{
"url": "/portal/login",
"desc": "用户登入",
"mock": true,
"res": {
"code": 0,
"msg": "success",
"data": {
"uname": "@cword(5,8)",
"uid": 9
}
}
},
{
"url": "/portal/updatePwd",
"desc": "修改密码",
"mock": true,
"res": {
"code": 0,
"msg": "success",
"data": {
"msg": "修改成功"
}
}
},
{
"url": "/portal/captchaImage",
"desc": "验证码",
"mock": true,
"res": {
"code": 0,
"msg": "success",
"data": {}
}
},
{
"url": "/portal/logout",
"desc": "用户登出",
"mock": true,
"res": {
"code": 0,
"msg": "success",
"data": {
"msg": "登出成功"
}
}
}
]
}
最后在 npm script 上加上 mock server 启动命令:
{
"scripts": {
"start": "run-p start_dev mock",
// ./src是项目路径
"start_dev": "webpack-dev-server --inline --hot --host 0.0.0.0 --progress --port 3000 --colors --content-base ./src",
// ./mock-server/server.js是mockServer路径 2618是端口号
"mock": "node ./mock-server/server.js 2618"
}
}
运行 npm run start