whistle.vase
Version:
用于mock数据的whistle插件
329 lines (213 loc) • 12.4 kB
Markdown
# whistle.vase
> [请将 Whistle 升级到最新版本](https://wproxy.org/whistle/update.html)
vase 内置[default](#default)、[doT](#dot)、[dust](#dust)、[ejs](#ejs)、[handlebars](#handlebars)、[mock](#mock)、[mustache](#mustache)、[nunjucks](#nunjucks)、[vm](#vm)及用于解析自定义脚本的[script](#script)等渲染引擎,通过该[whistle](https://github.com/avwo/whistle#whistle)插件,可以通过模板结合相应的引擎mock开发过程中需要的json、html、图片等数据,也可以通过[script](#script)来自定义脚本更加灵活的获取模板及数据,控制输出等(如果只是静态数据不需要借助模板引擎批量生成,直接利用[whistle](https://github.com/avwo/whistle)的 `file` 或 `xfile` 即可实现)。
# 安装
### 安装whistle
请参考:[https://github.com/avwo/whistle#whistle](https://github.com/avwo/whistle#whistle)
### 安装插件whistle.vase
安装启动[whistle](https://github.com/avwo/whistle#whistle)后,直接通过npm来安装whistle插件:
$ w2 install whistle.vase
**Note: 安装过程中的一些警告可以先忽略,如果要用到https、websocket需要[启用HTTPS](https://wproxy.org/whistle/webui/https.html)**
安装成功后在[whistle](https://github.com/avwo/whistle#whistle)的Plugins里面可以看到 `vase` 这个插件,并处于选中状态。
# 用法
### 配置界面
按上图操作打开vase的配置界面,也可以直接访问: [http://local.whistlejs.com/whistle.vase/](http://local.whistlejs.com/whistle.vase/)

### mock数据及获取数据
按上图,创建一个名称为`test-dust`、引擎名称为`dust`的的模板,内容如下:

也支持通过本地文件加载模板 `pattern vase://tpl:AbsoluteLocalFilePath`,如:`www.test.com/path/to vase://mock:D:\test\demo.json` 或 `www.test.com/path/to vase://mock:/Users/av/test/demo.json`,方便把 mock 数据集成到项目文件里面,并通过 [w2 add](https://wproxy.org/whistle/cli.html) 自动配置项目的 mock 环境
在whistle配置:
vase://test-dust /sina/ www.ifeng.com http://www.aliexpress.com/category/

分别访问如下url:
1. [http://www.aliexpress.com/category/200003482/dresses.html?name=Aliexpress](http://www.aliexpress.com/category/200003482/dresses.html?name=Aliexpress)
2. [http://www.ifeng.com/?name=ifeng](http://www.ifeng.com/?name=ifeng)
3. [http://www.sina.com.cn/?name=sina](http://www.sina.com.cn/?name=sina)
即可分别看到:
1. Hello Aliexpress
2. Hello ifeng
3. Hello sina
### 几点说明
1. 引擎用到的渲染数据默认先从接口提交的body中获取,如果没有对应的字段才从url的参数获取,如果要自定义数据可以通过vase的内置[script](#script)引擎来实现,具体参考下面的:[script](#script)
2. vase返回的数据的`content-type`默认都是 `text/html`,如果要修改`content-type`可以使用以下两种方式:
- 在模板名称中加对应的后缀,如 `test-dust.txt`,vase会根据后缀生成对应的`content-type`
- 通过[script](#script)引擎修改响应头部,具体参考下面的:[script](#script)
3. 如果要更加灵活的获取数据源、控制输出,如:通过本地文件或线上url获取模板内容、渲染数据,控制速度,分段输出,设置响应头、响应状态码、响应内容编码等,可以使用下面的:[script](#script)
4. websocket 请求比较特殊,请用 [whistle.script](https://github.com/whistle-plugins/whistle.script) 模拟请求响应
# 模板引擎
### default
默认引擎,即直接输出设置的文本,不做任何加工。
### doT
模板渲染引擎,使用方法参考Github:[https://github.com/olado/doT](https://github.com/olado/doT)
### ejs
模板渲染引擎,使用方法参考Github:[https://github.com/mde/ejs](https://github.com/mde/ejs)
### handlebars
模板渲染引擎,使用方法参考Github:[https://github.com/wycats/handlebars.js](https://github.com/wycats/handlebars.js)
### mock
模板渲染引擎,使用方法参考Github:[https://github.com/nuysoft/Mock](https://github.com/nuysoft/Mock)
### mustache
模板渲染引擎,使用方法参考Github:[https://github.com/janl/mustache.js](https://github.com/janl/mustache.js)
### nunjucks
模板渲染引擎,使用方法参考Github:[https://github.com/mozilla/nunjucks](https://github.com/mozilla/nunjucks)
### vm
模板渲染引擎,使用方法参考Github:[http://git.shepherdwind.com/velocity.js](http://git.shepherdwind.com/velocity.js)
### script
[script](#script-api)是vase系统自定义的脚本解析器,保留了JavaScript的一些基本特性,如:基本类型、条件语句、循环体、方法等,剔除了JavaScript内置的一些api,如:process、setTimeout、setInterval等,并内置了一些方法用于读取及处理vase的模板、本地文件、线上文件等,且所有调用都是同步的方式,具体用法参加下面的文档。
# script API
1. [out](#outdata-delay-speed): 所有的数据都要通过该方法才能输出到响应中,也可以用 `write`
2. [status](): 设置输出的http状态码,默认为`200`,也可以写成 `statusCode(code)`
3. [header](#headername-value): 设置响应头
4. [headers](#statuscode): 批量设置响应头
5. [file](#filepath): 读取本地文件
6. [get](#geturloptions): 通过get方式获取线上文件,支持https及http协议
7. [post](#posturloptions): 通过post方式获取线上文件,支持https及http协议
8. [request](#requestoptions): 通过自定义方式获取线上文件,支持https及http协议
9. [json](#jsondata): 将线上或本地文件、或字符串解析成json对象
10. [merge](#mergejson--jsonn): 合并json对象
11. [random](#randomarg1--argn): 随机输出
12. [join](#joinarr-seperator): 合并字符串
13. [req](#req对象): 用户请求对象
14. [render](#rendertpl-locals-enginetype): 渲染模板
详细用法请参考如下:
### out(data, delay, speed)
所有的数据都要通过该方法才能输出到响应中,也可以用 `write(data, delay, speed)`
data: 表示要输出的数据或数据源
1. 输出json对象
out({
test: 'hehe'
});
2. 输出文本数据
out('Hello world');
3. 输出vase加载的资源,详见下面个API文档
delay: 设置延迟多少毫秒输出
speed: 设置输出的速度kbs
### status(code)
设置输出的http状态码,默认为`200`,也可以写成 `statusCode(code)`
out(status(500));
### header(name, value)
设置响应头
out(header('content-type', 'text/plain; charset=utf8'));
out(header('x-test', 'abc'));
### headers(obj)
设置响应头
out(headers({
'content-type': 'text/plain; charset=utf8',
'x-test': 'abc'
}));
### file(path)
读取本地文件
out(file('/User/xxx/test.html'));
//windows
//out(file('D:/xxx/test.html'));
### get(url|options)
通过get方式获取线上文件,支持https及http协议
out(get('https://www.taobao.com/'));
自定义请求头部
out(get({
url: 'https://www.taobao.com/',
headers: {
'User-Agent': 'vase/x.y.z'
}
}));
### post(url|options)
通过post方式获取线上文件,支持https及http协议
//返回空
out(post('http://www.qq.com/'));
自定义请求头
out(get({
url: 'https://www.taobao.com/',
headers: {
'User-Agent': 'vase/x.y.z'
}
}));
自定义表单数据
out(get({
url: 'https://www.taobao.com/',
headers: {
'User-Agent': 'vase/x.y.z'
},
query: {key:'value'}
}));
关于post的更多功能请参考:[https://github.com/axios/axios#request-config](https://github.com/axios/axios#request-config)
### request(options)
通过自定义方式获取线上文件,支持https及http协议
//返回空
out(request({
url: 'http://www.qq.com/',
method: 'post',
headers: {
'User-Agent': 'vase/x.y.z'
},
params: {key:'value'}
}));
//返回qq官网首页
out(request({
url: 'http://www.qq.com/',
method: 'get',
headers: {
'User-Agent': 'vase/x.y.z'
}
}));
关于request的更多功能请参考:[https://github.com/axios/axios#request-config](https://github.com/axios/axios#request-config)
### json(data)
1. 将文本转换为json对象
out(json('{"test": 123}'));
2. 从线上获取(支持jsonp请求)
out(get('https://raw.githubusercontent.com/avwo/whistle/master/package.json'));
3. 从本地文件加载
out(file('/User/xxx/test.txt'));
### merge(json, ..., jsonN)
合并json
out(merge(json('{"test": 123}'), json(get('https://raw.githubusercontent.com/avwo/whistle/master/package.json')));
深度合并(>= v1.3.1):
``` txt
out(merge(true, json('{"test": 123}'), json(get('https://raw.githubusercontent.com/avwo/whistle/master/package.json')));
```
### random(arg1, ..., argN)
数据获取参数列表中的一个
out(random(json('{"test": 123}'), json(get('https://raw.githubusercontent.com/avwo/whistle/master/package.json'), 'test', file('/User/xxx/test.html')));
### join(arr, seperator)
与数组的`join`方法一样,拼接数组, `seperator`默认为`''`
out(join([json('{"test": 123}'), json(get('https://raw.githubusercontent.com/avwo/whistle/master/package.json')), 'test', file('/User/xxx/test.html')]));
如果使用默认的separator(`''`),也可以写成这样 `join(arg1, ..., argN)`
out(join(json('{"test": 123}'), json(get('https://raw.githubusercontent.com/avwo/whistle/master/package.json')), 'test', file('/User/xxx/test.html')));
### req对象
请求对象,包含:headers、method、body、query、url、locals(=merge(req.query, req.body))
out(req);
### render(tpl[, locals[, engineType]])
渲染模板
tpl:vase的模板名称或模板字符串
locals:可选,用于渲染的json对象
engineType:可选,渲染引擎名称,包含 [default](#default)、[doT](#dot)、[dust](#dust)、[doT](#dot)、[ejs](#ejs)、[mock](#mock)、[mustache](#mustache)、[nunjucks](#nunjucks)、[vm](#vm)
1. 如果tpl是字符串或数字,且vase里面有对应名称的模板,则会自动加载vase的模板内容
out(render('test-dust'), req.locals);
//修改locals
out(render('test-dust', json(get('https://raw.githubusercontent.com/avwo/whistle/master/package.json'))));
//切换engine
out(render('test-dust', json(get('https://raw.githubusercontent.com/avwo/whistle/master/package.json')), 'handlebars'));
2. 如果tpl是字符串或数字,且没有对应的vase模板,则这些字符串作为模板内容
out(render('Hello {{name}}', json(get('https://raw.githubusercontent.com/avwo/whistle/master/package.json')), 'handlebars'));
3. 渲染线上模板
out(render(get('http://www.qq.com/'), json(get('https://raw.githubusercontent.com/avwo/whistle/master/package.json')), 'handlebars'));
4. 渲染本地文件模板
out(render(file('/User/xxx/test.txt'), json(get('https://raw.githubusercontent.com/avwo/whistle/master/package.json')), 'handlebars'));
# script使用例子
### 模拟bigpipe
out(join(render('test-doT', json(get('https://raw.githubusercontent.com/whistle-plugins/whistle.vase/master/package.json'))), '<br>'));
out(join(render('test-default'), '<br>'), 1000);
out(join(render('test-doT', {name: 'doT'}), '<br>'), 1000);
out(join(render('test-dust', {name: 'dust'}), '<br>'), 1000);
out(join(render('test-ejs', {name: 'ejs'}), '<br>'), 1000);
out(join(render('test-handlebars', {name: 'handlebars'}), '<br>'), 1000);
out(join(render('test-mock', {name: 'mock'}), '<br>'), 1000);
out(join(render('test-mustache', {name: 'mustache'}), '<br>'), 1000);
out(join(render('test-nunjucks', {name: 'nunjucks'}), '<br>'), 1000);
out(render('test-vm', {name: 'vm'}));
`text-xxx`表示在vase上配置的模板
#### 随机输出
out(random(render('test-default'), render('test-doT', {name: 'doT'}), render('test-dust', {name: 'dust'})));
### 结合上述两种情况
for (var i = 0; i < 10; i++) {
out(join(random(render('test-default'), render('test-doT', {name: 'doT'}), render('test-dust', {name: 'dust'})), '<br>'), 1000);
}