在 Angular-cli 中使用 simple-mock 实现前端开发 API Mock 接口数据模拟

在前后端分离的开发模式中,接口数据模拟(API Mock)是不可避免的事情。前端同学在应对该情况时采取的办法可以各种各样,大概的方案可能会是这几类:

  1. 业务代码中临时写上 mock 数据的逻辑
  2. 在前端引入 mock 服务或框架,对 HTTP 请求服务进行拦截
  3. 代理转发至自建的 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.0Angular^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

| 1 | npm i -D @lzwme``/simple-mock |

| 2 | # or |

| 3 | yarn add -D @lzwme``/simple-mock |

2.2 增加配置文件angular.json 的代理配置项

在配置文件 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 相关 API 实现 mock 功能。

这里我们还引入了 co-body 用于解码 post 请求的参数,以便于自定义 mock 规则时使用。

该文件内容参考如下:

| 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 | * ``详细配置参考: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 请求参数至 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; |

以上操作完成,执行 ng serve,即会在项目根目录创建 mock 目录和 simple-mock 的配置文件 simple-mock-config.js,这些文件都会在 .gitignore 中注入过滤规则,可以在本地随意修改。

2.4 修改 simple-mock 配置文件

simple-mock 可以通过读取配置文件 simple-mock-config.js 判断 mock 的开启或关闭。

对于针对本文实现的示例项目 github-user-search-ng,该配置文件内容参考如下:

| 01 | module.exports = ``{ |

| 02 | mockFileDir: ``'mock'``, ``// path.contentlove(__dirname, 'mock'), // 指定 mock 文件存放的目录 |

| 03 | isEnableMock: ``true``, ``// 是否开启 Mock API 功能 |

| 04 | isAutoSaveApi: ``true``, ``// 是否自动保存远端请求的 API |

| 05 | isForceSaveApi: ``false``, ``// 是否强制保存,否则本地有时不再保存 |

| 06 | // 自动保存 API 返回内容时,对内容进行过滤的方法,返回为 true 才保存 |

| 07 | fnAutosaveFilter(content) { |

| 08 | // 示例: 不保存空的或 404 的内容 |

| 09 | if (!content || content.message === ``'Not Found'``) { |

| 10 | return false``; |

| 11 | } |

| 12 | |

| 13 | return true``; |

| 14 | } |

| 15 | }; |

通过修改配置文件中的开关,即可实现 mock 功能的开启或关闭了。

2.5 通过环境变量开启或关闭 Mock 功能

除了读取配置文件,simple-mock 还可以通过读取环境变量判断 mock 的开启或关闭(环境变量的优先级更高,方便将开关注入到工程化工具中),详细用法参考 simple-mock 使用文档

例如在示例项目 github-user-search-ng中,创建了 dev-start.bat 文件,在 window 下开发时,启动该文件即可即时选择是否开启 mock 功能。

dev-start.bat 文件主要内容参考:

| 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 是为本文实现的一个示例项目,有兴趣可前往查阅完整的仓库代码。

本文的方案本质上是在 http-proxy-middleware 执行过程中,注入 simple-mock 相关 API 实现 Mock 功能。故本文的示例方法,实际适用于任何使用 http-proxy-middleware 作为 HTTP 代理的 node server 服务。在 simple-mock 的说明文档中,则是以 node-http-proxy 代理库作为示例,有兴趣可进一步参考研究。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350