美文网首页实用前端
前端工程化之--Mock解决方案

前端工程化之--Mock解决方案

作者: d6e83ee69161 | 来源:发表于2017-04-19 11:06 被阅读3631次
    图片来自网络

    前端Mock的常见解决方案

    Mock数据进行调试是前端构建中不可或缺的一步,常见的前端Mock方案分为4种:

    1. 在代码层硬编码
      比如有一个函数负责请求某个接口,获得的回返数据,并对该回返数据进行操作。那么可以通过硬编码的方式,直接定义一个数据变量在代码中,该变量保存了回返的Mock数据。这种Mock方法操作比较简单,但缺点也很明显,就是Mock更改了代码逻辑,和代码耦合性太强。而且并不能模拟真实的网络请求的过程,局限性强,覆盖面窄。

    2. 在前端JS中拦截
      典型的解决方案就是Mock.js,通过在业务代码前挂载该JS文件,就可以无痛拦截Ajax请求。这种Mock方式相较于硬编码,虽然实现了Mock与代码的部分解耦,但无法完全和业务代码解耦(因为必须挂载一个JS并进行Mock配置)。虽然提供了大量的Mock API,但是也仍然无法发出真实的网络请求,模拟真实度不够。另外这种方式还存在一些不足,因为是对XHR对象的改写,有些情况下兼容性并不好,比如IE8等低版本浏览器,还有较新的Fetch API也拦截不到。

    3. 代理软件(Fiddler、Charles)拦截
      Fiddler和Charles可以对网络请求进行拦截,将其替换为我们需要的Mock数据,这也不失为一种Mock方式。其优点主要是真实性强,但这种方式操作步骤比较繁琐,不方便统一配置,Mock成本较高。

    4. Mock-Server
      最合适的方案无外乎搭建独立的Mock-Server,开发的前期阶段,所有的接口都会指向该Mock-Server。因为可能存在跨域的情况,所以一般都需要在开发环境搭配一套接口代理做搭配。这种方案对业务代码完全不具有侵入性,并且通用性强。缺点也很明显,成本高(还需要另起一个Mock-Server服务,并对其进行管理)。

    接口定义与Mock数据相结合的方案

    其实常见的解决方案便是上面提到的几种,或是在这类的基础上进行调整,但整体思路基本一致。Mock的本质是为了能让接口消费者脱离接口生产者进行开发,但是这个脱离并不是指脱离生产者的接口定义随意开发,接口定义与Mock数据的一致性也是我们必须考虑的一个问题,我们必须要确保Mock出的数据符合接口定义中的要求。所以实际上我们还需要多考虑一个问题:如何让接口定义的维护和Mock结合起来?

    很庆幸的是,我们有RAP这项工具。RAP是一款非常棒的工具,它是一个可视化接口管理工具,将所有的接口开发定义以其要求的格式进行管理,并能根据这些定义来产生Mock数据,提供给消费者。

    既然有了RAP为我们提供Mock-Server服务,那么我们下一步欠缺的就是如何让代码中的网络请求能直接访问到RAP上。RAP有提供一种插件JS,是在Mock.js的基础上扩展的,可以拦截页面上的请求,但暂时仅支持Kissy和jQuery。为此我们在Koa的基础上,结合RAP提供的NodeJS插件(rap-node-plugin)开发了一组工具,能够将配置中要求拦截的所有请求转发到RAP上,并将RAP生成的数据返回给请求方。另外,考虑到Mock调试中,RAP的Mock规则有限和接口定义文档频繁变更的问题,我们还加入了本地mock解决方案,可以随时随地的更改本地local-mock.js文件,避免频繁的RAP文档编辑。本地mock还支持以函数的形式动态返还Mock数据,大大提升了Mock数据生成的能力。另外,在网络请求Mock中,网络延时有时必不可少,我们通过在接口定义中添加_delay字段,可以决定让该接口多长时间后返回,其它下划线字段可以按需添加。RAP中的配置:

    RAP接口配置

    Mock方案实现

    方案主要由以下4个组件构成:

    mock工具
    • config.js
      包含一些对mock工具的配置
    /**
     * 默认配置
     */
    export default {
      PATH: '/pc/*',  // 默认拦截的路径
      USE_RAP: true, // 默认为true,会去寻找并调用RAP上的接口
      RAP_CONFIG: {
        host: 'rap.fe.yeshj.com', //启动的服务主机
        port: 80, //端口号
        projectId: 115, //RAP配置的项目ID
        mock: '/mockjsdata/', //RAP前缀
        wrapper: '' //不需要包装
      }
    }
    
    • filter.js
      KOA中间件,会对config中配置的PATH进行请求拦截,并根据相关配置获得请求回返数据,进行一定程度的包装,回返为Mock数据。与接口相关的_delay操作也在该中间件内实现

    • local_mock.js
      负责本地mock规则及数据的存放。_delay关键字在此配置,header支持自定义回返头部,body回返体数据支持以函数的形式进行生成。

    module.exports = {
      "POST /pc/check": {
        "_delay": 1000,
        "header": {
          "Content-Type": "application/json;charset=utf-8"
        },
        "body": function (ctx) {
          return {
            "status": 0,
            "data": {
              "ctx": ctx
            }
          }
        }
      },
      "POST /pc/info": {
        "_delay": 0,
        "header": {
          "Content-Type": "application/json;charset=utf-8"
        },
        "body": {
          "data": {
            "id": "12121212"
          },
          "message": "成功",
          "status": 0
        }
      }
    }
    
    • rap_connector.js
      该组件是对rap-node-plugin的封装,方便调用。

    开发环境集成

    下面就是如何将mock集成到我们的开发环境中去了。

    • 建立mock目录
      该Mock方案因为涉及到配置的调整和本地Mock数据的改写,不适于做成单独的node_module进行封装,所以我们选择将mock方案集成到项目中的构建工具中去,目录层级如下:
    Paste_Image.png
    • package.json中增加新脚本mock:
    "scripts": {
        "start": "npm run mock",
        "mock": "babel-node ./tools/build/server.js --dev --mock"
    }
    
    • 在koa中注入mock中间件:
    if (argv.mock && config.mockEnable) {
        let mockFilter = require('../mock/filter.js');
        app.use(mockFilter());
    }
    

    最后一步的工作很简单,就是在mock/config.js中进行一些简单配置,然后在bash中输入npm start就可以享受我们整套的mock解决方案了。

    相关文章

      网友评论

      本文标题:前端工程化之--Mock解决方案

      本文链接:https://www.haomeiwen.com/subject/cnxczttx.html