UNPKG

env-manage-plugin

Version:

A dev env plugin that integrates an Express server with request proxying capabilities.

191 lines (190 loc) 6.88 kB
"use strict"; var _a; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const express_1 = tslib_1.__importDefault(require("express")); const http_proxy_middleware_1 = require("http-proxy-middleware"); const set_cookie_parser_1 = tslib_1.__importDefault(require("set-cookie-parser")); const libCookie = tslib_1.__importStar(require("cookie")); const Utils_js_1 = tslib_1.__importDefault(require("./Utils.js")); const Config_js_1 = require("./Config.js"); class PreProxyServer { static create(envmConfig) { const { port } = envmConfig; if (this.appMap[port]) { console.log(`端口 ${port} 已经启动`); return null; } return new _a(envmConfig); } constructor(envmConfig) { this.app = (0, express_1.default)(); this.envKey = Utils_js_1.default.getRowKey(envmConfig); this.app.use(this.createPreProxyMiddleware()); this.startServer(envmConfig); } getEnvItem() { const envItem = _a.config.envMap.get(this.envKey); return envItem; } /** * 当前 代理的 cookie 后缀 */ get cookieSuffix() { const envItem = _a.config.envMap.get(this.envKey); return `-${envItem.port}-${_a.configCookieSuffix}`; } /** * 配置的 cookie 后缀 */ static get configCookieSuffix() { return `${_a.config.envmConfig.cookieSuffix}`; } /** * 生成代理中间件 * @returns */ createPreProxyMiddleware() { // 前置转发:将请求转发到 Webpack 开发服务器 return (0, http_proxy_middleware_1.createProxyMiddleware)({ ws: true, changeOrigin: true, router: (req) => { const envItem = _a.config.envMap.get(this.envKey); const devServerKey = Utils_js_1.default.getRowKey({ name: envItem.devServerName, }); const devServerConfig = _a.config.devServerMap.get(devServerKey); // 默认转发到 Webpack 开发服务器 return devServerConfig?.target; }, on: { proxyReq: (proxyReq, req) => { proxyReq.setHeader("X-API-Server", `${req.socket.localPort}`); this._rewrieCookieOnProxyReq(proxyReq, req); }, proxyRes: (proxyRes, req, res) => { this._rewriteSetCookieOnProxyRes(proxyRes); }, proxyReqWs(proxyReq, req, res) { proxyReq.setHeader("X-API-Server", `${req.socket.localPort}`); }, }, }); } /** * 代理的时候如果收到了 setcookie 请求 * 给 每一个 setcookie 追加保存一个 代理cookie * @param proxyRes */ _rewriteSetCookieOnProxyRes(proxyRes) { const envItem = this.getEnvItem(); const setCookie = proxyRes.headers["set-cookie"]; if (envItem.isEnableCookieProxy && setCookie) { const setCookies = set_cookie_parser_1.default.parse(setCookie); const proxyCookie = setCookies.map((item) => { const cookie = { ...item, name: `${item.name}${this.cookieSuffix}`, }; return libCookie.serialize(cookie.name, cookie.value, cookie); }); proxyRes.headers["set-cookie"].push(...proxyCookie); } } /** * 代理 转发的时候,将对应端口的cookie 重写回去 */ _rewrieCookieOnProxyReq(proxyReq, req) { const envItem = this.getEnvItem(); if (envItem.isEnableCookieProxy && req.headers.cookie) { const cookie = libCookie.parse(req.headers.cookie || ""); const newCookies = []; Object.keys(cookie).forEach((item) => { if (item.endsWith(_a.configCookieSuffix)) { return; } let cookieName = `${item}${this.cookieSuffix}`; if (!cookie[cookieName]) { cookieName = item; } newCookies.push(libCookie.serialize(item, cookie[cookieName])); }); proxyReq.setHeader("cookie", newCookies.join(";")); } } /** * 启动服务 * @param envmConfig * @returns */ startServer(envmConfig) { const { port } = envmConfig; if (_a.appMap[port]) { console.log(`端口 ${port} 已经启动`); return; } this.server = this.app.listen(port, () => { console.log(`Server is running on http://localhost:${port}`); _a.config.startServer(this.envKey); }); // 保存所有活动的 socket 连接 this.sockets = new Set(); this.server.on("connection", (socket) => { this.sockets.add(socket); // 保存 socket socket.setTimeout(300000); // 设置超时时间为 5 分钟 socket.on("timeout", () => { socket.destroy(); this.sockets.delete(socket); }); // 监听 socket 关闭事件 socket.on("close", () => { this.sockets.delete(socket); // 从集合中移除已关闭的 socket }); }); _a.appMap[port] = this; } static stopServer(port) { return new Promise((resolve, reject) => { if (!this.appMap[port]) { console.log(`端口 ${port} 未启动`); reject(`端口 【${port}】 未启动`); return; } for (const socket of this.appMap[port].sockets) { socket.destroy(); } this.appMap[port].server.close((err) => { this.config.stopServer(this.appMap[port].envKey); delete this.appMap[port]; console.log(`Server on port ${port} 已关闭`, err || ""); resolve(1); }); }); } /** * 配置文件变更 检查再配置中已经不存在的环境,并关闭改环境 * @param newConfig */ static updateAppMapAfterConfigFileChange() { const envMap = _a.config.envMap; Object.entries(_a.appMap).forEach(([port, item]) => { const rowKey = item.envKey; if (!envMap.has(rowKey)) { _a.stopServer(port); } }); } } _a = PreProxyServer; /** * 保存启动的环境实例 */ PreProxyServer.appMap = {}; PreProxyServer.config = new Config_js_1.Config(); (() => { _a.config.bus.on(Config_js_1.FILE_CHANGE_EVENT, () => { _a.updateAppMapAfterConfigFileChange(); }); })(); exports.default = PreProxyServer;