提早配置多个API代理目标, 在开发环境下可快速切换API代理目标.javascript
(鼠标移至前端界面右下角位置, 输入预先配置的目标来切换API代理) css
基于你项目的HTML模板文件, 复制一份出来, 加上style
, span#current-env
, input#modify-proxy
, script
. 样式及形式可随意修改, 反正是dev环境_(:з」∠)_html
/templates/dev.html
前端
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1" >
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="format-detection" content="telephone=no"/>
<link rel="icon" href="/static/build/logo-mini.png" type="image/x-icon">
<title>Title</title>
<style> #modify-proxy { position: fixed; width: 150px; right: -149px; bottom: 12px; } #current-env { position: fixed; right: 10px; bottom: 13px; opacity: 0.2; pointer-events: none; } #modify-proxy:hover, #modify-proxy:focus { right: 0; } </style>
</head>
<body>
<div id="app"></div>
<span id="current-env"></span>
<input id="modify-proxy" placeholder="修改代理" onchange="changeProxy(this)"/>
<script> document.getElementById('modify-proxy').value = window.localStorage.getItem('proxy').slice(1) document.getElementById('current-env').innerHTML = 'API 环境: ' + (window.localStorage.getItem('proxy').slice(1) || '默认') function changeProxy(el) { var value = el.value.trim() window.localStorage.setItem('proxy', value ? ('/' + value) : '') document.getElementById('current-env').innerHTML = 'API 环境: ' + (value || '默认') } </script>
</body>
</html>
复制代码
修改webpack配置文件. HtmlPlugin配置, 开发环境使用咱们刚刚写的dev.html
模板:java
const isProduction = process.env.mode && process.env.mode.trim() === 'production'
// ...
{
plugins: [
/* ... other plugins */
new HtmlPlugin({
title: 'Demo',
filename: 'index.html',
template: path.join(__dirname, 'src', isProduction ? 'templates/default.html' : 'templates/dev.html'), // 看这里!
chunks: ['index', 'manifest'],
hash: false,
}),
/* ... other plugins */
]
}
复制代码
新建 proxy-config.js
文件, 提早配置多个API代理目标:webpack
const proxyTargets = [
{
targetName: 'dev',
target: 'https://dev-xxx.xxx.com',
},
{
targetName: 'test',
target: 'https://test-xxx.xxx.com',
baseURL: '/api-manage',
},
{
targetName: 'caspian',
target: 'http://192.168.5.39:9003',
},
{
targetName: '小明',
target: 'http://192.168.5.116:9003',
},
{
targetName: '小红',
target: 'http://192.168.5.117:9003',
},
]
const proxies = {}
const BASE_URL = process.env.BASE_URL || ''
proxyTargets.forEach((proxyTarget) => {
proxies[`/${proxyTarget.targetName}${BASE_URL}`] = {
target: proxyTarget.target,
pathRewrite: { [`/${proxyTarget.targetName}${BASE_URL}`]: proxyTarget.baseURL || BASE_URL || '' },
changeOrigin: true,
toProxy: false,
prependPath: false,
}
})
module.exports = proxies
复制代码
修改WebpackDevServer的启动文件:web
const path = require('path')
const WebpackDevServer = require('webpack-dev-server')
const webpack = require('webpack')
const config = require('./webpack.config.js')
const proxies = require('./proxy-config') // 引入代理配置文件
const devPort = process.env.port
const options = {
hot: true,
historyApiFallback: true,
contentBase: path.join(__dirname, './'),
compress: false,
disableHostCheck: true,
host: '0.0.0.0', // 容许经过其余ip访问
proxy: Object.assign(proxies, { // !!!把配置扔这里, 顺便给个默认代理
'/**': {
target: 'https://default-xxx.com',
changeOrigin: true,
toProxy: false,
prependPath: false,
secure: false, // 接受 运行在 https 上的服务
},
}),
}
WebpackDevServer.addDevServerEntrypoints(config, options)
const compiler = webpack(config)
const server = new WebpackDevServer(compiler, options)
server.listen(devPort, '0.0.0.0', () => {
global.console.log(`dev server listening on port ${devPort}`)
})
复制代码
utils.js 在本身的工具库上加上getBaseURL
方法:chrome
const baseUrl = process.env.BASE_URL || ''
const isProduction = process.env.mode && process.env.mode.trim() === 'production'
getBaseURL() {
if (isProduction) {
return baseUrl
}
const proxy = window.localStorage.getItem('proxy') || ''
return proxy + baseUrl
}
复制代码
在本身所用的HTTP请求工具类上改动, 在 URL 前加上getBaseURL()
:api
async request(_url: string, options = {}) {
const url = utils.getBaseURL() + _url // 加上getBaseURL()
let fetchOptions = Object.assign(fetchOptions, this.defaultOptions, options)
const res = await fetch(url, fetchOptions)
}
复制代码
完成!app
不适用于全部的项目及团队开发模式, 这里只是分享一下本身在项目实践上的一些小技巧, 但愿对你有所帮助!