You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

173 lines
5.0 KiB

/**
* 用于将前端模块注册到后端服务器
*/
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
}