Webpack Proxy 代理使用更好的方式提升開發效率

yaimeet發表於2019-09-06

前陣子開發專案時,在和後臺聯調時,想透過本地除錯加快效率,這個實現也很簡單,就是修改專案中 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 協議》,轉載必須註明作者和本文連結
如有不對之處,還請不吝指出,非常感謝。

相關文章