Files

56 lines
2.1 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 極簡靜態伺服器:服務 client/dist(前端 build 產物),並把 /api 代理到後端 :3000
// 用法:node scripts/serve_dist.js [port] (預設 5173
const http = require('http');
const fs = require('fs');
const path = require('path');
const port = parseInt(process.argv[2] || '5173', 10);
const backendPort = parseInt(process.argv[3] || '3000', 10);
const distDir = path.resolve(__dirname, '../client/dist');
const types = {
'.html': 'text/html; charset=utf-8',
'.js': 'application/javascript; charset=utf-8',
'.css': 'text/css; charset=utf-8',
'.json': 'application/json',
'.png': 'image/png',
'.svg': 'image/svg+xml',
'.ico': 'image/x-icon',
'.map': 'application/json'
};
if (!fs.existsSync(distDir)) {
console.error('找不到 client/dist,請先執行 scripts/build_frontend.ps1');
process.exit(1);
}
// /api -> 後端 proxy
function proxyApi(req, res) {
const proxyReq = http.request({
host: 'localhost',
port: backendPort,
path: req.url,
method: req.method,
headers: Object.assign({}, req.headers, { host: 'localhost:' + backendPort })
}, (proxyRes) => {
res.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(res);
});
proxyReq.on('error', (e) => { res.writeHead(502); res.end('Bad Gateway: ' + e.message); });
req.pipe(proxyReq);
}
const server = http.createServer((req, res) => {
if (req.url.startsWith('/api')) { proxyApi(req, res); return; }
let urlPath = decodeURIComponent(req.url.split('?')[0]);
if (urlPath === '/') urlPath = '/index.html';
const filePath = path.join(distDir, urlPath);
if (!filePath.startsWith(distDir)) { res.writeHead(403); res.end('Forbidden'); return; }
if (!fs.existsSync(filePath) || fs.statSync(filePath).isDirectory()) { res.writeHead(404); res.end('Not Found'); return; }
res.writeHead(200, { 'Content-Type': types[path.extname(filePath)] || 'application/octet-stream' });
fs.createReadStream(filePath).pipe(res);
});
server.listen(port, () => {
console.log('靜態伺服器啟動於 http://localhost:' + port + '(服務 client/dist/api 代理至 :' + backendPort + '');
});