利用webpack-dev-server的before方法,拦截请求,将请求的路径映射到本地mock目录中的js文件中的数据。
mock中间件实现的功能
- 请求的路径和mock目录的路径相对应,找不到则返回
404 - 可直接返回响应数据
- 返回一个方法,参数为请求的常用参数,返回为响应数据,可实现处理请求返回不同响应结果。
项目目录结构
├─package.json
├─src
| ├─index.css
| ├─index.html
| ├─index.js
├─dev
| ├─mock
| | ├─fun.js
| | └test.js
├─build
| ├─fs-async.js
| ├─mock.js
| └─webpack.config.js
运行命令
webpack-dev-server --config build/webpack.config.js- 或者在
package.json的script中设置然后{ "scripts": { "dev": "webpack-dev-server --config build/webpack.config.js" } }npm run dev
webpack-dev-server配置
const mock = require('./mock.js');
module.exports = {
mode: 'development',
// 开发服务器配置
devServer: {
// 指向打包目录
contentBase: path.resolve(__dirname, '../dist'),
port: 8080, // 服务端口号
progress: true, // 打包进度
open: true, // 是否打开浏览器
compress: false, //是否压缩
before: (app) => {
mock(app);
}
},
// 其他配置。。。
}
实现获取mock数据的express中间件
mock.js
const path = require('path');
const fs = require('fs');
/**
* 读取本地mock数据
* @param {*} req
*/
function readMockData(req) {
const {url, pathname, param, method} = req;
return new Promise((resolve, reject) => {
const filepath = path.resolve(__dirname, '../dev/mock' + pathname + '.js');
const fileExist = fs.existsSync(filepath);
if (!fileExist) {
const msg = `'${url}': mock data is not exist!`;
reject({
statusCode: 404,
body: null,
message: msg
});
} else {
try {
delete require.cache[require.resolve(filepath)];
const response = require(filepath);
if (typeof response === 'function') {
const responseFun = response(req);
resolve(responseFun);
return;
}
resolve(response);
} catch (err) {
console.log('readMockError:', err);
const msg = `'${url}': parse mock file error!`;
reject({
statusCode: 500,
body: null,
message: msg
});
}
}
});
}
/**
* express中间件,实现ajax mock数据功能
* @param {*} app
*/
module.exports = function mock(app) {
app.all('*', function (req, res, next) {
const method = req.method.toLocaleUpperCase();
const param = method === 'GET' ? req.query : req.body;
// 请求日志打印
console.log(req.method, req.url, param, Date.now());
// 只处理ajax请求
if (req.headers['x-requested-with'] === 'XMLHttpRequest') {
readMockData({
url: req.url,
pathname: req.path,
param,
method
}).then(response => {
res.status(response.statusCode || 200);
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(response.body));
}).catch(err => {
res.status(err.statusCode || 404);
res.end();
});
} else {
next();
}
});
}
mock文件数据内容
test.js
module.exports = {
statusCode: 200,
body: {
code: 0,
message: 'ok',
data: {
text: 'aabbcc'
}
}
};
fun.js
// 输出一个函数,可以根据请求的参数做对应的响应
module.exports = function (req) {
const param = req.param;
const method = req.method;
return {
statusCode: 200,
body: {
code: 0,
message: 'ok',
data: {
text: 'abcd',
param,
method
}
}
}
};