在 Angular-cli 中使用 simple-mock 實現前端開發 API Mock 介面資料模擬
在前後端分離的開發模式中,介面資料模擬(API Mock)是不可避免的事情。前端同學在應對該情況時採取的辦法可以各種各樣,大概的方案可能會是這幾類:
- 業務程式碼中臨時寫上 mock 資料的邏輯
- 在前端引入 mock 服務或框架,對 HTTP 請求服務進行攔截
- 代理轉發至自建的 mock server
本文主要介紹在 Angular-cli
中引入 simple-mock
以快速實現專案資料介面模擬功能的方法。該方案本質上為上述的第三種方案。
1 simple-mock 簡介
simple-mock
是一個引入成本簡單的 API Mcok 庫,通過提供 API 供 node Server 呼叫,以幫助 node Server 實現 Mock 功能。實現該庫的主要目的還是為了懶,希望前端開發過程中 mock 資料能夠儘可能地簡單。
與常見 Mock 庫或 Mock Server 有點不同的是,它實現了自動儲存後端 API 資料的功能,如果你足夠懶且隨意,可以不寫任何 mock 規則。
2 在 Angular-cli 中使用 simple-mock
這裡以 Angular-cli^7.0.0
和 Angular^7.0.0
為例。
Angular-cli^7.0.0
在執行 ng serve
時,內部實際是採用 express 啟動 node server,並且使用 http-proxy-middleware
實現 HTTP API 代理。所以本文方案的本質是在 http-proxy-middleware
執行過程中,注入 simple-mock
相關 API 實現 Mock 功能。
在 Angular-cli 中引入 simple-mock 的方法十分簡單。具體流程參考如下。
2.1 在專案中引入 simple-mock
npm i -D @lzwme/simple-mock # or yarn add -D @lzwme/simple-mock
2.2 增加配置檔案 angular.json
的代理配置項
在配置檔案 angular.json
中的 serve/options
部分增加 proxyConfig
欄位的配置。參考:
{ "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "github-user-search:build", "liveReload": true, "open": true, "host": "localhost", "port": 3008, "servePath": "/", "publicHost": "localhost", "proxyConfig": "config/ngcli-proxy-config.js" }, }, }
proxyConfig 的值 config/ngcli-proxy-config.js
為我們自定義的代理配置定義檔案。
2.3. 新建自定義代理配置檔案 config/ngcli-proxy-config.js
我們通過在自定義代理配置檔案中引入 simple-mock
相關 API 實現 mock 功能。
這裡我們還引入了 co-body
用於解碼 post
請求的引數,以便於自定義 mock 規則時使用。
該檔案內容參考如下:
const anyParse = require('co-body'); const apiMock = require('@lzwme/simple-mock'); const chalk = require('chalk'); const apiProxyList = { '/users/**': 'https://api.github.com/', }; /** * 詳細配置參考:https://www.npmjs.com/package/http-proxy-middleware */ const proxyCfg = Object.keys(apiProxyList).reduce((pCfg, key) => { constproxyTarget = apiProxyList[key]; pCfg[key] = { target: proxyTarget, changeOrigin: true, onProxyRes(proxyRes, req, res) { apiMock.saveApi(req, res, proxyRes.headers['content-encoding']); }, async onProxyReq(proxyReq, req, res) { // 嘗試解碼 post 請求引數至 req.body if (!req.body && proxyReq.getHeader('content-type')) { try { req.body = await anyParse({req}); } catch(err) { // console.log(err); } } apiMock.render(req, res).then(isMocked => { if (!isMocked) { console.log(chalk.cyan('[apiProxy]'), req._parsedUrl.pathname, '\t', chalk.yellow(proxyTarget)); } }); }, }; return pCfg; }, {}); module.exports = proxyCfg;
以上操作完成,執行 ng serve
,即會在專案根目錄建立 mock
目錄和 simple-mock
的配置檔案 simple-mock-config.js
,這些檔案都會在 .gitignore
中注入過濾規則,可以在本地隨意修改。
2.4 修改 simple-mock 配置檔案
simple-mock
可以通過讀取配置檔案 simple-mock-config.js
判斷 mock 的開啟或關閉。
對於針對本文實現的示例專案 ofollow,noindex">github-user-search-ng ,該配置檔案內容參考如下:
module.exports = { mockFileDir: 'mock', // path.contentlove(__dirname, 'mock'), // 指定 mock 檔案存放的目錄 isEnableMock: true, // 是否開啟 Mock API 功能 isAutoSaveApi: true, // 是否自動儲存遠端請求的 API isForceSaveApi: false, // 是否強制儲存,否則本地有時不再儲存 // 自動儲存 API 返回內容時,對內容進行過濾的方法,返回為 true 才儲存 fnAutosaveFilter(content) { // 示例: 不儲存空的或 404 的內容 if (!content || content.message === 'Not Found') { return false; } return true; } };
通過修改配置檔案中的開關,即可實現 mock 功能的開啟或關閉了。
2.5 通過環境變數開啟或關閉 Mock 功能
除了讀取配置檔案, simple-mock
還可以通過讀取環境變數判斷 mock 的開啟或關閉(環境變數的優先順序更高,方便將開關注入到工程化工具中),詳細用法參考 simple-mock 使用文件 。
例如在示例專案 github-user-search-ng 中,建立了 dev-start.bat
檔案,在 window 下開發時,啟動該檔案即可即時選擇是否開啟 mock 功能。
dev-start.bat
檔案主要內容參考:
@title GMTS-FRONT-NG-START-HELPER @echo off set NODE_ENV=development set MOCKAPI_ENABLE=N set MOCKAPI_AUTOSAVE=N set MOCKAPI_AUTOSAVE_FORCE=N set /p enablemock=Enable mockAPI?(y/): if "%enablemock%"=="y" set MOCKAPI_ENABLE=mock set /p autosave=Auoto Save API Data?(y/): if "%autosave%"=="y" set MOCKAPI_AUTOSAVE=save if "%enablemock%"=="y" goto run set /p forcesave=Force Save API Data?(y/): if "%forcesave%"=="y" set MOCKAPI_AUTOSAVE_FORCE=force :run echo ======================================================= echo MOCKAPI_ENABLE= %MOCKAPI_ENABLE% echo MOCKAPI_AUTOSAVE= %MOCKAPI_AUTOSAVE% echo MOCKAPI_AUTOSAVE_FORCE = %MOCKAPI_AUTOSAVE_FORCE% echo ======================================================= ng serve
更多參考
github-user-search-ng 是為本文實現的一個示例專案,有興趣可前往查閱完整的倉庫程式碼。
本文的方案本質上是在 http-proxy-middleware
執行過程中,注入 simple-mock
相關 API 實現 Mock 功能。故本文的示例方法,實際適用於任何使用 http-proxy-middleware
作為 HTTP 代理的 node server 服務。在 simple-mock 的說明文件中,則是以 node-http-proxy 代理庫作為示例,有興趣可進一步參考研究。
- https://github.com/renxia/github-user-search-ng
- https://github.com/lzwme/simple-mock
- https://lzw.me/pages/share/ppt/simple-mock.html
- https://www.npmjs.com/package/http-proxy-middleware