对于这个问题,第一反应是在 vue.config.js
中配置 devServer,通过 proxy 代理让流量流向 mockServer。
于是第一时间查看了 vue.config.js
,devServer 配置如下:
devServer: {
port: port,
open: true,
overlay: {
warnings: false,
errors: true
},
before: require('./mock/mock-server.js')
}
出乎意料的是,并没有 proxy。
线索到这儿断了,那么先去看看 .env
是如何配置的吧:
# .env.stage
VUE_APP_BASE_API = '/stage-api'
# .env.development
VUE_APP_BASE_API = '/dev-api'
# .env.production
VUE_APP_BASE_API = '/prod-api'
可见,这里连打包之后的地址都没有指向服务器,那么这个项目打包之后,是怎么找到服务器的呢?
怀着这个问题,在全局搜索 VUE_APP_BASE_API
,找到了下一条线索:
显然,关键在这个 mock-server.js
中,这个时候,再仔细看看 vue.config.js
,发现这里其实用到了 mock-server.js
:
devServer: {
/* ... */
before: require('./mock/mock-server.js')
}
那么我们再回到 mock-server.js
,这里我们关注点来到 module.exports
的方法:
module.exports = app => {
app.use(bodyParser.json())
app.use(
bodyParser.urlencoded({
extended: true
})
)
const mockRoutes = registerRoutes(app)
var mockRoutesLength = mockRoutes.mockRoutesLength
var mockStartIndex = mockRoutes.mockStartIndex
chokidar
.watch(mockDir, {
ignored: /mock-server/,
ignoreInitial: true
})
.on('all', (event, path) => {
if (event === 'change' || event === 'add') {
try {
app._router.stack.splice(mockStartIndex, mockRoutesLength)
unregisterRoutes()
const mockRoutes = registerRoutes(app)
mockRoutesLength = mockRoutes.mockRoutesLength
mockStartIndex = mockRoutes.mockStartIndex
console.log(
chalk.magentaBright(
`\\n > Mock Server hot reload success! changed ${path}`
)
)
} catch (error) {
console.log(chalk.redBright(error))
}
}
})
}
大致分析一下,不难看出,它总共做了三件事:
bodyParser
解析请求registerRoutes
注册了 mockRoutes
chokidar
监听 mock 目录,从而实现 mock-server 的热更新那么核心自然是 registerRoutes
,我们看看它又是怎么做的:
function registerRoutes(app) {
let mockLastIndex
const { mocks } = require('./index.js')
const mocksForServer = mocks.map(route => {
return responseFake(route.url, route.type, route.response)
})
for (const mock of mocksForServer) {
app[mock.type](mock.url, mock.response)
mockLastIndex = app._router.stack.length
}
const mockRoutesLength = Object.keys(mocksForServer).length
return {
mockRoutesLength: mockRoutesLength,
mockStartIndex: mockLastIndex - mockRoutesLength
}
}
可以看到,这里逻辑如下: