内容简介:上一篇文章项目中需要对两个开发地址进行代理,部分数据也需要使用mock数据,所以可以参照虽说是参照
上一篇文章
json-server的实践与自定义配置化
提到过, json-server
在我看来不太适用;之前有赞开源的
zan-proxy
我也尝试用过,其痛点在于mock数据保存在第三方,这个特性使得公司项目不适合使用 zan-proxy
,所以尝试自己搭建一个mock服务——
ma-mock
。
背景
项目中需要对两个开发地址进行代理,部分数据也需要使用mock数据,所以可以参照 zan-proxy
做代理和mock的切换按钮,鉴于之前是使用 koa
编写后端服务的,所以这次使用 koa
编写 可用于mock和proxy的可视化服务
。
构思
虽说是参照 zan-proxy
,但是我还是保留着自己的想法;首先,与 zan-proxy
不同, zan-proxy
使用浏览器插件进行地址代理,其主要目的是用于调试线上页面,但我们只在dev环境使用,使用webpack的proxyTable将后端接口都代理到mock服务,由mock服务统一分发代理还是返回mock数据即可;其次,数据保存在本地,构建一个本地文件增删查改的操作,mock服务只在dev开发中使用,io的损耗其实没有太大的区别;
后端
主要有三个功能, 分发mock和proxy
、 提供可视化界面的后端接口
、 部署前端资源
,因为主要是给前端人员使用,所以维护一份全局变量(lib/Global.js)替代 redis
。
三个功能的执行顺序为 分发mock和proxy
-> 返回单页面资源
-> 可视化界面的后端接口
分发功能可以利用koa中间件特性:
'use strict'; const { Logger, fsHandler, Global } = require('../lib/index'); const axios = require('axios'); const pathToRegexp = require('path-to-regexp'); /** * * @param {object} options 配置项 * {object} options.prefix mock数据的url前缀 * @return {function} * */ module.exports = options => { // 进行中间件参数的配置,最终返回一个中间件函数 let prefix = options.prefix; // 兼容prefix格式的写法 "/__DEV__/xxx" 或者 "/__DEV__/xxx/" if (prefix.lastIndexOf('/') + 1 !== prefix.length) { prefix = prefix + '/'; } return async function(ctx, next) { let curPath = ctx.path; // 不符合prefix的接口地址直接跳过 if (curPath.indexOf(prefix) !== 0) return await next(); let pathArr = curPath.split(prefix); // 如果prefix之后不再有path则请求不合法 // 例如:prefix为 __DEV__/pay/但请求路径为http://*/__DEV__/pay/ if (pathArr.length < 2) { ctx.body = '请求路径不合法'; } // 判断是否使用MOCK数据 const find = Global.mockList.find(it => { const re = pathToRegexp(it.url); return re.test(`/${pathArr[1]}`); }); // 规则是mock优先级大于proxy if (find && find.enable) { ctx.body = handlerMock(find.url.slice(1)); } else if (Global.enableProxy) { ctx.body = await handlerProxySync(`/${pathArr[1]}`, ctx); } else { ctx.body = '未开启proxy'; } // 此处没有next(),直接返回数据 }; // 用mock数据 function handlerMock(filePath) { let result = ''; try { result = fsHandler.getMockFile(filePath); } catch (e) { result = e; } Logger.debug(result); return { ...result, type: 'MOCK' }; } // 后端代理 async function handlerProxySync(api, ctx) { const options = { ...ctx.request, url: `${Global.currentProxyUrl}/${api}`, params: ctx.query, }; try { const res = await axios(options); return { ...res, type: 'PROXY' }; } catch (e) { return { message: e.message, type: 'PROXY', }; } } }; 复制代码
中间件使用
// 配置mock app.use( mockProxy({ prefix: '__DEV__', }) ); 复制代码
可视化界面的后端接口
常规后端restful接口,此处略过不讲。
前端静态资源部署
因为是开发环境使用,所以不必部署到nginx上,自己编写了基于 koa-static
的
koa-spa-static
。
使用方法,配置采用vue打包出来的目录,react可能需要自行按情况修改:
const spaStatic = required('koa-spa-static'); // 挂在静态资源 app.use( spaStatic({ matchReg: /^(?!\/api)/, // 不以"/api"开头的接口地址会返回静态资源 root: path.join(__dirname, './dist'), // 静态资源目录 staticReg: /^\/static/, // 前端static资源返回文件,其他返回index.html }) ); 复制代码
前端
使用element-ui2的组件构造,属于简单的组装,基于自己编写的 vue cli模板 ,使用命令
vue init masongzhi/vue-template-webpack
其他
ma-mock服务的安装和使用
安装
npm install -D ma-mock
在根目录编写 .mamockrc.js
配置文件
const path = require('path'); // 默认配置 module.exports = { prefix: '/__DEV__', rootPath: path.resolve(__dirname, './data/mock'), proxyPath: path.resolve(__dirname, './data/proxy'), proxyFilename: 'config.json', }; 复制代码
配置webpack proxyTable
// ...省略 module.exports = { // ...省略 dev: { // ...省略 proxyTable: { // 填写 .mamockrc.js的prefix,默认为'/__DEV__' '/__DEV__': { target: 'http://localhost:3001', // 接口的域名 // secure: false, // 如果是https接口,需要配置这个参数 changeOrigin: true, // 如果接口跨域,需要进行这个参数配置 } }, }, } 复制代码
package.json添加script命令
mamock [--port 3001]
.mamockrc.js的读取
我们在项目跟目录编写了 .mamockrc.js
文件,那是怎么在mock服务中读取到这个文件的信息呢,或者说怎样才能将npm包的配置参数写在根目录的文件内。
我们可以使用 rc-config-loader
,其他类似包也行,像 prettier
就使用 editorconfig
和自己编写的 editorconfig-to-prettier
。
const rcfile = require("rc-config-loader"); // 会向上遍历.mamockrc or .mamockrc.json or .mamockrc.js or.<product>rc.yml, .mamockrc.yaml // 我们需要用到基于跟目录的data文件,所以需要用到__dirname,所以使用js文件 const data = rcfile('mamock'); 复制代码
bin命令的使用
我们在package.json的scripts编写了 mamock --port 3001
命令,是怎么实现的呢。
在package.json添加
"bin": { "ma-mock": "./bin/mock-proxy.js", "mamock": "./bin/mock-proxy.js" } 复制代码
在bin目录添加 mock-proxy.js
#!/usr/bin/env node 'use strict'; // 定义用到的参数 const keys = ['port', 'prefix', 'rootPath', 'proxyPath', 'proxyFilename']; const argvs = process.argv.slice(2); function getArgv(key) { const index = argvs.findIndex(it => it === `--${key}`); return index >= 0 && argvs[index + 1]; } keys.forEach(key => { const value = getArgv(key); if (value) process.env[key] = value; }); // 执行koa的index.js require('../server/index.js'); 复制代码
自动打开浏览器
启动 ma-mock
服务时自动打开浏览器
// index.js const opn = require('opn'); app.listen(PORT); opn(`http://localhost:${PORT}`, {app: 'google chrome'}); 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
How Great Decisions Get Made
Maruska, Don / 2006-2 / $ 20.28
All too often, solving tough work issues can become a tug of war as clashing departments, priorities, personality styles, and other concerns threaten to destroy any possibility of a successful conclus......一起来看看 《How Great Decisions Get Made》 这本书的介绍吧!