故事背景
我们在项目完成之后,有时候会有一些小的调整,比如:文案的修改,fixbug,很小的功能调整。
为了完成这个功能调整我们一般来说需要三步:
- 账号登录系统
- 跳转相应的功能页面
- 查看返回的数据结构
产生的问题
寻找账号很费时间,找到了,还不一定有这个权限。不同的账号,可能数据结构有差异,更有的时候,开发环境突然清库,发现没有任何数据,因此还是很难得到我们想要的数据
原因分析
开发环境的不稳定(数据经常丢失),没有一个大而全的账号(通常情况下账号有些功能是互拆的)。
解决方案
我们想要的无非是后端返回的数据结构,因此我们只要应对每一个api接口给一份完整的数据结构就行了。 大致思路就是:在webpack就行api代理的时候实时的copy一份数据生成到当前的mock文件夹中,文件名当前是根据api的url生成,这样就保证了生成数据的唯一性,下次mock访问相同规则直接提取
const fs = require('fs-extra');
const path = require('path');
const zlib = require('zlib');
/**
* 判断文件存不存在,不存在就新建
*/
function getFilePath(url) {
const filename = url.split('/').filter(str => str).join('_');
return path.join(__dirname, '../mock/', filename + '.json');
}
async function generateMockDataByUrl(url, data) {
const filePath = getFilePath(url);
const exists = await fs.pathExists(filePath);
try {
if (!exists) {
await fs.outputJsonSync(filePath, JSON.parse(data), {
spaces: 2
});
}
} catch (error) {
console.log(data);
}
}
async function getDataFromMockByUrl(url) {
const filePath = getFilePath(url);
const exists = await fs.pathExists(filePath);
if (exists) {
return fs.readJson(filePath);
}
return JSON.stringify([]);
}
function unZip(data) {
return new Promise((resolve, reject) => {
zlib.gunzip(data, function (err, buffer) {
if (err) {
reject(err);
}
resolve(buffer.toString());
});
});
}
// 设置headers
function setHeaders(originHeaders, targetHeaders) {
Object.keys(originHeaders).forEach(key => {
targetHeaders.setHeader(key, originHeaders[key]);
});
}
module.exports = function(app) {
app.use(
['/idgate', '/login'],
createProxyMiddleware({
changeOrigin: true,
target: ''
selfHandleResponse: true,
async onProxyReq(proxyReq, req, res) {
proxyReq.setHeader('host', req.headers.host);
// 启用 mock 方案
if (isMock) {
setHeaders(
{
...req.headers,
'content-type': 'application/json;charset=UTF-8'
}, res);
const data = await getDataFromMockByUrl(req.url);
return res.send(data);
}
},
async onProxyRes(proxyRes, req, res) {
if (!isMock) {
setHeaders(proxyRes.headers, res);
}
let body = [];
proxyRes.on('data', function (chunk) {
body.push(chunk);
});
proxyRes.on('end', async function () {
body = Buffer.concat(body);
// 这里需要判断header content-encoding编码格式 进一步处理
if (proxyRes.headers['content-encoding'] === 'gzip') {
const data = await unZip(body);
await generateMockDataByUrl(req.url, data);
} else {
// 这个方案需要和后端联调 存在多种编码格式 gzip defate ....
await generateMockDataByUrl(req.url, body.toString());
}
res.end(body);
});
}
})
);
};
结论
所有数据完全真实,账号导致的差异,我们可以本地修改对应字段,基本能够解决寻找账号的尴尬。
最后
欢迎大家一起讨论更好的方案~。