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上,严格区分斜杠问题,不要随意加,这是个很严禁的问题。
Last modification:December 1st, 2019 at 01:13 am
如果觉得我的文章对你有用,请随意赞赏

Leave a Comment