/** * 用于将前端模块注册到后端服务器 */ const packageJson = require('./package.json'); const { ModuleFederationPlugin } = require('webpack').container; const Server = require('webpack-dev-server'); const mf = require('./webpack.config.mf.cjs'); const fs = require('fs'); const http = require('http'); const https = require('https'); const Json5 =require('json5'); // 解析前端注册器配置文件 const frontendRegisterConfigure = Json5.parse(fs.readFileSync('./frontend-register.json', 'utf8')); // 解析前端路由配置文件 const frontendRoutes =Json5.parse(fs.readFileSync('./src/routes/routes.json', 'utf8')); /** * 远程组件注册器类 */ class RemoteFrontEndModuleRegister { /** * 构造函数,传入配置信息, 包括远程和本地服务器配置信息 * 配置信息定义格式如下: * // 远程服务器配置信息 * remoteServerConfig: { * protocol: 'http', * host: 'localhost', * port: 8080, * path: '/api/system/frontend/regist', * }, * // 本地服务器配置信息 * localServerConfig: { * protocol: devServer.options.server.type, * host: Server.internalIPSync("v4"), * port: devServer.options.port, * path: '/', * } * @param devServer webpack dev server 对象 */ constructor(devServer) { if (!devServer) { throw new Error('webpack-dev-server is not defined'); } this.devServer = devServer; this.registSuccess = null; this.remoteServerConfig = { protocol: frontendRegisterConfigure.protocol, host: frontendRegisterConfigure.host, port: frontendRegisterConfigure.port, path: frontendRegisterConfigure.path, }; this.localServerConfig = { protocol: devServer.options.server.type, host: Server.internalIPSync("v4"), port: devServer.options.port, path: '/', }; } /** * 周期性向服务器注册前端模块 * @param delay 延迟执行(单位:毫秒) * @param interval 固定频率执行(单位:毫秒) */ regist(delay,interval) { if(frontendRegisterConfigure.enable){ setTimeout(() => { let remoteServerUrl = this.remoteServerConfig.protocol + '//' + this.remoteServerConfig.host + ':' + this.remoteServerConfig.port + this.remoteServerConfig.path; console.info('regist frontend module to server --> ' + remoteServerUrl); setInterval(this.doRegist.bind(this), delay); }, delay); } } /** * 向服务器注册前端模块 */ doRegist() { const data = JSON.stringify(this.getRegistJson()); if (data) { let request = this.getRequest(this.remoteServerConfig.protocol); let This = this; request.on('error', error => { if (This.registSuccess == null || This.registSuccess) { This.registSuccess = false; console.error('regist frontend module to server, Failed!', error); } }); request.write(data); request.end(); } } /** * 获取前端模块的注册信息 * @returns 前端模块的注册信息 */ getRegistJson() { return { protocol: this.localServerConfig.protocol, host: this.localServerConfig.host, port: this.localServerConfig.port, contextPath: this.localServerConfig.contextPath, name: packageJson.name, components: this.getComponents(), routes: frontendRoutes, } } /** * 获取前端模块的注册信息(组件集合) * @returns 前端模块的注册信息(组件集合) */ getComponents() { const plugins = mf.plugins; for (let i = 0; i < plugins.length; i++) { const plugin = plugins[i]; if (plugin instanceof ModuleFederationPlugin) { const exposes = plugin._options.exposes; if (exposes) { const components = []; let keyIndex = 0; for (let key in exposes) { components[keyIndex] = key; keyIndex++; } return components; } } } return null; } /** * 获取 http/https 请求 * @param {*} protocol 请求协议 */ getRequest(protocol) { let request = http; if (protocol == 'https:') { request = https; } let This = this; return request.request({ protocol: this.remoteServerConfig.protocol + ":", host: this.remoteServerConfig.host, port: this.remoteServerConfig.port, path: this.remoteServerConfig.path, method: 'POST', headers: { 'Content-Type': 'application/json' } }, request => { request.setEncoding('utf-8'); request.on('data', d => { const data = JSON.parse(d); if (data.code === 200) { if (This.registSuccess == null || !This.registSuccess) { This.registSuccess = true; console.info('regist frontend module to server, Success!'); } } else { console.error('regist frontend module to server, Failed!', d); } }) }); } } module.exports = { RemoteFrontEndModuleRegister }