在工程中配置简易的mockjs服务

322 阅读1分钟

mockjs在今天已经是一个很常用的功能了,主要作用是提升前后端分离开发效率,前端可以不依赖于后端,只需要按照api文档即可自己完成开发并调通数据。最近自己实现了下一个比较简易的版本

1.配置mockjs直接引用

// 在main入口引入配置好的mock文件就可以直接调用了
if (process.env.NODE_ENV === 'development') {
  // 区分环境,这样即使打包时忘了把下面代码注释掉也不会影响生产环境
  // require('../../mock') // 不需要开启mock
}

/mock/index.js的配置

// 首先引入Mock
import Mock from 'mockjs'

// 设置拦截ajax请求的相应时间
Mock.setup({
  timeout: '200-600'
})

let configArray = []

// 使用webpack的require.context()遍历所有mock文件
const files = require.context('.', true, /\.js$/)
files.keys().forEach(key => {
  if (key === './index.js') return
  configArray = configArray.concat(files(key).default)
})
// 注册所有的mock服务
configArray.forEach(item => {
  for (let [path, target] of Object.entries(item)) {
    let protocol = path.split('|')
    Mock.mock(protocol[1], protocol[0], target)
    // Mock.mock(new RegExp('^' + protocol[1]), protocol[0], target)
  }
})

/mock/requestA.js

import Mock from 'mockjs'
//requesA.js
const demoList = req => {
  // console.log(req)
  return Mock.mock({
    status: 200,
    message: 'success',
    data: {
      total: 100,
      'rows|10': [
        {
          id: '@guid',
          name: '@cname',
          'age|20-30': 23,
          'job|1': ['前端工程师', '后端工程师', 'UI工程师', '需求工程师']
        }
      ]
    }
  })
}

export default {
  'get|/mock/parameter/query': demoList
}

很明显这样做虽然可以使用Mock,但是ajax请求会被mock拦截导致在network看不到信息,而且切换到真实url需要改地址

2.启一个服务来支持mock

在脚手架中配置/scripts.js

function loadMockServer() {
  if (isTrue(config.mock)) {
    spawn('babel-node', [require.resolve('../util/mock.js')], {
      stdio: 'inherit',
      env: Object.assign({}, process.env, env)
    })
  }
}

switch (script) {
      case 'start':
        loadMockServer()
       .........省略

mock服务/util/mock.js

// import express from "express"
// import Mock from "mockjs"
const http = require('http')
const fs = require('fs');
const path = require('path');
const express = require('express');   //引入express
const Mock = require('mockjs');       //引入mock
const Random = Mock.Random;

let server = register()

fs.watch(path.resolve(process.cwd(), 'mock'), function (event, filename) {
  console.log('event is: ' + event);
  if (filename) {
    console.log('filename provided: ' + filename);
    server.close()
    server = register()
  } else {
    console.log('filename not provided');
  }
});

function register(){
  delete require.cache[path.resolve(process.cwd(), 'mock/index.js')]
  const mockCase = require(path.resolve(process.cwd(), 'mock/index.js'))
  let app = express();
  app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
    res.header("Access-Control-Allow-Headers", "X-Requested-With");
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
  });

  for (const key in mockCase) {
    const [type, url] = key.split('|')
    app.use(url, function (req, res) {
      if(req.method !== type){
        res.json({
          success: false,
          status: {
            RetCode: 99999,
            msg: "请求类型错误"
          },
        })
        return;
      }
      setTimeout(() => {
        res.json(Mock.mock(mockCase[key]))
      }, 500)
    })
  }

  return http.createServer(app).listen(8090);
}

自定义mock数据编写/mock/index.js

const Mock = require('mockjs')
const Random = Mock.Random

const mockCase = {
  'GET|/mock/test': {
    status: {
      RetCode: 0,
      msg: 'success'
    },
    success: true,
    data: {
      total: 10,
      'rows|10': [
        {
          id: '@guid',
          name: '@cname',
          'age|20-30': 24,
          'job|1': ['前端工程师', '后端工程师', 'UI工程师', '需求工程师']
        }
      ]
    }
  },
  'GET|/mock/yunfan': {
    status: {
      RetCode: 0,
      msg: 'success'
    },
    success: true,
    data: {
      total: 10,
      name: 'yunfan',
      'list|10': [
        {
          'name|+1': ['John Brown', 'Jim Green', 'Joe Black', 'Jon Snow'],
          'age|18-70': 70,
          address: Random.region(),
          date: Random.date()
        }
      ]
    }
  }
}

module.exports = mockCase


这里可以在目录在配置不同路由需要的数据 引入到Index中统一抛出
封装下request方法

import { **** } from '***-fetch'

const mock = ******.mock; // 从配置中读,这里演示下
const Index = (type, url, params) => {
  return ****(type, `${mock ? '/mock' : ''}${url}`)(params)
}

export default Index;

配置下proxy

proxy: {
        '/mock': {    
            target: 'http://localhost:8090',  // 接口域名
            secure: false,  
            changeOrigin: true,  
            pathRewrite: {
                '^/mock': ''  
            }              
        }
  }

好了,这样就实现了一个简易的Mock服务,现在可以在network看到我们的mock请求了,并且支持了热更新