环境
我们在日常设计中应当常常会有必须转换不一样自然环境地址的状况。当一个项目代码转换自然环境详细地址时,vue-cli并没有可以认知文档的改变,因此代理或是老旧详细地址,所以通常我们应该实行npm run serve
进行项目重跑,而新项目重跑往往意味着长时间等候,很痛苦!
计划方案调查
实际上,其实大家只是要重新启动webpack给我们启动proxy服务咨询
,或许可以从webpack的服务咨询软件中寻找解决方案。
从webpack官方网站能够看见proxy服务项目其实就是由 http-proxy-middleware所提供的,也许我们可以从中找到解决方案。
初步方案
在http-proxy-middleware配置列表中,除开比较常见的target,也有router。router回到一个字符串数组服务详细地址,当2个选择项都配备了的情形下,会优先使用router函数的返回值,只有在router的传参不能耗时,才能应用target数值。
我们可以利用这一点来重新配置我们自己的项目代码。参照文本文档在这儿
// vue.config.js
const { defineConfig } = require('@vue/cli-service')
const { proxy } = require('./environments/proxy.js')
module.exports = defineConfig({
devServer:{
proxy
},
})
// proxy.js
const fs = require('fs')
const path = require('path')
const encoding = 'utf-8'
const getContent = filename => {
const dir = path.resolve(process.cwd(), 'environments')
return fs.readFileSync(path.resolve(dir, filename), { encoding })
}
const jsonParse = obj => { return Function('"use strict";return (' obj ')')() }
const getConfig = () => { try {
return jsonParse(getContent('proxy-config.json'))
} catch (e) { return {} } }
module.exports = {
proxy: {
// 插口匹配规则自主改动
'/api': {
// 这儿必须有字符串数组去进行团块
// 假如出错Invaild Url,将target改为高效的url字符串数组就可以,如http://localhost:9001
target: 'that must have a empty placeholder',
changeOrigin: true,
router: () => (getConfig() || {}).target || ''
}
}
}
// proxy-config.json
{ "target": "http://localhost:9001" }
此后,在我们必须改动自然环境详细地址时,只需改动proxy-config.json
文档便可以即时起效,无需再npm run serve
!
关键代码分析
完成编码中实际上最关键的就是getContent
用这种方法,大家项目在每一次进行http要求的时候都会启用router里的函数公式
,而getContent往往会根据node的fs服务项目,对于我们的自然环境详细地址文件进行即时载入
,进而偏向大家全新改动的自然环境详细地址。
方案总结
在依照参照文本文档配备了项目代码以后,我们不难发现的确能及时偏向新环境详细地址,再也不用重新启动编码,不需要长期漫长的等待了。可是,大家得多2个必须维修的文档,每一次大家改动自然环境详细地址时,既需要改动config里的api,还要改动proxy-config.json里的target!
有没有可能在只需改动config文档的情形下,完成代理地址动态性改动
呢?
方案优化
从上面的关键代码分析中,能够看见只需大家可以在router函数公式实行时,取得正确config文档中导出来的api属性值,也可以实现相同的实际效果!
这个是不是代表着因为我们在函数中对config文件进行require要求,载入api数值,再return出来就可立即改动代理商偏向了啦?
没有错,你就会发现不管你怎么改动,函数公式内require取过的api始终不会改变,或是服务项目刚运作时的生活环境详细地址。
参照源代码就可以知道,主要是因为我们在使用require要求文件信息时,node会分析出大家传到的字符数组的目标文件夹的相对路径,而且以相对路径为健值,对该文件开展缓存文件
。
因而,如果我们在实行require函数公式时打断点进行观察得话,就会发现require上面还有一个cache缓存文件了早已载入完的文档。
也刚好反映了只需我们可以彻底删除文档保存在require里的缓存文件,咱们就能拿到最新文件信息,那样我们还可以由此得到我们自己的最后改进方案。
// vue.config.js
const hotRequire = modulePath => {
// require.resolve能通过绝对路径获得相对路径
// 以相对路径为健值删掉require里的相匹配文件信息缓存文件
delete require.cache[require.resolve(modulePath)]
// 再次获取文件具体内容
const target = require(modulePath)
return target
}
...
proxy: {
'/api': {
// 假如router合理优先选择取router返回值
target: 'that must have a empty placeholder',
changeOrigin: true,
// 每一次进行http要求都是会实行router函数公式
router: () => (hotRequire('./src/utils/config') || {}).api || '',
ws: true,
pathRewrite: {
'^/api': ''
}
}
}
此后,大家新项目改动自然环境详细地址将没有在必须重新启动新项目,不需要维护保养额外文件夹名称,再也不用痛楚等待了!