前陣子開發專案時,在和後臺聯調時,想透過本地除錯加快效率,這個實現也很簡單,就是修改專案中 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 協議》,轉載必須註明作者和本文連結