Webpack Proxy 代理使用更好的方式提升开发效率
前阵子开发项目时,在和后台联调时,想通过本地调试加快效率,这个实现也很简单,就是修改项目中 webpack 的配置文件,像 vue-cli3 之前,配置文件在
config/index.js
, vue-cli3 是在根目录vue.config.js
,但不管是 2 还是 3 其实都是配置的一个对象,在 2 中属性叫proxyTable
, 在 3 中属性叫proxy
,值都一样,下面记录一下我的改造方式。
前言
其实这个不仅仅用于 Vue 中,只要使用 webpack 代理 Proxy 解决跨域的地方,皆适用,但目前本站的 webpack 论坛的支持数目还没增加到 100 ,所以暂未开放。
模拟联调
这里假设你需要联调的人员和他们对应的本地服务地址如下:
- 张三
http://192.168.1.101
- 李四
http://192.168.1.102
- 王五
http://192.168.1.103
- ...... 多少人都行
Git忽略本地配置文件
首先在项目的 .gitignore
文件中新增一个忽略项:proxyTarget.js
。
本地配置文件
在根目录新建 proxyTarget.js
,内容如下:
module.exports = {
zhangsanApi: 'http://192.168.1.101:8081',
lisiApi: 'http://192.168.1.101:8081',
wangwuApi: 'http://192.168.1.101:8081',
// ...... 有多少人就配置多少人在这里
}
请注意上面配置的
key
,这个key
将作为 代理 用到的proxyPath
使用,后面再说。
核心代码实现
如果是 vue-cli2 ,位置在 config/index.js
,如果是 vue-cli3 位置在 根目录/vue.config.js
(如果没有新建即可),在文件的最上面新增如下代码:
let target = {};
// 因为这个动态是非必须配置,所以用 `try catch` 做个容错处理。
try {
// 引入动态代理,因为 vue-cli2 和 vue-cli3 位置不同,下面自行调整
// 如果是 vue-cli2 使用下面这行
// target = require('../proxyTarget');
// 如果是 vue-cli3 使用下面这行
target = require('./proxyTarget');
console.log('成功引入proxyTarget', target);
} catch (e) {}
const proxy = {};
const proxyInfo = (path) => {
return {
target: target[path],
changeOrigin: true,
ws: true,
pathRewrite: {
[`^/${path}`]: `/`
}
}
};
// 合并默认代理
target = Object.assign(target, {
devApi: "https://dev.api.com",
prodApi: "https://prpd.api.com"
});
// 将默认和动态的代理组装成webpack需要的Proxy格式
Object.keys(target).forEach(localApiPath => {
proxy[`/${localApiPath}`] = proxyInfo(localApiPath)
});
console.log('最终Proxy结果', proxy)
如果是 vue-cli2 ,修改地方:
module.exports = {
// ...
dev: {
proxyTable: proxy
}
}
如果是 vue-cli3,修改地方:
module.exports = {
// ...
devServer: {
proxy
}
};
通过上面的配置,就等于动态的设置了 N 个 Proxy ,这样的好处有两个:
- 代码保持整洁,哪个前端想和谁调,就到
proxyTarget.js
去动态配置即可。 - 这个动态的配置信息取决于前端和哪些后台联调,这个配置属于动态且本地化,不应该增加到 Git 中,所以前面在一开始就被忽略。
配置 OK 了,下面说下具体的使用。
使用
代理的含义这里不再多说,想必有过经验的都知道,就是当请求以 代理的 proxyPath
开头时,被代理服务转发到目标地址,来解决跨域问题,既然如此,那使用的核心,就是支持动态更新 请求的 proxyPath
即可。
现在常用的就是 http库 大多就是 axios 了,在 axios 设置 baseURL 前,新增如下代码:
import getUrlParam from '@/utils/getUrlParam'
let baseURL = process.env.NODE_ENV !== 'development' ? '/devApi' : '/prodApi'
if (process.env.NODE_ENV === 'development') {
const localApi = getUrlParam('localApi')
console.log('localProxyApi', localApi)
if (localApi && localApi !== 'null') {
baseURL = `/${localApi}`
}
}
axios.defaults.baseURL = baseURL
上面用到了个工具函数 getUrlParam
,位置 src/utils/getUrlParam
没有新建即可,内容如下:
export default function (name) {
let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
let r = window.location.search.substr(1).match(reg)
if (r != null) return unescape(r[2])
return null
}
看到这里,想必已经知道怎么使用这玩意了,哈哈,没错,就是通过 URL 传参数来 动态切换代理。
效果
假设我们项目启动的地址是: http://localhost:8080/#/xxx你的路由
,那么使用方式就是在 #
前面增加一个参数 localApi
,最终的调试地址则是:http://localhost:8080/?localApi=前面定义的proxyPath#/xxx你的路由
。
那么当后台想自己调接口时,使用的最终地址就是如下:
- 张三
http://localhost:8080/?localApi=zhangsanApi#/xxx你的路由
- 李四
http://localhost:8080/?localApi=lisiApi#/xxx你的路由
- 王五
http://localhost:8080/?localApi=wangwuApi#/xxx你的路由
这样前端想和谁调,想和多少人调,就去配置里面都加上就可以了。
注意事项
- 前端和后端需要在一个局域网,两者内网必须互通,你懂得
- 要弄明白你们自己后台本地接口的真实路径,以免代理偏了
- 建议所有后台本地服务的路径都保持一致,避免各种意外问题
- 不管是配置,还是URL上,严格区分斜杠问题,不要随意加,这是个很严禁的问题。
本作品采用《CC 协议》,转载必须注明作者和本文链接