0x00 背景
写这个工具的最根本的原因,是因为我司vue2.x项目的逐渐壮大,在与后端联调过程中切换代理每次都需要重启服务,由于项目巨大,每次重新启动都会消耗8-10分钟,效率肉眼可见的低。写这个工具的目的就是为了实现切换代理,而不需要重启项目(就是为了卷)。(别问为什么不使用vite,问就是我司不打算放弃IE)
0x01 摸一摸 webpack-dev-server 的代理
马克思主义告诉我们,认识来源于实践,反作用与实践。所以首先要搞清楚我们原来的代理是怎么实现的。
你以为我要去看源码?不可能的,直接打开webpack的文档配置。
开发服务器使用功能强大的 http-proxy-middleware 软件包。 查看其 documentation 了解更多高级用法。 请注意,
http-proxy-middleware的某些功能不需要target键,例如 它的router功能,但是仍然需要在此处的配置中包含target,否则webpack-dev-server不会将其传递给http-proxy-middleware)
抓住关键字:http-proxy-middleware
0x02 摸一摸 http-proxy-middleware
兴奋的打开了G站,找到了代码:传送门
你以为我要看源码?不可能的,我做为一个无情的API调用工具,怎么可能去看那玩意儿。看看README得了
0x03 如何热重载
热重载不是难题,用chokidar监听文件改变得了,可是要怎么实现删除原来的代理,使用新的代理覆盖。
这里想到了入门vue的时候看的 @panjiachen 大佬的 vue-element-admin,相关链接
这里有一个内容极其小的东西,或许你都没有注意过,我直接 “拿来把你” 。具体文件
注册路由
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
}
}
这是个好东西,这玩意儿基于express,相当于循环加入中间件,然后记录下自己插入的中间件的位置。(如果你不曾了解过express,直接忽略)
清理路由
function unregisterRoutes() {
Object.keys(require.cache).forEach(i => {
if (i.includes(mockDir)) {
delete require.cache[require.resolve(i)]
}
})
}
这里个人感觉不是很精髓,这个清除路由的函数没有体现他的用途,只是清理了require的缓存
#66 app._router.stack.splice(mockStartIndex, mockRoutesLength)
第66行的这条代码才是从真正的删除注册的中间件
0x04 写工具
看完上面的东西,大概就有思路了,接下来就是紧张刺激的写代码的环节。
我就不多在这里BB了,话多了都是水,直接上地址: GitHub传送门
当然,你可能觉得我写的代码很辣鸡~这有问题么?没有问题,我也觉得自己很辣鸡。可以拿来就用。
0x05 拿来就用
npm:
npm install dynamic-proxy --save-dev
yarn
yarn add dynamic-proxy -D
0x06 正确食用方法
1、代理文件
创建自己的代理文件或使用默认的proxy.js(默认的文件要放到你的项目根目录,和package.json),准确的说,这个工具会读取你执行命令行命令所在路径下的proxy.js
文件内容:
module.exports = {
"/api": {
ws: true,
changeOrigin: true,
target: "http://127.0.0.1:8888",
},
};
不能说和原来配置proxy的方式类似吧,这就是一摸一样,你可以直接把你原来的proxyTable直接拿出来。
2、修改devServer配置
vue.config.js or webpack.config.js
// ...
const { useProxy } = require("dynamic-proxy");
module.exports = {
// ...
devServer: {
// ...
after(app) {
useProxy(app); // or useProxy(app, options)
},
},
};
关键点:在after里面使用,移除你原来的proxy字段
更多配置信息请参看项目 README
0x07 写在最后
总结一下?不可能的,没有总结。这个文章的最后只是在乞讨。
各位客官如果食用效果甚佳,还请不吝赐star!
再次提供: GitHub传送门
问:为什么项目名称不是webpack-dynamic-proxy?
答:理论上可以用于任何express项目,不限于webpack