部署自己的MOCK
本文適合團(tuán)隊(duì)內(nèi)部沒(méi)有MOCK服務(wù),對(duì)mock有實(shí)際需要的小伙伴。
歡迎關(guān)注前端早茶,與廣東靚仔攜手共同進(jìn)階
作者:廣東靚仔
一、前言
本文基于開(kāi)源項(xiàng)目:
???我們?cè)谶M(jìn)行新項(xiàng)目開(kāi)發(fā)、或者項(xiàng)目迭代開(kāi)發(fā),有些時(shí)候我們前端先一步開(kāi)發(fā)完頁(yè)面,就需要等待后端伙伴開(kāi)發(fā)完成才可以聯(lián)調(diào)。如果有個(gè)Mock服務(wù)我們就可以先一步驗(yàn)證我們頁(yè)面的功能,提早發(fā)現(xiàn)并完成調(diào)整優(yōu)化。? ? 使用Mock的好處有很多,這里就不啰嗦了。? ? 新項(xiàng)目一般我們直接調(diào)用Mock的api url即可,對(duì)于一些迭代開(kāi)發(fā)的項(xiàng)目,我們既可以調(diào)用之前聯(lián)調(diào)好的自己服務(wù)api,同時(shí)也可以調(diào)用我們的Mock,兩者同時(shí)訪問(wèn)并不沖突的。有很多種處理方式,例如我們通過(guò)url上進(jìn)行一些特定的處理即可。https://github.com/easy-mock/easy-mock
? ??廣東靚仔在18年的時(shí)候分享過(guò)這方面的內(nèi)容,這里給小伙伴們重溫下。
業(yè)界有不少關(guān)于MOCK這方面的應(yīng)用,列舉幾個(gè):
- Mock
- RAP
- NEI
- EASY MOCK
- api blueprint
? ? 嚴(yán)謹(jǐn)?shù)募夹g(shù)團(tuán)隊(duì)一般會(huì)選擇本地部署自己的Mock服務(wù)
? ? 這里廣東靚仔主要講EASY MOCK本地部署、以及它的語(yǔ)法
二、easy-mock擁有的特性
支持API代理
便捷的快捷方式
支持協(xié)同編輯
支持團(tuán)隊(duì)項(xiàng)目
支持RESTful
支持Swagger?|?OpenAPI規(guī)范(1.2&2.0&3.0)
基于Swagger快速創(chuàng)建項(xiàng)目
支持顯示參數(shù)和返回值
支持顯示類(lèi)模型
響應(yīng)數(shù)據(jù)更加靈活和可擴(kuò)展
支持自定義響應(yīng)配置(例如:狀態(tài)/標(biāo)題/ cookie)
使用Mock.js模式
支持restc預(yù)覽API
這些特性都是官方列舉出來(lái)的,大家有興趣可以去看官方文檔。
三、easy-mock本地部署
? ? 要私有部署easy-mock,我們需要安裝?Node.js?(?v8.x,不支持v10.x)和?MongoDB(> = v3.4)以及?REdis(> = v4.0)。? ? 具體安裝方式大家可以網(wǎng)上找對(duì)應(yīng)的版本進(jìn)行安裝,這里就不展開(kāi)了。安裝完以上三個(gè)東東,我們安裝最主要的easy-mock,操作如下:$?git?clone?https://github.com/easy-mock/easy-mock.git
$?cd?easy-mock?&&?npm?install? ? 接著我們配置一下,查找config / default.json或創(chuàng)建config / local.json覆蓋某些配置。配置有很多,有興趣可以自行查看,這里簡(jiǎn)單的配置參考如下:{
??"port":?7300,
??"host":?"0.0.0.0",
??"pageSize":?30,
??"proxy":?false,
??"db":?"mongodb://localhost/easy-mock",
??"unsplashClientId":?"",
??"redis":?{
????"keyPrefix":?"[Easy?Mock]",
????"port":?6379,
????"host":?"localhost",
????"password":?"",
????"db":?0
??},
??"blackList":?{
????"projects":?[],?//?projectId,?e.g."5a4495e16ef711102113e500"
????"ips":?[]?//?ip,?e.g.?"127.0.0.1"
??},
??"rateLimit":?{?//?https://github.com/koajs/ratelimit
????"max":?1000,
????"duration":?1000
??},
??"jwt":?{
????"expire":?"14?days",
????"secret":?"shared-secret"
??},
??"upload":?{
????"types":?[".jpg",?".jpeg",?".png",?".gif",?".json",?".yml",?".yaml"],
????"size":?5242880,
????"dir":?"../public/upload",
????"expire":?{
??????"types":?[".json",?".yml",?".yaml"],
??????"day":?-1
????}
??},
??"ldap":?{
????"server":?"",?//?Set?server?to?enable?LDAP?login.?e.g.?"ldap://localhost:389"?or?"ldaps://localhost:389"(use?SSL)
????"bindDN":?"",?//?Username,e.g.?"cn=admin,dc=example,dc=com"
????"password":?"",
????"filter":?{
??????"base":?"",?//?Base?where?we?can?search?for?users,e.g.?"dc=example,dc=com"
??????"attributeName":?""?//?e.g.?"mail"?or?"email"?etc.
????}
??},
??"fe":?{
????"copyright":?"",
????"storageNamespace":?"easy-mock_",
????"timeout":?25000,
????"publicPath":?"/dist/"
??}
}
部署,官方建議使用PM2,操作如下
全局安裝PM2
$?[sudo]?npm?install?pm2?-g通過(guò)PM2啟動(dòng)
應(yīng)該在此步驟之前運(yùn)行build
$?NODE_ENV=production?pm2?start?app.js當(dāng)我們完成以上操作后,啟動(dòng)服務(wù),在頁(yè)面訪問(wèn),會(huì)看到以下頁(yè)面:
? ? 當(dāng)然,我們得做點(diǎn)什么,讓頁(yè)面看起來(lái)高大上一點(diǎn)。我們可以對(duì)這個(gè)頁(yè)面的改造,比如我們把logo換成我們自己團(tuán)隊(duì)的,把里面的一些不經(jīng)常用的入口屏蔽了。在里面增加一些其他操作都是可以的,別把應(yīng)用搞崩即可。
? ? 我們改造完成之后,重新打包,更新服務(wù)就可以看到效果了。
四、easy-mock語(yǔ)法
? ? 我們除了一些簡(jiǎn)單的api接口數(shù)據(jù)獲取,我們還可以輸出一些定制化的數(shù)據(jù)。我們得熟悉它的使用,以及它的語(yǔ)法。
語(yǔ)法規(guī)范
Mock.js 的語(yǔ)法規(guī)范包括兩部分:
1、數(shù)據(jù)模板定義規(guī)范(Data Template Definition,DTD)
2、數(shù)據(jù)占位符定義規(guī)范(Data Placeholder Definition,DPD)
數(shù)據(jù)模板定義規(guī)范 DTD
數(shù)據(jù)模板中的每個(gè)屬性由 3 部分構(gòu)成:屬性名、生成規(guī)則、屬性值:
//?屬性名???name
//?生成規(guī)則?rule
//?屬性值???value
'name|rule':?value注意:屬性名 和 生成規(guī)則 之間用豎線 | 分隔。生成規(guī)則 是可選的。生成規(guī)則 有 7 種格式:
'name|min-max':?value
'name|count':?value
'name|min-max.dmin-dmax':?value
'name|min-max.dcount':?value
'name|count.dmin-dmax':?value
'name|count.dcount':?value
'name|+step':?value
生成規(guī)則 的 含義 需要依賴(lài) 屬性值的類(lèi)型 才能確定。
屬性值 中可以含有?@占位符。
屬性值 還指定了最終值的初始值和類(lèi)型。
生成規(guī)則和示例:
1. 屬性值是字符串 String
'name|min-max':?string通過(guò)重復(fù)?string?生成一個(gè)字符串,重復(fù)次數(shù)大于等于?min,小于等于?max。
'name|count':?string通過(guò)重復(fù)?string?生成一個(gè)字符串,重復(fù)次數(shù)等于?count。
2. 屬性值是數(shù)字 Number
'name|+1':?number屬性值自動(dòng)加 1,初始值為?number。
'name|min-max':?number生成一個(gè)大于等于?min、小于等于?max?的整數(shù),屬性值?number?只是用來(lái)確定類(lèi)型。
'name|min-max.dmin-dmax':?number生成一個(gè)浮點(diǎn)數(shù),整數(shù)部分大于等于?min、小于等于?max,小數(shù)部分保留?dmin?到?dmax?位。
Mock.mock({
????'number1|1-100.1-10':?1,
????'number2|123.1-10':?1,
????'number3|123.3':?1,
????'number4|123.10':?1.123
})
//?=>
{
????"number1":?12.92,
????"number2":?123.51,
????"number3":?123.777,
????"number4":?123.1231091814
}
3. 屬性值是布爾型 Boolean
'name|1':?boolean隨機(jī)生成一個(gè)布爾值,值為?true?的概率是 1/2,值為?false?的概率同樣是 1/2。
'name|min-max':?value
隨機(jī)生成一個(gè)布爾值,值為 value 的概率是?min / (min + max),值為 !value 的概率是?max / (min + max)。
4. 屬性值是對(duì)象 Object
'name|count':?object從屬性值?object?中隨機(jī)選取?count?個(gè)屬性。
'name|min-max':?object
從屬性值?object?中隨機(jī)選取?min?到?max?個(gè)屬性。
5. 屬性值是數(shù)組 Array
'name|1':?array從屬性值?array?中隨機(jī)選取 1 個(gè)元素,作為最終值。
'name|+1':?array
從屬性值?array?中順序選取 1 個(gè)元素,作為最終值。
'name|min-max':?array通過(guò)重復(fù)屬性值?array?生成一個(gè)新數(shù)組,重復(fù)次數(shù)大于等于?min,小于等于?max。
'name|count':?array
通過(guò)重復(fù)屬性值?array?生成一個(gè)新數(shù)組,重復(fù)次數(shù)為?count。
6. 屬性值是函數(shù) Function
'name':?function執(zhí)行函數(shù) function,取其返回值作為最終的屬性值,函數(shù)的上下文為屬性?'name'?所在的對(duì)象。
7. 屬性值是正則表達(dá)式 RegExp
'name':?regexp根據(jù)正則表達(dá)式 regexp 反向生成可以匹配它的字符串。用于生成自定義格式的字符串。
Mock.mock({
????'regexp1':?/[a-z][A-Z][0-9]/,
????'regexp2':?/\w\W\s\S\d\D/,
????'regexp3':?/\d{5,10}/
})
//?=>
{
????"regexp1":?"pJ7",
????"regexp2":?"F)\fp1G",
????"regexp3":?"561659409"
}
數(shù)據(jù)占位符定義規(guī)范 DPD
占位符 只是在屬性值字符串中占個(gè)位置,并不出現(xiàn)在最終的屬性值中。
占位符 的格式為:
@占位符 @占位符(參數(shù) [, 參數(shù)]) 注意:
用 @ 來(lái)標(biāo)識(shí)其后的字符串是 占位符。占位符 引用的是?Mock.Random?中的方法。通過(guò)?Mock.Random.extend()?來(lái)擴(kuò)展自定義占位符。占位符 也可以引用 數(shù)據(jù)模板 中的屬性。占位符 會(huì)優(yōu)先引用 數(shù)據(jù)模板 中的屬性。占位符 支持 相對(duì)路徑 和 絕對(duì)路徑。
Mock.mock({
????name:?{
????????first:?'@FIRST',
????????middle:?'@FIRST',
????????last:?'@LAST',
????????full:?'@first?@middle?@last'
????}
})
//?=>
{
????"name":?{
????????"first":?"Charles",
????????"middle":?"Brenda",
????????"last":?"Lopez",
????????"full":?"Charles?Brenda?Lopez"
????}
}
一些規(guī)則 【少量數(shù)據(jù)不能夠兼容】
{
"cname":?"@cname",//中文人名
"id":?"@id",//生成20?位數(shù)字
"title":?"@ctitle",//中文title
"city":?"@city",//中文城市
"ip":?"@ip",//ip?地址
"email":?"@email",//email
"url":?"@url",//url
"cfirst":?"@cfirst",//姓名,姓
"clast":?"@clast",//姓名,名
"cword":?"@cword('123456')",//123456?從中選取一個(gè)字符
"csentence":?"@csentence(1,5)",//文字文段
"csentence5":?"@csentence(5)",//文字文段
"cparagraph":?"@cparagraph(1,3)",//文字文段
"string":?"@string(11)",//輸出11?個(gè)字符長(zhǎng)度的字符串
"float":?"@float(0,10)",//0?到?10?的浮點(diǎn)數(shù)
"int":?"@integer(60,70)",//60?到?70?之間的整數(shù)
"boolean":?"@boolean",//boolean?類(lèi)型?true,false
"array|1-3":?[{
"id":?"@integer(1,10)",//整數(shù)?1到10?取整數(shù)
"name":?"cname"
}],//數(shù)組(隨機(jī)?1?到3個(gè))
"array_sort_add|+1":?["1",?"2",?"3"],//數(shù)組1,2,3輪詢(xún)輸出
"boolean|1-2":?true,//boolean?類(lèi)型?true,false
"actionType|1":?['click_url',?'open_resource_detail',?'open_resource_search'],
"payload":?function()?{
??????var?returnClickUrl?=?{
????????"linkUrl":?"http://tob.zhisland.com/apph5"
??????};
??????var?returnResourceDetail?=?{
????????"resourceId":?"606"
??????};
??????var?returnResourceSearch?=?{
????????"keyWords":?"",
????????"tagCategory":?"1",
????????"tag":?"1"
??????};
??????var?s?=?this.actionType?==?'click_url'???returnClickUrl?:?this.actionType?==?'open_resource_detail'???returnResourceDetail?:?returnResourceSearch;
??????return?s;
?}//function?返回設(shè)置返回的數(shù)據(jù)
}五、總結(jié)
? ? 這里我們列舉了業(yè)界一些Mock應(yīng)用,我們可以根據(jù)需要選擇一款應(yīng)用進(jìn)行使用。廣東靚仔推薦easy-mock,用了好久,感覺(jué)不錯(cuò)。關(guān)注我,一起攜手前行
歡迎關(guān)注前端早茶,與廣東靚仔攜手共同進(jìn)階


