设计思路
- 封装原则:利用 TypeScript 的类和模块系统,将每个微前端应用的内部数据和逻辑封装在类中,通过访问修饰符(如
private
、protected
)来限制外部对内部数据的直接访问。例如,将敏感数据设为 private
,只暴露必要的公共方法来操作这些数据。
- 通信机制:采用事件总线模式,创建一个全局的事件总线类,各个微前端应用通过注册事件监听器和触发事件来进行通信。这样可以解耦不同微前端之间的直接依赖关系。
- 跨域问题:使用代理服务器来解决跨域问题。在开发环境中,可以使用工具(如 webpack-dev-server 的 proxy 配置)进行代理转发。在生产环境中,配置服务器端(如 Nginx)进行反向代理,将跨域请求转发到目标微前端应用所在的服务器。
- 访问权限问题:在事件总线的基础上,添加权限验证逻辑。例如,在触发事件时,检查当前微前端应用是否具有触发该事件的权限。可以通过在事件注册时,为每个事件绑定权限标识,在触发事件前进行权限检查。
关键代码结构
- 事件总线类
class EventBus {
private events: { [eventName: string]: Array<(data: any) => void> } = {};
// 注册事件监听器
on(eventName: string, callback: (data: any) => void) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
}
// 触发事件
emit(eventName: string, data: any) {
if (this.events[eventName]) {
this.events[eventName].forEach(callback => callback(data));
}
}
}
// 创建全局事件总线实例
const globalEventBus = new EventBus();
- 微前端应用示例
class MicroFrontend {
private internalData: string;
constructor() {
this.internalData = 'private data';
// 注册事件监听器
globalEventBus.on('message-from-other', (data) => {
console.log(`Received message: ${data}`);
});
}
// 暴露公共方法来触发事件
public sendMessageToOther(data: string) {
globalEventBus.emit('message-to-other', data);
}
}
处理跨域和访问权限问题
- 跨域处理
- 开发环境:在
webpack.config.js
中配置 proxy:
module.exports = {
//...其他配置
devServer: {
proxy: {
'/api': {
target: 'http://target - micro - frontend - url',
changeOrigin: true
}
}
}
};
- **生产环境**:在 Nginx 配置文件中添加反向代理规则:
server {
listen 80;
server_name your - domain.com;
location /api {
proxy_pass http://target - micro - frontend - url;
proxy_set_header Host $host;
proxy_set_header X - Real - IP $remote_addr;
proxy_set_header X - Forwarded - For $proxy_add_x_forwarded_for;
proxy_set_header X - Forwarded - Proto $scheme;
}
}
- 访问权限处理
- 权限标识绑定:修改事件总线类,为事件添加权限标识。
class EventBus {
private events: { [eventName: string]: { permission: string, callbacks: Array<(data: any) => void> } } = {};
// 注册事件监听器
on(eventName: string, permission: string, callback: (data: any) => void) {
if (!this.events[eventName]) {
this.events[eventName] = { permission, callbacks: [] };
}
this.events[eventName].callbacks.push(callback);
}
// 触发事件
emit(eventName: string, data: any, currentPermission: string) {
if (this.events[eventName] && this.events[eventName].permission === currentPermission) {
this.events[eventName].callbacks.forEach(callback => callback(data));
}
}
}
// 创建全局事件总线实例
const globalEventBus = new EventBus();
- **权限检查**:在微前端应用中,触发事件前进行权限检查。
class MicroFrontend {
private internalData: string;
private myPermission: string = 'allowed - permission';
constructor() {
this.internalData = 'private data';
// 注册事件监听器
globalEventBus.on('message - from - other', 'allowed - permission', (data) => {
console.log(`Received message: ${data}`);
});
}
// 暴露公共方法来触发事件
public sendMessageToOther(data: string) {
globalEventBus.emit('message - to - other', data, this.myPermission);
}
}