THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Browse Source

feature[Mock]: mock-server support hot reload (#1850)

https://github.com/PanJiaChen/vue-element-admin/issues/1849
tags/4.0.1
花裤衩 GitHub 1 year ago
parent
commit
90b7c2fbde
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 98 additions and 32 deletions
  1. +17
    -4
      mock/index.js
  2. +79
    -0
      mock/mock-server.js
  3. +0
    -12
      mock/mocks.js
  4. +1
    -0
      package.json
  5. +1
    -16
      vue.config.js

+ 17
- 4
mock/index.js View File

@@ -1,11 +1,23 @@
import Mock from 'mockjs'
import mocks from './mocks'
import { param2Obj } from '../src/utils'

const MOCK_API_BASE = '/mock'
import user from './user'
import role from './role'
import article from './article'
import search from './remoteSearch'

const mocks = [
...user,
...role,
...article,
...search
]

// for front mock
// please use it cautiously, it will redefine XMLHttpRequest,
// which will cause many of your third-party libraries to be invalidated(like progress event).
export function mockXHR() {
// 修复在使用 MockJS 情况下,设置 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题
// mock patch
// https://github.com/nuysoft/Mock/issues/300
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
Mock.XHR.prototype.send = function() {
@@ -42,9 +54,10 @@ export function mockXHR() {
}
}

// for mock server
const responseFake = (url, type, respond) => {
return {
url: new RegExp(`${MOCK_API_BASE}${url}`),
url: new RegExp(`/mock${url}`),
type: type || 'get',
response(req, res) {
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))


+ 79
- 0
mock/mock-server.js View File

@@ -0,0 +1,79 @@
const chokidar = require('chokidar')
const bodyParser = require('body-parser')
const chalk = require('chalk')

function registerRoutes(app) {
const { default: mocks } = require('./index.js')
for (const mock of mocks) {
app[mock.type](mock.url, mock.response)
}
return {
mockRoutesLength: Object.keys(mocks).length
}
}

function unregisterRoutes() {
Object.keys(require.cache).forEach(i => {
if (i.includes('/mock')) {
delete require.cache[require.resolve(i)]
}
})
}

function getPath(path) {
var match = path.toString()
.replace('\\/?', '')
.replace('(?=\\/|$)', '$')
.match(/^\/\^((?:\\[.*+?^${}()|[\]\\\/]|[^.*+?^${}()|[\]\\\/])*)\$\//)
return match
? match[1].replace(/\\(.)/g, '$1').split('/')
: path.toString()
}

function getMockRoutesIndex(app) {
for (let index = 0; index <= app._router.stack.length; index++) {
const r = app._router.stack[index]
if (r.route && r.route.path) {
const path = getPath(r.route.path)
if (path.includes('mock')) {
return index
}
}
}
}

module.exports = app => {
// es6 polyfill
require('@babel/register')

// parse app.body
// http://expressjs.com/en/4x/api.html#req.body
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))

const { mockRoutesLength } = registerRoutes(app)

// watch files, hot reload mock server
chokidar.watch(('./mock'), {
ignored: 'mock/mock-server.js',
persistent: true,
ignoreInitial: true
}).on('all', (event, path) => {
if (event === 'change' || event === 'add') {
// find mock routes stack index
const index = getMockRoutesIndex(app)

// remove mock routes stack
app._router.stack.splice(index, mockRoutesLength)

// clear routes cache
unregisterRoutes()

registerRoutes(app)

console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
}
})
}

+ 0
- 12
mock/mocks.js View File

@@ -1,12 +0,0 @@
import user from './user'
import role from './role'
import article from './article'
import search from './remoteSearch'

export default [
...user,
...role,
...article,
...search
]


+ 1
- 0
package.json View File

@@ -82,6 +82,7 @@
"babel-eslint": "10.0.1",
"babel-jest": "23.6.0",
"chalk": "2.4.2",
"chokidar": "2.1.5",
"connect": "3.6.6",
"eslint": "5.15.3",
"eslint-plugin-vue": "5.2.2",


+ 1
- 16
vue.config.js View File

@@ -41,22 +41,7 @@ module.exports = {
}
}
},
after(app) {
require('@babel/register')
const bodyParser = require('body-parser')

// parse app.body
// http://expressjs.com/en/4x/api.html#req.body
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))

const { default: mocks } = require('./mock')
for (const mock of mocks) {
app[mock.type](mock.url, mock.response)
}
}
after: require('./mock/mock-server.js')
},
configureWebpack: {
// provide the app's title in webpack's name field, so that


Loading…
Cancel
Save