| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- /**
- * @created by pan
- * @updated by helin3 2019-04-08
- * @description Mock Express 热更新注册
- */
- const chokidar = require('chokidar')
- const bodyParser = require('body-parser')
- const chalk = require('chalk')
- const path = require('path')
- const mockDir = path.join(process.cwd(), 'mocks')
- const mockEnable = process.env.VUE_APP_MOCK_ENABLE === 'true' // Mock是否启用
- const mockMode = process.env.VUE_APP_MOCK_MODE === 'true' // 模拟模式,true真实express服务,false XHR拦截方式
- /**
- * 通过express 路由方式注册mocks api
- * @param {*} app express实例
- * @returns {object}
- * mockStartIndex mock路由开始索引位置
- * mockRoutesLength 路由长度mocks api
- */
- function registerRoutes(app) {
- let mockLastIndex
- // 读取注册路由
- const { default: mocks } = require('./index.js')
- console.log('\n Mocks Server Register Routes : \n')
- for (const mock of mocks) {
- let url = mock.url ? (mock.url.source || mock.url): ''
- url = url.replace(/\\\//g, '/')
- console.log(' - ' + mock.type + ' - ' + url)
- app[mock.type](mock.url, mock.response)
- }
- mockLastIndex = app._router.stack.length
- const mockRoutesLength = Object.keys(mocks).length
- return {
- mockStartIndex: mockLastIndex - mockRoutesLength,
- mockRoutesLength: Object.keys(mocks).length
- }
- }
- /**
- * 清除/mocks目录require缓存
- * TODO: 待调试
- */
- function unregisterRoutes() {
- Object.keys(require.cache).forEach(i => {
- // 清除/mocks目录require缓存
- if (i.includes(mockDir)) {
- delete require.cache[require.resolve(i)]
- }
- })
- }
- module.exports = app => {
- // es6 polyfill
- require('@babel/register')
- // Mock启用,则在开发模式添加mock api拦截
- // 此处必须得是字符串方式判断,因其不在浏览器中
- if (!mockEnable || !mockMode) {
- return
- }
- // 开发模式,没有统一前缀,如何区分API是Mock服务
- app.all('*', function(req, res, next) {
- res.header("X-Mock-Api", "xyMock")
- next()
- })
- // parse app.body
- // https://expressjs.com/en/4x/api.html#req.body
- app.use(bodyParser.json())
- app.use(bodyParser.urlencoded({
- extended: true
- }))
-
- let lastRegReturn = registerRoutes(app)
- let mockRoutesLength = lastRegReturn.mockRoutesLength
- let mockStartIndex = lastRegReturn.mockStartIndex
- // 监听/mocks文件(忽略/mocks/mocks-server.js),热加载Mocks Server
- chokidar.watch(mockDir, {
- ignored: /mocks-server/,
- ignoreInitial: true
- }).on('all', (event, path) => {
- if (event === 'change' || event === 'add') {
- // 移除 mock api Express路由堆栈
- app._router.stack.splice(mockStartIndex, mockRoutesLength)
- // 清除路由文件缓存
- unregisterRoutes()
- // 重新注册Mocks api路由
- lastRegReturn = registerRoutes(app)
- mockRoutesLength = lastRegReturn.mockRoutesLength
- mockStartIndex = lastRegReturn.mockStartIndex
-
- console.log(chalk.magentaBright(`\n > Mocks Server hot reload success! changed ${path}`))
- }
- })
- }
|