zoukankan      html  css  js  c++  java
  • 深入浅出的webpack4构建工具---比mock模拟数据更简单的方式(二十一)

    如果想要了解mock模拟数据的话,请看这篇文章(https://www.cnblogs.com/tugenhua0707/p/9813122.html

    在实际应用场景中,总感觉mock数据比较麻烦,并且在webpack3中mock数据的代码在正式环境并不能自动移除掉,导致正式环境有mock相对应的代码,但是在webpack4中,会使用 tree shaking插件会自动移除掉未使用到的代码的,想要了解tree shaking(https://www.cnblogs.com/tugenhua0707/p/9671618.html),请看这篇文章。所以为了兼容webpack版本的话,研究了一种新的方式来模拟后台接口数据,使用webpack中的 devServer.before这个配置即可,详细请看如下介绍。
    在讲解如何模拟数据之前,我们来看下我目前整个项目架构如下:

    ### 目录结构如下:
    demo1                                       # 工程名
    |   |--- dist                               # 打包后生成的目录文件             
    |   |--- node_modules                       # 所有的依赖包
    |   |--- app
    |   | |---index
    |   | | |-- views                           # 存放所有vue页面文件
    |   | | | |-- parent.vue                    # 父组件
    |   | | | |-- child.vue                     # 子组件
    |   | | | |-- index.vue
    |   | | |-- components                      # 存放vue公用的组件
    |   | | |-- js                              # 存放js文件的
    |   | | |-- store                           # store仓库
    |   | | | |--- actions.js
    |   | | | |--- mutations.js
    |   | | | |--- state.js
    |   | | | |--- mutations-types.js
    |   | | | |--- index.js
    |   | | |-- app.js                          # vue入口配置文件
    |   | | |-- router.js                       # 路由配置文件
    |   |--- views
    |   | |-- index.html                        # html文件
    |   |--- json                               # 存放所有模拟数据
    |   | |-- parent_getPower.json
    |   | |-- parent_reConfig.json
    |   | |-- parent_reconlist.json
    |   | |-- parent_reGroup.json 
    |   |--- mock.js                            # mock 数据的所有调用方法
    |   |--- webpack.config.js                  # webpack配置文件 
    |   |--- .gitignore  
    |   |--- README.md
    |   |--- package.json
    |   |--- .babelrc                           # babel转码文件

    项目的结构如上所示:其中 json 文件夹内会存放所有模拟的数据,比如和开发后台约定好的数据,我可以直接把数据复制到json文件内,比如我们简单的看下 parent_reConfig.json 数据代码如下(假如开发接口返回的数据是这样的):

    {
      "data": [{
          "bTableName": "reconfig",
          "businessCode": "reconfig",
          "businessImportImpl": "reconfig",
          "businessImportMethod": "reconfig",
          "businessName": "reconfig"
        }
      ],
      "code": 0
    }

    其他的json文件也是类似的数据,这里不一一贴代码哦,有兴趣的话,可以到下面的github上查看demo。

    json文件命名方式:比如我上面json下的叫 parent_reConfig.json, 因为vue页面叫 parent.vue, 所以前缀就是页面的名称,然后下划线(_) + reConfig + 'json', 其中reConfig 是接口的最后一个名字,这样命名的话,我一眼就可以知道是那个页面下的接口,接口是做什么使用的。方便以后接口很多更容易区分。

    2. 在项目的根目录下 mock.js 代码是如下所示:

    const getPower = require('./json/parent_getPower.json');
    const reConfig = require('./json/parent_reConfig.json');
    const reConList = require('./json/parent_reconlist.json');
    const reGroup = require('./json/parent_reGroup.json');
    
    function Mock(app) {
      app.get('/xxxx/yyy', function(req, res) {
        console.log('getPower111');
        res.json(getPower);
      });
      app.post('/reconfig', function(req, res) {
        console.log('reConfig111');
        res.json(reConfig);
      });
      app.post('/conlist', function(req, res) {
        console.log('reConList111');
        res.json(reConList);
      });
      app.post('/regroup', function(req, res) {
        console.log('reGroup111');
        res.json(reGroup);
      });
    }
    
    module.exports = Mock;

    如上代码首先是把 json文件夹下的所有的json文件 require进来,然后定义一个函数,里面写所有的(get或post)方法,然后使用 res.json 方式就可以把上面的json数据模拟返回回来。如上的app参数是从webpack.config.js 配置传进来的。

    3. webpack.config.js 配置方式如下:

    // 引入mock.js
    const Mock = require('./mock.js');
    
    module.exports = {
      devServer: {
        port: 8082,
        host: '0.0.0.0',
        headers: {
          'X-foo': '112233'
        },
        inline: true,
        overlay: true,
        stats: 'errors-only',
        before: function(app) {
          console.log(app);
          if (process.env.NODE_ENV === 'mock') {
            Mock(app);
          }
        }
      },
      plugins: [
        // 设置环境变量信息
        new webpack.DefinePlugin({
          'process.env': {
            NODE_ENV: JSON.stringify(process.env.NODE_ENV)
          }
        })
      ]
    }

    如上配置代码,首先引入 mock.js 进来,上面的mock.js对外返回函数,因此在devServer.before中配置调用下Mock函数,传入参数是app,并且环境变量也判断了下,如果是 mock环境,就执行mock函数代码的数据,否则不是mock命令的话,就不会执行mock数据,而是执行真正环境的数据。下面我们来看下 上面 before函数打印的app是什么东西,如下所示:

    { [EventEmitter: app]
      domain: undefined,
      _events: { mount: [Function: onmount] },
      _maxListeners: undefined,
      setMaxListeners: [Function: setMaxListeners],
      getMaxListeners: [Function: getMaxListeners],
      emit: [Function: emit],
      addListener: [Function: addListener],
      on: [Function: addListener],
      prependListener: [Function: prependListener],
      once: [Function: once],
      prependOnceListener: [Function: prependOnceListener],
      removeListener: [Function: removeListener],
      removeAllListeners: [Function: removeAllListeners],
      listeners: [Function: listeners],
      listenerCount: [Function: listenerCount],
      eventNames: [Function: eventNames],
      init: [Function: init],
      defaultConfiguration: [Function: defaultConfiguration],
      lazyrouter: [Function: lazyrouter],
      handle: [Function: handle],
      use: [Function: use],
      route: [Function: route],
      engine: [Function: engine],
      param: [Function: param],
      set: [Function: set],
      path: [Function: path],
      enabled: [Function: enabled],
      disabled: [Function: disabled],
      enable: [Function: enable],
      disable: [Function: disable],
      acl: [Function],
      bind: [Function],
      checkout: [Function],
      connect: [Function],
      copy: [Function],
      delete: [Function],
      get: [Function],
      head: [Function],
      link: [Function],
      lock: [Function],
      'm-search': [Function],
      merge: [Function],
      mkactivity: [Function],
      mkcalendar: [Function],
      mkcol: [Function],
      move: [Function],
      notify: [Function],
      options: [Function],
      patch: [Function],
      post: [Function],
      propfind: [Function],
      proppatch: [Function],
      purge: [Function],
      put: [Function],
      rebind: [Function],
      report: [Function],
      search: [Function],
      subscribe: [Function],
      trace: [Function],
      unbind: [Function],
      unlink: [Function],
      unlock: [Function],
      unsubscribe: [Function],
      all: [Function: all],
      del: [Function],
      render: [Function: render],
      listen: [Function: listen],
      request: IncomingMessage { app: [Circular] },
      response: ServerResponse { app: [Circular] },
      cache: {},
      engines: {},
      settings: {},
      _eventsCount: 1,
      locals: 
       { settings: {}},
      mountpath: '/',
      _router: {} 
    }

    更多关于 devServer.before可以看官网(https://webpack.js.org/configuration/dev-server/#devserver-before)。

    4. package.json 配置如下:

    {
      "scripts": {
        "dev": "cross-env NODE_ENV=development webpack-dev-server --progress --colors --devtool cheap-module-eval-source-map --hot --inline",
        "build": "cross-env NODE_ENV=production webpack --progress --colors --devtool cheap-module-source-map",
        "build:dll": "webpack --config webpack.dll.config.js",
        "start": "webpack-dev-server --progress --colors --devtool cheap-module-eval-source-map --hot --inline",
        "mock": "cross-env NODE_ENV=mock npm run start"
      },
    }

    5. app/index/views/parent.vue 代码如下所示:

    <template>
      <div>
      </div>
    </template>
    <script type="text/javascript">
      import { mapActions } from 'vuex';
      export default {
        data() {
          return {
          }
        },
        created() {
          this.testMock();
        },
        methods: {
          testMock() {
            const obj = {
              'xx': 11
            };
            // 请求的地址是 '//xxx.abc.com/xxxx/yyy'
            Promise.all([this.commonActionGet(['getPower', obj])]).then((res) => {
              console.log('getPower');
              console.log(typeof res);
              console.log(res);
            });
    
            Promise.all([this.commonActionPost(['reConfig', obj])]).then((res) => {
              console.log('reConfig');
              console.log(res);
            });
    
            Promise.all([this.commonActionPost(['reConList', obj])]).then((res) => {
              console.log('reConList');
              console.log(res);
            });
    
            Promise.all([this.commonActionPost(['reGroup', obj])]).then((res) => {
              console.log('reGroup');
              console.log(res);
            });
          },
          ...mapActions(['commonActionGet', 'commonActionGetJSON', 'commonActionPost', 'commonActionPostJSON'])
        },
        mounted() {
    
        }
      }
    </script>

    如上代码,当我执行打包命令 npm run mock 时,就会调用webpack中的 devServer.before函数,该函数会判断当前的环境是否是mock命令,如果是mock命令就执行 mock.js中的Mock函数,然后会请求数据。

    注意:上面的请求数据是:'//0.0.0.0:8082/reconfig' 这样的,这样就可以把 json/parent_reConfig.json请求的数据返回回来,但是我们真正的接口的前缀可能是 '//xxx.abc.com', 因此我们在配置所有的接口名称的时候,接口域名的前缀我们可以定义一个变量,然后传递进去。比如我下面是这样定义的:

    // const prefix = '//xxx.abc.com'; // 真正的域名接口先注释掉
    const prefix = '//0.0.0.0:8082';

    我们可以简单的判断下:

    let prefix;
    if (process.env.NODE_ENV === 'mock') {
      prefix = '//0.0.0.0:8082'; // 测试域名
    } else {
      prefix = '//xxx.abc.com'; // 正式域名
    }

    const url = prefix + '/reconfig';

    类似上面这中形式,因此当我们在页面上请求 this.$http.get(url);的时候,实际上在mock数据下请求的是 '//0.0.0.0:8082/reconfig' 这样的,因此会直接被 devServer.before中拦截到,因此会返回我们的模拟上的数据,但是在我们使用 npm run dev 或 npm run build 的时候,我们需要把 //xxx.abc.com 这个真正的接口域名前缀打开,'//0.0.0.0:8082' 需要被注释掉。就可以了,其他的vue中的代码不需要做任何改动,以前该怎么写,现在也还是就那么写。

    查看github上的代码

  • 相关阅读:
    Unity3d 汽车物理系第二篇
    Unity3d 汽车物理系统
    RabbitMq 之客户端(publish,subscrbe)
    MongoDB Python create by lee
    sql 分页语句 备忘
    结构化结点定位(数据结构)
    Mongodb 安装
    url 的相对路径转换成绝对路径方法
    mongodb cloud store db
    快速备份指定的表 create by lee
  • 原文地址:https://www.cnblogs.com/tugenhua0707/p/9846298.html
Copyright © 2011-2022 走看看