1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
const { createProxyMiddleware } = require('http-proxy-middleware');
const logger = require('./logger');
const setupProxyFeature = (app, webpackConfig) => {
if (!Array.isArray(webpackConfig.proxy)) {
if (Object.prototype.hasOwnProperty.call(webpackConfig.proxy, 'target')) {
webpackConfig.proxy = [webpackConfig.proxy];
} else {
webpackConfig.proxy = Object.keys(webpackConfig.proxy).map(context => {
let proxyOptions;
// For backwards compatibility reasons.
const correctedContext = context.replace(/^\*$/, '**').replace(/\/\*$/, '');
if (typeof webpackConfig.proxy[context] === 'string') {
proxyOptions = {
context: correctedContext,
target: webpackConfig.proxy[context],
};
} else {
proxyOptions = Object.assign({}, webpackConfig.proxy[context]);
proxyOptions.context = correctedContext;
}
proxyOptions.logLevel = proxyOptions.logLevel || 'warn';
return proxyOptions;
});
}
}
// eslint-disable-next-line consistent-return
const getProxyMiddleware = proxyConfig => {
const context = proxyConfig.context || proxyConfig.path;
// It is possible to use the `bypass` method without a `target`.
// However, the proxy middleware has no use in this case, and will fail to instantiate.
if (proxyConfig.target) {
return createProxyMiddleware(context, proxyConfig);
}
};
/**
* Assume a proxy configuration specified as:
* proxy: [
* {
* context: ...,
* ...options...
* },
* // or:
* function() {
* return {
* context: ...,
* ...options...
* };
* }
* ]
*/
webpackConfig.proxy.forEach(proxyConfigOrCallback => {
let proxyMiddleware;
let proxyConfig =
typeof proxyConfigOrCallback === 'function' ? proxyConfigOrCallback() : proxyConfigOrCallback;
proxyMiddleware = getProxyMiddleware(proxyConfig);
if (proxyConfig.ws) {
this.websocketProxies.push(proxyMiddleware);
}
// eslint-disable-next-line consistent-return
const handle = (req, res, next) => {
if (typeof proxyConfigOrCallback === 'function') {
const newProxyConfig = proxyConfigOrCallback();
if (newProxyConfig !== proxyConfig) {
proxyConfig = newProxyConfig;
proxyMiddleware = getProxyMiddleware(proxyConfig);
}
}
// - Check if we have a bypass function defined
// - In case the bypass function is defined we'll retrieve the
// bypassUrl from it otherwise bypassUrl would be null
const isByPassFuncDefined = typeof proxyConfig.bypass === 'function';
const bypassUrl = isByPassFuncDefined ? proxyConfig.bypass(req, res, proxyConfig) : null;
if (typeof bypassUrl === 'boolean') {
// skip the proxy
req.url = null;
next();
} else if (typeof bypassUrl === 'string') {
// byPass to that url
req.url = bypassUrl;
next();
} else if (proxyMiddleware) {
return proxyMiddleware(req, res, next);
} else {
next();
}
};
app.use(handle);
// Also forward error requests to the proxy so it can handle them.
app.use((error, req, res, next) => handle(req, res, next));
});
};
const addProxyMiddleware = app => {
if (process.env.PROXY) {
const proxies = process.env.PROXY.split(';');
// 设置代理
setupProxyFeature(app, {
proxy: proxies.map(proxyStr => {
const mathes = proxyStr.match(/^\s*([/\w]+)\s*:\s*(.+)\s*$/);
return {
path: mathes[1],
target: mathes[2],
changeOrigin: true,
};
}),
});
}
};
module.exports = {
addProxyMiddleware,
};