webpack无感切换代理

212 阅读1分钟

使用webpack切换代理痛点

项目开发过程中,会涉及代理的更换,每次更换代理时,就需要伴随着项目的重启关闭和重新启动,耗时1-2分钟左右

    "/api": {
        target: "https://ke-qa.weizhipin.com/",       // QA环境
        // target: "https://xx.com/",          // 线上环境
        // target: "http://xx:18080",      // 服务端本地ip
        pathRewrite: { "^/api": "" },
        secure: false,
        changeOrigin: true,
    },

希望切换代理时,开发者无需重新启动项目,也就是所谓的无感知切换代理。

实现

前提条件

首先需要知道webpack的proxy中router的用法 router: 重新设置目标代理,并且每次发起请求都会经过此router.

实现思路一(不推荐)

网上方案,采用json的方式:www.jb51.net/article/248…

缺点:每次更改代理麻烦且json有格式要求,不灵活

实现思路二(推荐)

采用js文件引入方式

webpack.utils.js

const path = require('path')
const fs = require('fs')
const chalk = require('chalk')
const getContent = filename => {
    return fs.readFileSync(path.resolve(process.cwd(), filename), { encoding: 'utf-8' })
}

// 获取本地代理
const getProxyTarget = (name) => {
    try {
        const config = getContent('custom/server-proxy.js')
        const parseResult = eval(config)
        let target;
        if (parseResult && parseResult[name] && parseResult[name].target) {
            target = parseResult[name].target
        }
        console.log(`===ServerProxy=== ${chalk.blue(target)}`);
        return target
    } catch (err) {
        console.log(err)
    }
}

webpack.dev.js

import ServerProxy from './xx/custom/server-proxy.js'

devServer: {
      proxy: ServerProxy
},

custom/server-proxy.js

const { getProxyTarget } = require('../scripts/webpack.utils')

module.exports = {
    "/api/other": {
        target: "https://boss-m-qa.weizhipin.com/",       // QA环境
        // target: "https://xx.com/",          // 线上环境
        // target: "http://xx:18080/",               
        router: () => getProxyTarget('/api/other'),
        pathRewrite: { "^/api/other": "" },
        secure: false,
        changeOrigin: true,
    },
    "/api": {
        target: "https://ke-qa.weizhipin.com/",       // QA环境
        // target: "https://xx.com/",          // 线上环境
        // target: "http://xx:18080",                
        router: () => getProxyTarget('/api'),
        pathRewrite: { "^/api": "" },
        secure: false,
        changeOrigin: true,
    },
}

使用时,只需要将对应的target打开,其他target注释掉即可