servermock 2.x.x
一开始只准备做一个server
和mock
数据的小工具,后来发现可以做的事还很多, 分享给大家
Install
sudo npm install servermock -g
//也可以当做node_module来引用到自己的工具中
npm install servermock --save
Usage
//启动命令(start)
servermock start
//安装删除插件
servermock plugin [intall | delete] | [-i | -d] [git repository]
//如:
servermock plugin intall https://github.com/shalles/synctest.git
//或
servermock plugin -i https://github.com/shalles/synctest.git
//或作为node模块使用
require('servermock')(config)
Config
启动目录下的配置文件 sm.config
{
"port": 8080, // 启动端口 默认80 unix系需要sudo
"hostname": "0.0.0.0", // 当为0.0.0.0时自动获取当前IPv4
"protocol": "http", //https
//"key": "~/cert/cert.key",
//"cert": "~cert/cert.crt",
"main": "./index.html", //default null, not open
// 需要使用websocket才配置,使用插件对其有依赖时会覆盖插件的配置
// "websocket": {
// "open": true,
// "maxsize": 10240,
// "encoding": "utf8",
// // callback: "console.log('outside: ', data); return 'get data ' + data;",
// // callback: function(data){
// // console.log('outside: ', data);
// // return 'get data ' + data;
// // },
// "originReg": "", //new RegExp 服务接受原正则匹配
// "sameOrigin": true, // 使用同源发送 default: true
// "broadcast": true, // 是否广播
// "mTm": false, //是否广播到自己
// "debug": false //log
// },
//
// 插件
"plugins":[{
"name": "mock",
"open": true,
"param": {
"datapath": "mock/",
"mockrc": ".mockrc", //相对mock datapath 可用绝对路径
"ignore": ["html", "jpg", "png", "gif"],
"regexurl": { //前面是regex new RegExp()
"com/api/mockdata.do": "mockdata.mjson",
"/static/webapp/src/": "filemock.js",
"/api/1placesuggestion" : "placesuggestion.js", //走js 遵循cmd
"/api/1placesuggestion" : "placesuggestion.json", //
"/api/placesuggestion" : "placesuggestion.mjson" //
}
}
},{
"name": "pagemock",
"open": true,
"param": {
"basepath": "mock/page", //"", //default: 同级目录
"mockrc": "../.mockrc", //基于basepath 可与mock同用 可用绝对路径
"acceptExts": ["php", "html", "vm"] //监听的页面扩展
}
},{// 需要单独安装 servermock plugin -i https://github.com/shalles/synctest.git
"name": "synctest",
"open": true,
"param": {
//vpn: "192.168.1.6",
"exts": ["html", "php", "vm"]
}
}]
}
sm.config
支持单行注释”//”, 暂不支持多行注释”/**/”;- 插件按需open;
protocol
:启动server服务的协议支持http/https
, 当为https是需要传入key和cert两个证书文件;- main提供的话会在start的时候
启动浏览器打开服务
,不提供则不打开;
更多配置使用请看对应插件 mock readme pagemock readme synctest readme
Plugin
插件安装/删除
//安装删除插件
servermock plugin [intall | delete] | [-i | -d] [git repository]
//如:
servermock plugin intall https://github.com/shalles/synctest.git
//或
servermock plugin -i https://github.com/shalles/synctest.git
插件列表
- mock (默认)
- pagemock (默认)
- synctest(需安装)
- …
插件编写
- 主要实现两个方法
init
和excute
; - init的时候可以拿到用户配置sm.config中serverConfig的一些配置和servermock utils.js提供的一些使用方法具体可以看源码,虽然写的很差但会慢慢优化。 主要提倡用utils.log;
- 目前提供了两个插件口
content
和router
并在excute的时候提供不同的参数和返回值; - 在
package.json
中配置需要servermock提供的支持;
如下以synctest为例
synctest的主要实现原理
- 监听页面的事件->编辑事件信息;
- 用servermock提供的websocket功能将编辑的事件信息广播到链接的其他设备的打开的页面监听client端;
- 在接收到事件信息后解析并重构事件;
- 触发该事件;
- 循环
a). 要在页面监听事件就需要向servermock启动的服务的页面文件中插入脚本,在servemock中属于content类插件即如下package.json中"type"
为"content"
;
b). 需要用到servermock的websocket功能则需要配置websocket的信息这是正对servermock配置的,且高于默认配置,低于用户配置;
c). 注意:servermock以文件的目录名位插件名,主目录下必须包含主文件index.js
和package.json
, package.json与node同用,插件使用node module加载 因此写起来和node语法无异
package.json
"servermock": {
"type": "content",
"websocket": {
"open": true,
"maxsize": 10240,
"encoding": "utf8",
"originReg": "",
"sameOrigin": true,
"broadcast": true,
"mTm": false
}
},
index.js
var utils,
origin,
protocol,
acceptExtname,
plugin = {},
path = require('path');
plugin.excute = function (params){
if(utils.inArray(params.ext, acceptExtname)){
console.log('[synctest loading]');
// do something
return params.cnt;
}
}
plugin.init = function(config){
var serverConfig = config.__serverConfig; // sm.config中的部分配置信息
utils = config.__utils; //utils.js
acceptExtname = config.exts || ['html', 'htm'];
origin = (config.vpn || serverConfig.hostname) + ":" + serverConfig.port;
protocol = serverConfig.protocol
}
module.exports = plugin;
content 与 router下 config
两个类型的插件在init提供相同的config参数,即__utils
, __serverConfig
;
content下的params
//当前请求
plugins.excute('router', {
res: res, //response mock插件拦截匹配的req,然后res返回mock数据
req: req, //request
pathname: pathname, //请求的文件路径
extname: extname //请求的文件扩展
});
router下的params
// 当前请求
plugins.excute('content', {
cnt: fileContent, // 请求匹配文件内容
stat: fdStat, // 请求匹配文件的stat信息
ext: extname, // 请求匹配文件的扩展
filepath: pathname // 请求匹配文件的物理路径
})
目录结构