vue動態代理無須重啟專案解決方案
1.背景
當我們vue構建專案的時候,都會在vue.config.js
中配置我們需要代理的伺服器地址。有時候我們需要使用不同後端伺服器地址,也就是我們開發中所說的測試環境、灰度環境、正式環境等,這個時候如果我們需要使用不同的環境地址的時候,就需要使用命令或者手動修改vue.config.js
中配置來重新啟動專案。當專案專案越來越大的時候,我們需要很長的時間來啟動專案,如此反覆,極大影響我們開發進度。這個時候我們急需一種vue動態代理無須重啟專案解決方案
來提高我們的開發專案,以此為背景,萌生出了以下方案。
2.技術方案
2.1 舊的配置方案
我們在vue.config.js
中常用的代理方案如下:
js
const port = process.env.port || process.env.npm_config_port || 80 // 埠
module.exports = {
lintOnSave: false,
devServer: {
host: '0.0.0.0',
port,
open: false,
proxy: {
'/my-api': {
target: 'https://www.baidu.com',
ws: false,
changeOrigin: true,
}
}
}
}
在啟動專案的時候,只會讀取一次配置檔案,當再次修改target
地址時,vue-cli
是無法感知檔案的變化,所以代理的還是舊的地址,所以我們需要重新啟動專案來使配置生效。有沒有一種方案,可以在修改配置的時候能使vue-cli
感知到檔案的變化,從而讀取新的配置呢?方案入下:
2.2 新的配置方案思路
vue-cli
的代理是使用的http-proxy-middleware
包,所以proxy
選項的配置也是基於這個包的配置。在proxy
配置選項中有兩個屬性target
以及router
。其中target
是預設的代理地址。而router
可以return一個字串服務地址,那麼當兩個選項都配置了時,http-proxy-middleware
在解析配置時,會首先使用router函式
的返回值,當router的返回值不可以用時,那麼就會fallback至target。
http-proxy-middleware router配置原始碼
配置校驗原始碼
我們可以使用proxy
中router
來讀取我們的代理配置檔案,這樣就可以實現修改代理配置檔案來更新代理地址,無須啟動專案。
3. 配置
在vue.config.js
中加入如下配置:
```js
// vue.config.js
const dynamicProxy = require('./environments/proxy.js')
const port = process.env.port || process.env.npm_config_port || 80 // 埠
module.exports = {
lintOnSave: false,
devServer: {
host: '0.0.0.0',
port,
open: false,
proxy: dynamicProxy.proxy,
disableHostCheck: true
},
}
新建`environments`資料夾,同時在裡面新建`proxy.js`檔案
js
// proxy.js
const fs = require('fs')
const path = require('path')
const encoding = 'utf-8' /* * 獲取配置檔案內容 getContent('proxy-config.json') * @param filename env.json * @returns {string} / 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 + ')')() }
/ * 獲取配置選項 getConfig() * @returns {{}|} / const getConfig = () => { try { return jsonParse(getContent('proxy-config.json')) } catch (e) { return {} } }
module.exports = {
proxy: {
// 介面匹配規則自行修改
['/my-api']: {
target: 'that must have a empty placeholder', // 這裡必須要有字串來進行佔位
changeOrigin: true,
router: () => (getConfig() || {}).target || ''
}
}
}
``
proxy.js最後匯出一個物件,這個物件跟我們以前使用的舊代理方案很像,但是多了一個
router配置,
router函式返回執行
getConfig`函式讀取配置檔案的內容,也就是我們的代理地址。
在environments
目錄下新建我們的代理配置檔案proxy-config.json
:
json
{
"target": "https://www.baidu.com"
}
當專案啟動後,會讀取我們的代理配置檔案。我們在專案啟動後,手動修改代理配置檔案的代理地址,然後重新整理頁面,就可以使我們的新代理地址生效。