/**
|
* 前端静态服务器(PM2 托管,对外 :9000)
|
* - 托管 dist 静态资源
|
* - /api/* 转发后端(去掉 /api 前缀)
|
* - /upload/* 转发后端
|
* - /socket.io 转发后端(支持 WebSocket)
|
*/
|
const path = require('path');
|
const express = require('express');
|
const { createProxyMiddleware } = require('http-proxy-middleware');
|
|
const PORT = Number(process.env.PORT || 9000);
|
const BACKEND = process.env.BACKEND || 'http://127.0.0.1:8001';
|
const DIST = path.join(__dirname, 'dist');
|
|
const onErr = (name) => (err, req, res) => {
|
console.error(`[proxy:${name}]`, err && err.message);
|
if (res && res.writeHead) {
|
res.writeHead(502, { 'Content-Type': 'application/json' });
|
res.end(JSON.stringify({ code: 502, msg: `backend unreachable: ${name}` }));
|
}
|
};
|
|
const app = express();
|
|
// 1) 业务接口:/api/admin/xxx -> /admin/xxx
|
app.use(
|
'/api',
|
createProxyMiddleware({
|
target: BACKEND,
|
changeOrigin: true,
|
pathRewrite: { '^/api': '' },
|
ws: false,
|
onError: onErr('api'),
|
})
|
);
|
|
// 2) 上传文件
|
app.use(
|
'/upload',
|
createProxyMiddleware({
|
target: BACKEND,
|
changeOrigin: true,
|
ws: false,
|
onError: onErr('upload'),
|
})
|
);
|
|
// 3) socket.io(含 WebSocket)
|
const socketProxy = createProxyMiddleware({
|
target: BACKEND,
|
changeOrigin: true,
|
ws: true,
|
onError: onErr('socket.io'),
|
});
|
app.use('/socket.io', socketProxy);
|
|
// 4) 前端静态资源
|
app.use(
|
express.static(DIST, {
|
maxAge: '7d',
|
index: 'index.html',
|
setHeaders(res, filePath) {
|
if (filePath.endsWith('index.html')) res.setHeader('Cache-Control', 'no-cache');
|
},
|
})
|
);
|
|
// 5) history 路由兜底(hash 模式不会走到这)
|
// app.get('*', (req, res, next) => {
|
// if (req.path.startsWith('/api') || req.path.startsWith('/upload')) return next();
|
// res.sendFile(path.join(DIST, 'index.html'), (err) => err && next(err));
|
// });
|
app.use((req, res, next) => {
|
if (req.path.startsWith('/api') || req.path.startsWith('/upload')) return next();
|
res.sendFile(path.join(DIST, 'index.html'), (err) => err && next(err));
|
});
|
|
const server = app.listen(PORT, '0.0.0.0', () => {
|
console.log(`[frontend] http://0.0.0.0:${PORT} -> backend ${BACKEND}`);
|
});
|
|
// WebSocket 升级
|
server.on('upgrade', socketProxy.upgrade);
|
|
process.on('unhandledRejection', (r) => console.error('[unhandledRejection]', r && r.message));
|
process.on('uncaughtException', (e) => console.error('[uncaughtException]', e && e.message));
|