mockjs在今天已经是一个很常用的功能了,主要作用是提升前后端分离开发效率,前端可以不依赖于后端,只需要按照api文档即可自己完成开发并调通数据。最近自己实现了下一个比较简易的版本
1.配置mockjs直接引用
// 在main入口引入配置好的mock文件就可以直接调用了
if (process.env.NODE_ENV === 'development') {
// 区分环境,这样即使打包时忘了把下面代码注释掉也不会影响生产环境
// require('../../mock') // 不需要开启mock
}
/mock/index.js的配置
// 首先引入Mock
import Mock from 'mockjs'
// 设置拦截ajax请求的相应时间
Mock.setup({
timeout: '200-600'
})
let configArray = []
// 使用webpack的require.context()遍历所有mock文件
const files = require.context('.', true, /\.js$/)
files.keys().forEach(key => {
if (key === './index.js') return
configArray = configArray.concat(files(key).default)
})
// 注册所有的mock服务
configArray.forEach(item => {
for (let [path, target] of Object.entries(item)) {
let protocol = path.split('|')
Mock.mock(protocol[1], protocol[0], target)
// Mock.mock(new RegExp('^' + protocol[1]), protocol[0], target)
}
})
/mock/requestA.js
import Mock from 'mockjs'
//requesA.js
const demoList = req => {
// console.log(req)
return Mock.mock({
status: 200,
message: 'success',
data: {
total: 100,
'rows|10': [
{
id: '@guid',
name: '@cname',
'age|20-30': 23,
'job|1': ['前端工程师', '后端工程师', 'UI工程师', '需求工程师']
}
]
}
})
}
export default {
'get|/mock/parameter/query': demoList
}
很明显这样做虽然可以使用Mock,但是ajax请求会被mock拦截导致在network看不到信息,而且切换到真实url需要改地址
2.启一个服务来支持mock
在脚手架中配置/scripts.js
function loadMockServer() {
if (isTrue(config.mock)) {
spawn('babel-node', [require.resolve('../util/mock.js')], {
stdio: 'inherit',
env: Object.assign({}, process.env, env)
})
}
}
switch (script) {
case 'start':
loadMockServer()
.........省略
mock服务/util/mock.js
// import express from "express"
// import Mock from "mockjs"
const http = require('http')
const fs = require('fs');
const path = require('path');
const express = require('express'); //引入express
const Mock = require('mockjs'); //引入mock
const Random = Mock.Random;
let server = register()
fs.watch(path.resolve(process.cwd(), 'mock'), function (event, filename) {
console.log('event is: ' + event);
if (filename) {
console.log('filename provided: ' + filename);
server.close()
server = register()
} else {
console.log('filename not provided');
}
});
function register(){
delete require.cache[path.resolve(process.cwd(), 'mock/index.js')]
const mockCase = require(path.resolve(process.cwd(), 'mock/index.js'))
let app = express();
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
});
for (const key in mockCase) {
const [type, url] = key.split('|')
app.use(url, function (req, res) {
if(req.method !== type){
res.json({
success: false,
status: {
RetCode: 99999,
msg: "请求类型错误"
},
})
return;
}
setTimeout(() => {
res.json(Mock.mock(mockCase[key]))
}, 500)
})
}
return http.createServer(app).listen(8090);
}
自定义mock数据编写/mock/index.js
const Mock = require('mockjs')
const Random = Mock.Random
const mockCase = {
'GET|/mock/test': {
status: {
RetCode: 0,
msg: 'success'
},
success: true,
data: {
total: 10,
'rows|10': [
{
id: '@guid',
name: '@cname',
'age|20-30': 24,
'job|1': ['前端工程师', '后端工程师', 'UI工程师', '需求工程师']
}
]
}
},
'GET|/mock/yunfan': {
status: {
RetCode: 0,
msg: 'success'
},
success: true,
data: {
total: 10,
name: 'yunfan',
'list|10': [
{
'name|+1': ['John Brown', 'Jim Green', 'Joe Black', 'Jon Snow'],
'age|18-70': 70,
address: Random.region(),
date: Random.date()
}
]
}
}
}
module.exports = mockCase
这里可以在目录在配置不同路由需要的数据 引入到Index中统一抛出
封装下request方法
import { **** } from '***-fetch'
const mock = ******.mock; // 从配置中读,这里演示下
const Index = (type, url, params) => {
return ****(type, `${mock ? '/mock' : ''}${url}`)(params)
}
export default Index;
配置下proxy
proxy: {
'/mock': {
target: 'http://localhost:8090', // 接口域名
secure: false,
changeOrigin: true,
pathRewrite: {
'^/mock': ''
}
}
}
好了,这样就实现了一个简易的Mock服务,现在可以在network看到我们的mock请求了,并且支持了热更新