在前后端分離的開發(fā)模式中拆吆,接口數(shù)據(jù)模擬(API Mock)是不可避免的事情线婚。前端同學(xué)在應(yīng)對(duì)該情況時(shí)采取的辦法可以各種各樣洋措,大概的方案可能會(huì)是這幾類:
- 業(yè)務(wù)代碼中臨時(shí)寫上 mock 數(shù)據(jù)的邏輯
- 在前端引入 mock 服務(wù)或框架剑按,對(duì) HTTP 請(qǐng)求服務(wù)進(jìn)行攔截
- 代理轉(zhuǎn)發(fā)至自建的 mock server
本文主要介紹在 Angular-cli
中引入 simple-mock
以快速實(shí)現(xiàn)項(xiàng)目數(shù)據(jù)接口模擬功能的方法菇用。該方案本質(zhì)上為上述的第三種方案澜驮。
1 simple-mock 簡(jiǎn)介
simple-mock
是一個(gè)引入成本簡(jiǎn)單的 API Mcok 庫(kù),通過提供 API 方法供 node Server 調(diào)用惋鸥,以幫助 node Server 實(shí)現(xiàn) Mock 功能杂穷。實(shí)現(xiàn)該庫(kù)的主要目的還是為了懶,希望前端開發(fā)過程中 mock 數(shù)據(jù)能夠盡可能地簡(jiǎn)單卦绣。
與常見 Mock 庫(kù)或 Mock Server 有點(diǎn)不同的是耐量,它實(shí)現(xiàn)了自動(dòng)保存后端 API 數(shù)據(jù)的功能,如果你足夠懶且隨意滤港,可以不寫任何 mock 規(guī)則廊蜒。
2 在 Angular-cli 中使用 simple-mock
這里以 Angular-cli^7.0.0
和 Angular^7.0.0
為例。
Angular-cli^7.0.0
在執(zhí)行 ng serve
時(shí)溅漾,內(nèi)部實(shí)際是采用 express 啟動(dòng) node server山叮,并且使用 http-proxy-middleware
實(shí)現(xiàn) HTTP API 代理。所以本文方案的本質(zhì)是在 http-proxy-middleware
執(zhí)行過程中添履,注入 simple-mock
相關(guān) API 實(shí)現(xiàn) Mock 功能屁倔。
在 Angular-cli 中引入 simple-mock 的方法十分簡(jiǎn)單。具體流程參考如下暮胧。
2.1 在項(xiàng)目中引入 simple-mock
| 1
| npm i -D @lzwme``/simple-mock
|
| 2
| # or
|
| 3
| yarn add -D @lzwme``/simple-mock
|
2.2 增加配置文件angular.json
的代理配置項(xiàng)
在配置文件 angular.json
中的 serve/options
部分增加 proxyConfig
字段的配置锐借。參考:
| 01
| {
|
| 02
| "serve"``: {
|
| 03
| "builder"``: ``"@angular-devkit/build-angular:dev-server"``,
|
| 04
| "options"``: {
|
| 05
| "browserTarget"``: ``"github-user-search:build"``,
|
| 06
| "liveReload"``: ``true``,
|
| 07
| "open"``: ``true``,
|
| 08
| "host"``: ``"localhost"``,
|
| 09
| "port"``:
3008``,
|
| 10
| "servePath"``: ``"/"``,
|
| 11
| "publicHost"``: ``"localhost"``,
|
| 12
| "proxyConfig"``: ``"config/ngcli-proxy-config.js"
|
| 13
| },
|
| 14
| },
|
| 15
| }
|
proxyConfig 的值 config/ngcli-proxy-config.js
為我們自定義的代理配置定義文件。
2.3. 新建自定義代理配置文件 config/ngcli-proxy-config.js
我們通過在自定義代理配置文件中引入 simple-mock
相關(guān) API 實(shí)現(xiàn) mock 功能往衷。
這里我們還引入了 co-body
用于解碼 post
請(qǐng)求的參數(shù)钞翔,以便于自定義 mock 規(guī)則時(shí)使用。
該文件內(nèi)容參考如下:
| 01
| const
anyParse
= ``require(``'co-body'``);
|
| 02
| const
apiMock
= ``require(``'@lzwme/simple-mock'``);
|
| 03
| const
chalk
= ``require(``'chalk'``);
|
| 04
| const
apiProxyList
= ``{
|
| 05
| '/users/**'``: ``'[https://api.github.com/](https://api.github.com/)'``,
|
| 06
| };
|
| 07
| /**
|
| 08
| * ``詳細(xì)配置參考:https:``//www.npmjs.com/package/http-proxy-middleware
|
| 09
| */
|
| 10
| const
proxyCfg
= ``Object.keys(apiProxyList).reduce((pCfg, key) => {
|
| 11
| const
proxyTarget
= ``apiProxyList[key];
|
| 12
| |
| 13
| pCfg[key]
= ``{
|
| 14
| target: proxyTarget,
|
| 15
| changeOrigin: ``true``,
|
| 16
| onProxyRes(proxyRes, req, res) {
|
| 17
| apiMock.saveApi(req, res, proxyRes.headers[``'content-encoding'``]);
|
| 18
| },
|
| 19
| async
onProxyReq(proxyReq, req, res) {
|
| 20
| // 嘗試解碼 post 請(qǐng)求參數(shù)至 req.body
|
| 21
| if
(!req.body && proxyReq.getHeader(``'content-type'``)) {
|
| 22
| try
{
|
| 23
| req.body
= ``await
anyParse({req});
|
| 24
| } ``catch``(err) {
|
| 25
| // console.log(err);
|
| 26
| }
|
| 27
| }
|
| 28
| |
| 29
| apiMock.render(req, res).then(isMocked => {
|
| 30
| if
(!isMocked) {
|
| 31
| console.log(chalk.cyan(``'[apiProxy]'``), req._parsedUrl.pathname, ``'\t'``, chalk.yellow(proxyTarget));
|
| 32
| }
|
| 33
| });
|
| 34
| },
|
| 35
| };
|
| 36
| return
pCfg;
|
| 37
| }, {});
|
| 38
| module.exports
= ``proxyCfg;
|
以上操作完成炼绘,執(zhí)行 ng serve
嗅战,即會(huì)在項(xiàng)目根目錄創(chuàng)建 mock
目錄和 simple-mock
的配置文件 simple-mock-config.js
,這些文件都會(huì)在 .gitignore
中注入過濾規(guī)則俺亮,可以在本地隨意修改。
2.4 修改 simple-mock 配置文件
simple-mock
可以通過讀取配置文件 simple-mock-config.js
判斷 mock 的開啟或關(guān)閉疟呐。
對(duì)于針對(duì)本文實(shí)現(xiàn)的示例項(xiàng)目 github-user-search-ng脚曾,該配置文件內(nèi)容參考如下:
| 01
| module.exports
= ``{
|
| 02
| mockFileDir: ``'mock'``, ``// path.contentlove(__dirname, 'mock'), // 指定 mock 文件存放的目錄
|
| 03
| isEnableMock: ``true``, ``// 是否開啟 Mock API 功能
|
| 04
| isAutoSaveApi: ``true``, ``// 是否自動(dòng)保存遠(yuǎn)端請(qǐng)求的 API
|
| 05
| isForceSaveApi: ``false``, ``// 是否強(qiáng)制保存,否則本地有時(shí)不再保存
|
| 06
| // 自動(dòng)保存 API 返回內(nèi)容時(shí)启具,對(duì)內(nèi)容進(jìn)行過濾的方法本讥,返回為 true 才保存
|
| 07
| fnAutosaveFilter(content) {
|
| 08
| // 示例: 不保存空的或 404 的內(nèi)容
|
| 09
| if
(!content || content.message
=== ``'Not Found'``) {
|
| 10
| return
false``;
|
| 11
| }
|
| 12
| |
| 13
| return
true``;
|
| 14
| }
|
| 15
| };
|
通過修改配置文件中的開關(guān),即可實(shí)現(xiàn) mock 功能的開啟或關(guān)閉了。
2.5 通過環(huán)境變量開啟或關(guān)閉 Mock 功能
除了讀取配置文件拷沸,simple-mock
還可以通過讀取環(huán)境變量判斷 mock 的開啟或關(guān)閉(環(huán)境變量的優(yōu)先級(jí)更高色查,方便將開關(guān)注入到工程化工具中),詳細(xì)用法參考 simple-mock 使用文檔撞芍。
例如在示例項(xiàng)目 github-user-search-ng中秧了,創(chuàng)建了 dev-start.bat
文件,在 window 下開發(fā)時(shí)序无,啟動(dòng)該文件即可即時(shí)選擇是否開啟 mock 功能验毡。
dev-start.bat
文件主要內(nèi)容參考:
| 01
| @title GMTS-FRONT-NG-START-HELPER
|
| 02
| @``echo
off
|
| 03
| |
| 04
| set
NODE_ENV=development
|
| 05
| set
MOCKAPI_ENABLE=N
|
| 06
| set
MOCKAPI_AUTOSAVE=N
|
| 07
| set
MOCKAPI_AUTOSAVE_FORCE=N
|
| 08
| |
| 09
| set
/p
enablemock=Enable mockAPI?(y/):
|
| 10
| if
"%enablemock%"``==``"y"
set
MOCKAPI_ENABLE=mock
|
| 11
| |
| 12
| set
/p
autosave=Auoto Save API Data?(y/):
|
| 13
| if
"%autosave%"``==``"y"
set
MOCKAPI_AUTOSAVE=save
|
| 14
| |
| 15
| if
"%enablemock%"``==``"y"
goto run
|
| 16
| |
| 17
| set
/p
forcesave=Force Save API Data?(y/):
|
| 18
| if
"%forcesave%"``==``"y"
set
MOCKAPI_AUTOSAVE_FORCE=force
|
| 19
| |
| 20
| :run
|
| 21
| echo
=======================================================
|
| 22
| echo
MOCKAPI_ENABLE = %MOCKAPI_ENABLE%
|
| 23
| echo
MOCKAPI_AUTOSAVE = %MOCKAPI_AUTOSAVE%
|
| 24
| echo
MOCKAPI_AUTOSAVE_FORCE = %MOCKAPI_AUTOSAVE_FORCE%
|
| 25
| echo
=======================================================
|
| 26
| |
| 27
| ng serve
|
更多參考
github-user-search-ng 是為本文實(shí)現(xiàn)的一個(gè)示例項(xiàng)目,有興趣可前往查閱完整的倉(cāng)庫(kù)代碼帝嗡。
本文的方案本質(zhì)上是在 http-proxy-middleware
執(zhí)行過程中晶通,注入 simple-mock
相關(guān) API 實(shí)現(xiàn) Mock 功能。故本文的示例方法哟玷,實(shí)際適用于任何使用 http-proxy-middleware
作為 HTTP 代理的 node server 服務(wù)狮辽。在 simple-mock 的說明文檔中,則是以 node-http-proxy 代理庫(kù)作為示例巢寡,有興趣可進(jìn)一步參考研究隘竭。