前端微前端架构深度实践:从单体应用到微前端的完整架构解决方案
·
在现代前端开发中,随着应用规模的不断扩大和团队的增长,传统的单体前端架构逐渐暴露出维护困难、部署复杂、技术栈固化等问题。微前端架构作为一种新兴的架构模式,为大型前端应用提供了更好的可扩展性、可维护性和团队协作能力。本文将深入探讨微前端架构的设计原理、实现方案和最佳实践。
目录
1. 微前端架构概述
1.1 微前端核心概念
微前端是一种将大型前端应用拆分为多个小型、独立的前端应用的架构模式。每个微前端应用可以独立开发、测试、部署和运行。
// 微前端架构管理器
class MicrofrontendArchitecture {
constructor() {
this.applications = new Map();
this.router = null;
this.eventBus = null;
this.sharedDependencies = new Map();
this.config = {
mode: 'spa', // spa, mpa, iframe
isolation: 'js-sandbox', // js-sandbox, css-sandbox, iframe
communication: 'event-bus', // event-bus, props, custom-events
routing: 'browser-router', // browser-router, hash-router, memory-router
loading: 'lazy', // lazy, eager, preload
errorHandling: 'boundary' // boundary, global, custom
};
this.lifecycle = {
beforeMount: [],
mounted: [],
beforeUnmount: [],
unmounted: [],
error: []
};
this.performance = {
loadTime: new Map(),
bundleSize: new Map(),
memoryUsage: new Map(),
renderTime: new Map()
};
this.initializeArchitecture();
}
// 初始化架构
initializeArchitecture() {
this.setupRouter();
this.setupEventBus();
this.setupErrorHandling();
this.setupPerformanceMonitoring();
this.setupSharedDependencies();
}
// 注册微前端应用
registerApplication(config) {
const application = {
name: config.name,
entry: config.entry,
container: config.container,
activeWhen: config.activeWhen,
props: config.props || {},
lifecycle: {
bootstrap: config.bootstrap,
mount: config.mount,
unmount: config.unmount,
update: config.update
},
status: 'NOT_LOADED', // NOT_LOADED, LOADING, LOADED, MOUNTING, MOUNTED, UNMOUNTING
instance: null,
assets: {
js: [],
css: [],
html: ''
},
sandbox: null,
errorBoundary: null
};
// 验证应用配置
this.validateApplicationConfig(application);
// 设置应用沙箱
if (this.config.isolation === 'js-sandbox') {
application.sandbox = this.createJSSandbox(application.name);
}
// 设置错误边界
if (this.config.errorHandling === 'boundary') {
application.errorBoundary = this.createErrorBoundary(application.name);
}
this.applications.set(config.name, application);
// 触发注册事件
this.eventBus.emit('application:registered', {
name: config.name,
config: application
});
return application;
}
// 验证应用配置
validateApplicationConfig(application) {
const required = ['name', 'entry', 'container', 'activeWhen'];
const missing = required.filter(field => !application[field]);
if (missing.length > 0) {
throw new Error(`微前端应用配置缺少必需字段: ${missing.join(', ')}`);
}
// 验证生命周期函数
const lifecycleMethods = ['bootstrap', 'mount', 'unmount'];
const missingLifecycle = lifecycleMethods.filter(
method => typeof application.lifecycle[method] !== 'function'
);
if (missingLifecycle.length > 0) {
throw new Error(`微前端应用缺少生命周期方法: ${missingLifecycle.join(', ')}`);
}
// 验证容器元素
if (typeof application.container === 'string') {
const container = document.querySelector(application.container);
if (!container) {
throw new Error(`找不到容器元素: ${application.container}`);
}
}
}
// 加载应用
async loadApplication(name) {
const application = this.applications.get(name);
if (!application) {
throw new Error(`未找到应用: ${name}`);
}
if (application.status !== 'NOT_LOADED') {
return application;
}
try {
application.status = 'LOADING';
// 记录加载开始时间
const loadStartTime = performance.now();
// 加载应用资源
await this.loadApplicationAssets(application);
// 执行bootstrap生命周期
if (application.lifecycle.bootstrap) {
await application.lifecycle.bootstrap(application.props);
}
application.status = 'LOADED';
// 记录加载时间
const loadTime = performance.now() - loadStartTime;
this.performance.loadTime.set(name, loadTime);
// 触发加载完成事件
this.eventBus.emit('application:loaded', {
name,
loadTime,
application
});
return application;
} catch (error) {
application.status = 'LOAD_ERROR';
this.handleApplicationError(name, 'load', error);
throw error;
}
}
// 加载应用资源
async loadApplicationAssets(application) {
const { entry } = application;
if (typeof entry === 'string') {
// 单一入口点
const assets = await this.fetchApplicationAssets(entry);
application.assets = assets;
} else if (typeof entry === 'object') {
// 多个资源文件
const assets = {
js: entry.js || [],
css: entry.css || [],
html: entry.html || ''
};
// 并行加载所有资源
await Promise.all([
...assets.js.map(js => this.loadScript(js)),
...assets.css.map(css => this.loadStylesheet(css))
]);
if (assets.html) {
assets.html = await this.fetchHTML(assets.html);
}
application.assets = assets;
}
}
// 获取应用资源
async fetchApplicationAssets(entry) {
try {
const response = await fetch(entry);
const html = await response.text();
// 解析HTML中的资源链接
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const assets = {
js: [],
css: [],
html: html
};
// 提取JavaScript文件
const scripts = doc.querySelectorAll('script[src]');
scripts.forEach(script => {
const src = script.getAttribute('src');
if (src && !src.startsWith('http')) {
assets.js.push(new URL(src, entry).href);
} else if (src) {
assets.js.push(src);
}
});
// 提取CSS文件
const links = doc.querySelectorAll('link[rel="stylesheet"]');
links.forEach(link => {
const href = link.getAttribute('href');
if (href && !href.startsWith('http')) {
assets.css.push(new URL(href, entry).href);
} else if (href) {
assets.css.push(href);
}
});
return assets;
} catch (error) {
throw new Error(`加载应用资源失败: ${entry} - ${error.message}`);
}
}
// 挂载应用
async mountApplication(name, props = {}) {
const application = this.applications.get(name);
if (!application) {
throw new Error(`未找到应用: ${name}`);
}
if (application.status === 'MOUNTED') {
return application;
}
try {
// 确保应用已加载
if (application.status !== 'LOADED') {
await this.loadApplication(name);
}
application.status = 'MOUNTING';
// 记录挂载开始时间
const mountStartTime = performance.now();
// 准备容器
const container = this.prepareContainer(application);
// 设置沙箱环境
if (application.sandbox) {
application.sandbox.activate();
}
// 合并props
const finalProps = {
...application.props,
...props,
container,
name: application.name,
eventBus: this.eventBus
};
// 执行mount生命周期
application.instance = await application.lifecycle.mount(finalProps);
application.status = 'MOUNTED';
// 记录挂载时间
const mountTime = performance.now() - mountStartTime;
this.performance.renderTime.set(name, mountTime);
// 触发挂载完成事件
this.eventBus.emit('application:mounted', {
name,
mountTime,
application
});
return application;
} catch (error) {
application.status = 'MOUNT_ERROR';
this.handleApplicationError(name, 'mount', error);
throw error;
}
}
// 卸载应用
async unmountApplication(name) {
const application = this.applications.get(name);
if (!application) {
throw new Error(`未找到应用: ${name}`);
}
if (application.status !== 'MOUNTED') {
return application;
}
try {
application.status = 'UNMOUNTING';
// 执行unmount生命周期
if (application.lifecycle.unmount) {
await application.lifecycle.unmount({
container: application.container,
instance: application.instance
});
}
// 清理容器
this.cleanupContainer(application);
// 停用沙箱
if (application.sandbox) {
application.sandbox.deactivate();
}
application.status = 'LOADED';
application.instance = null;
// 触发卸载完成事件
this.eventBus.emit('application:unmounted', {
name,
application
});
return application;
} catch (error) {
application.status = 'UNMOUNT_ERROR';
this.handleApplicationError(name, 'unmount', error);
throw error;
}
}
// 准备容器
prepareContainer(application) {
let container;
if (typeof application.container === 'string') {
container = document.querySelector(application.container);
} else {
container = application.container;
}
if (!container) {
throw new Error(`找不到容器元素: ${application.container}`);
}
// 清空容器
container.innerHTML = '';
// 设置容器属性
container.setAttribute('data-micro-app', application.name);
container.setAttribute('data-micro-status', application.status);
return container;
}
// 清理容器
cleanupContainer(application) {
let container;
if (typeof application.container === 'string') {
container = document.querySelector(application.container);
} else {
container = application.container;
}
if (container) {
container.innerHTML = '';
container.removeAttribute('data-micro-app');
container.removeAttribute('data-micro-status');
}
}
// 设置路由
setupRouter() {
this.router = new MicrofrontendRouter({
mode: this.config.routing,
applications: this.applications
});
// 监听路由变化
this.router.onRouteChange(async (route) => {
await this.handleRouteChange(route);
});
}
// 处理路由变化
async handleRouteChange(route) {
const { pathname, search, hash } = route;
const currentPath = pathname + search + hash;
// 找到需要激活的应用
const applicationsToMount = [];
const applicationsToUnmount = [];
for (const [name, application] of this.applications) {
const shouldBeActive = this.shouldApplicationBeActive(application, currentPath);
const isActive = application.status === 'MOUNTED';
if (shouldBeActive && !isActive) {
applicationsToMount.push(name);
} else if (!shouldBeActive && isActive) {
applicationsToUnmount.push(name);
}
}
// 先卸载不需要的应用
await Promise.all(
applicationsToUnmount.map(name => this.unmountApplication(name))
);
// 再挂载需要的应用
await Promise.all(
applicationsToMount.map(name => this.mountApplication(name))
);
}
// 判断应用是否应该激活
shouldApplicationBeActive(application, path) {
const { activeWhen } = application;
if (typeof activeWhen === 'string') {
return path.startsWith(activeWhen);
} else if (typeof activeWhen === 'function') {
return activeWhen(path);
} else if (activeWhen instanceof RegExp) {
return activeWhen.test(path);
} else if (Array.isArray(activeWhen)) {
return activeWhen.some(rule => {
if (typeof rule === 'string') {
return path.startsWith(rule);
} else if (rule instanceof RegExp) {
return rule.test(path);
}
return false;
});
}
return false;
}
// 设置事件总线
setupEventBus() {
this.eventBus = new MicrofrontendEventBus();
// 设置全局事件总线
window.__MICROFRONTEND_EVENT_BUS__ = this.eventBus;
}
// 设置错误处理
setupErrorHandling() {
// 全局错误处理
window.addEventListener('error', (event) => {
this.handleGlobalError(event.error);
});
window.addEventListener('unhandledrejection', (event) => {
this.handleGlobalError(event.reason);
});
}
// 处理应用错误
handleApplicationError(appName, phase, error) {
console.error(`微前端应用 ${appName} 在 ${phase} 阶段发生错误:`, error);
// 触发错误事件
this.eventBus.emit('application:error', {
name: appName,
phase,
error,
timestamp: Date.now()
});
// 执行错误处理回调
this.lifecycle.error.forEach(callback => {
try {
callback({ appName, phase, error });
} catch (callbackError) {
console.error('错误处理回调执行失败:', callbackError);
}
});
}
// 处理全局错误
handleGlobalError(error) {
console.error('微前端架构全局错误:', error);
// 尝试识别错误来源
const appName = this.identifyErrorSource(error);
if (appName) {
this.handleApplicationError(appName, 'runtime', error);
} else {
// 触发全局错误事件
this.eventBus.emit('global:error', {
error,
timestamp: Date.now()
});
}
}
// 识别错误来源
identifyErrorSource(error) {
// 通过错误堆栈或其他信息识别错误来源的应用
if (error.stack) {
for (const [name, application] of this.applications) {
if (application.status === 'MOUNTED' &&
error.stack.includes(name)) {
return name;
}
}
}
return null;
}
// 设置性能监控
setupPerformanceMonitoring() {
// 监控内存使用
if (performance.memory) {
setInterval(() => {
for (const [name, application] of this.applications) {
if (application.status === 'MOUNTED') {
this.performance.memoryUsage.set(name, {
used: performance.memory.usedJSHeapSize,
total: performance.memory.totalJSHeapSize,
limit: performance.memory.jsHeapSizeLimit,
timestamp: Date.now()
});
}
}
}, 5000);
}
// 监控bundle大小
this.monitorBundleSize();
}
// 监控bundle大小
monitorBundleSize() {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.entryType === 'resource' &&
(entry.name.endsWith('.js') || entry.name.endsWith('.css'))) {
// 尝试匹配到对应的应用
for (const [name, application] of this.applications) {
if (application.assets.js.includes(entry.name) ||
application.assets.css.includes(entry.name)) {
const currentSize = this.performance.bundleSize.get(name) || 0;
this.performance.bundleSize.set(name, currentSize + entry.transferSize);
break;
}
}
}
}
});
observer.observe({ entryTypes: ['resource'] });
}
// 设置共享依赖
setupSharedDependencies() {
// 设置全局共享依赖
window.__MICROFRONTEND_SHARED__ = this.sharedDependencies;
// 注册常用共享依赖
this.registerSharedDependency('react', window.React);
this.registerSharedDependency('react-dom', window.ReactDOM);
this.registerSharedDependency('lodash', window._);
}
// 注册共享依赖
registerSharedDependency(name, dependency) {
this.sharedDependencies.set(name, dependency);
// 触发共享依赖注册事件
this.eventBus.emit('shared:registered', {
name,
dependency
});
}
// 获取共享依赖
getSharedDependency(name) {
return this.sharedDependencies.get(name);
}
// 加载脚本
loadScript(src) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
}
// 加载样式表
loadStylesheet(href) {
return new Promise((resolve, reject) => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = href;
link.onload = resolve;
link.onerror = reject;
document.head.appendChild(link);
});
}
// 获取HTML
async fetchHTML(url) {
const response = await fetch(url);
return await response.text();
}
// 获取应用状态
getApplicationStatus(name) {
const application = this.applications.get(name);
return application ? application.status : null;
}
// 获取所有应用
getAllApplications() {
return Array.from(this.applications.values());
}
// 获取活跃应用
getActiveApplications() {
return Array.from(this.applications.values())
.filter(app => app.status === 'MOUNTED');
}
// 获取性能指标
getPerformanceMetrics() {
return {
loadTime: Object.fromEntries(this.performance.loadTime),
bundleSize: Object.fromEntries(this.performance.bundleSize),
memoryUsage: Object.fromEntries(this.performance.memoryUsage),
renderTime: Object.fromEntries(this.performance.renderTime)
};
}
// 销毁架构
destroy() {
// 卸载所有应用
const activeApps = this.getActiveApplications();
Promise.all(
activeApps.map(app => this.unmountApplication(app.name))
);
// 清理事件监听
if (this.router) {
this.router.destroy();
}
if (this.eventBus) {
this.eventBus.destroy();
}
// 清理全局变量
delete window.__MICROFRONTEND_EVENT_BUS__;
delete window.__MICROFRONTEND_SHARED__;
// 清理数据
this.applications.clear();
this.sharedDependencies.clear();
}
}
1.2 微前端路由管理
// 微前端路由管理器
class MicrofrontendRouter {
constructor(options = {}) {
this.mode = options.mode || 'browser-router';
this.applications = options.applications || new Map();
this.routes = new Map();
this.currentRoute = null;
this.listeners = [];
this.history = [];
this.maxHistoryLength = 50;
this.initializeRouter();
}
// 初始化路由
initializeRouter() {
switch (this.mode) {
case 'browser-router':
this.setupBrowserRouter();
break;
case 'hash-router':
this.setupHashRouter();
break;
case 'memory-router':
this.setupMemoryRouter();
break;
default:
throw new Error(`不支持的路由模式: ${this.mode}`);
}
// 初始化当前路由
this.updateCurrentRoute();
}
// 设置浏览器路由
setupBrowserRouter() {
// 监听popstate事件
window.addEventListener('popstate', (event) => {
this.updateCurrentRoute();
this.notifyRouteChange();
});
// 拦截pushState和replaceState
this.interceptHistoryMethods();
}
// 设置Hash路由
setupHashRouter() {
window.addEventListener('hashchange', (event) => {
this.updateCurrentRoute();
this.notifyRouteChange();
});
}
// 设置内存路由
setupMemoryRouter() {
this.memoryHistory = ['/'];
this.memoryIndex = 0;
}
// 拦截History方法
interceptHistoryMethods() {
const originalPushState = history.pushState;
const originalReplaceState = history.replaceState;
history.pushState = (...args) => {
originalPushState.apply(history, args);
this.updateCurrentRoute();
this.notifyRouteChange();
};
history.replaceState = (...args) => {
originalReplaceState.apply(history, args);
this.updateCurrentRoute();
this.notifyRouteChange();
};
}
// 更新当前路由
updateCurrentRoute() {
let pathname, search, hash;
switch (this.mode) {
case 'browser-router':
pathname = location.pathname;
search = location.search;
hash = location.hash;
break;
case 'hash-router':
const hashPath = location.hash.slice(1) || '/';
const [hashPathname, hashSearch] = hashPath.split('?');
pathname = hashPathname;
search = hashSearch ? `?${hashSearch}` : '';
hash = '';
break;
case 'memory-router':
const memoryPath = this.memoryHistory[this.memoryIndex] || '/';
const [memoryPathname, memorySearch] = memoryPath.split('?');
pathname = memoryPathname;
search = memorySearch ? `?${memorySearch}` : '';
hash = '';
break;
}
const newRoute = {
pathname,
search,
hash,
fullPath: pathname + search + hash,
query: this.parseQuery(search),
params: {},
meta: {},
timestamp: Date.now()
};
// 添加到历史记录
if (this.currentRoute &&
this.currentRoute.fullPath !== newRoute.fullPath) {
this.addToHistory(this.currentRoute);
}
this.currentRoute = newRoute;
}
// 解析查询参数
parseQuery(search) {
const query = {};
if (search) {
const params = new URLSearchParams(search);
for (const [key, value] of params) {
query[key] = value;
}
}
return query;
}
// 添加到历史记录
addToHistory(route) {
this.history.unshift(route);
if (this.history.length > this.maxHistoryLength) {
this.history = this.history.slice(0, this.maxHistoryLength);
}
}
// 通知路由变化
notifyRouteChange() {
this.listeners.forEach(listener => {
try {
listener(this.currentRoute);
} catch (error) {
console.error('路由监听器执行错误:', error);
}
});
}
// 监听路由变化
onRouteChange(listener) {
this.listeners.push(listener);
// 返回取消监听的函数
return () => {
const index = this.listeners.indexOf(listener);
if (index > -1) {
this.listeners.splice(index, 1);
}
};
}
// 导航到指定路径
navigate(path, options = {}) {
const { replace = false, state = null } = options;
switch (this.mode) {
case 'browser-router':
if (replace) {
history.replaceState(state, '', path);
} else {
history.pushState(state, '', path);
}
break;
case 'hash-router':
if (replace) {
location.replace(`#${path}`);
} else {
location.hash = path;
}
break;
case 'memory-router':
if (replace) {
this.memoryHistory[this.memoryIndex] = path;
} else {
this.memoryIndex++;
this.memoryHistory = this.memoryHistory.slice(0, this.memoryIndex);
this.memoryHistory.push(path);
}
this.updateCurrentRoute();
this.notifyRouteChange();
break;
}
}
// 后退
goBack() {
switch (this.mode) {
case 'browser-router':
case 'hash-router':
history.back();
break;
case 'memory-router':
if (this.memoryIndex > 0) {
this.memoryIndex--;
this.updateCurrentRoute();
this.notifyRouteChange();
}
break;
}
}
// 前进
goForward() {
switch (this.mode) {
case 'browser-router':
case 'hash-router':
history.forward();
break;
case 'memory-router':
if (this.memoryIndex < this.memoryHistory.length - 1) {
this.memoryIndex++;
this.updateCurrentRoute();
this.notifyRouteChange();
}
break;
}
}
// 注册路由
registerRoute(pattern, config) {
this.routes.set(pattern, {
pattern,
...config,
regex: this.patternToRegex(pattern)
});
}
// 模式转正则
patternToRegex(pattern) {
// 简单的路径模式转换
const regexPattern = pattern
.replace(/\//g, '\\/')
.replace(/:\w+/g, '([^/]+)')
.replace(/\*/g, '.*');
return new RegExp(`^${regexPattern}$`);
}
// 匹配路由
matchRoute(path) {
for (const [pattern, route] of this.routes) {
const match = path.match(route.regex);
if (match) {
// 提取参数
const params = {};
const paramNames = pattern.match(/:\w+/g) || [];
paramNames.forEach((param, index) => {
const paramName = param.slice(1);
params[paramName] = match[index + 1];
});
return {
...route,
params,
match
};
}
}
return null;
}
// 获取当前路由
getCurrentRoute() {
return this.currentRoute;
}
// 获取历史记录
getHistory() {
return [...this.history];
}
// 销毁路由器
destroy() {
this.listeners = [];
this.routes.clear();
this.history = [];
}
}
1.3 事件总线系统
// 微前端事件总线
class MicrofrontendEventBus {
constructor() {
this.events = new Map();
this.middlewares = [];
this.history = [];
this.maxHistoryLength = 100;
this.debugMode = false;
this.setupGlobalEventBus();
}
// 设置全局事件总线
setupGlobalEventBus() {
// 监听原生事件
window.addEventListener('message', (event) => {
if (event.data && event.data.type === 'MICROFRONTEND_EVENT') {
this.handleCrossOriginEvent(event.data);
}
});
}
// 订阅事件
on(eventName, listener, options = {}) {
const { once = false, priority = 0, namespace = 'default' } = options;
if (!this.events.has(eventName)) {
this.events.set(eventName, []);
}
const listenerWrapper = {
listener,
once,
priority,
namespace,
id: this.generateListenerId(),
createdAt: Date.now()
};
const listeners = this.events.get(eventName);
listeners.push(listenerWrapper);
// 按优先级排序
listeners.sort((a, b) => b.priority - a.priority);
if (this.debugMode) {
console.log(`事件监听器已注册: ${eventName}`, listenerWrapper);
}
// 返回取消订阅函数
return () => this.off(eventName, listenerWrapper.id);
}
// 取消订阅
off(eventName, listenerId) {
if (!this.events.has(eventName)) {
return false;
}
const listeners = this.events.get(eventName);
const index = listeners.findIndex(l => l.id === listenerId);
if (index > -1) {
listeners.splice(index, 1);
if (listeners.length === 0) {
this.events.delete(eventName);
}
if (this.debugMode) {
console.log(`事件监听器已移除: ${eventName}`, listenerId);
}
return true;
}
return false;
}
// 发布事件
emit(eventName, data, options = {}) {
const {
async = false,
timeout = 5000,
namespace = 'default',
source = 'unknown'
} = options;
const event = {
name: eventName,
data,
namespace,
source,
timestamp: Date.now(),
id: this.generateEventId()
};
// 添加到历史记录
this.addToHistory(event);
if (this.debugMode) {
console.log(`事件发布: ${eventName}`, event);
}
// 应用中间件
const processedEvent = this.applyMiddlewares(event);
if (!processedEvent) {
return; // 事件被中间件拦截
}
const listeners = this.events.get(eventName) || [];
const results = [];
if (async) {
// 异步执行
return this.executeListenersAsync(listeners, processedEvent, timeout);
} else {
// 同步执行
return this.executeListenersSync(listeners, processedEvent);
}
}
// 同步执行监听器
executeListenersSync(listeners, event) {
const results = [];
const toRemove = [];
for (const listenerWrapper of listeners) {
try {
const result = listenerWrapper.listener(event.data, event);
results.push(result);
if (listenerWrapper.once) {
toRemove.push(listenerWrapper.id);
}
} catch (error) {
console.error(`事件监听器执行错误: ${event.name}`, error);
results.push({ error });
}
}
// 移除一次性监听器
toRemove.forEach(id => this.off(event.name, id));
return results;
}
// 异步执行监听器
async executeListenersAsync(listeners, event, timeout) {
const promises = [];
const toRemove = [];
for (const listenerWrapper of listeners) {
const promise = Promise.resolve().then(() => {
return listenerWrapper.listener(event.data, event);
}).catch(error => {
console.error(`事件监听器执行错误: ${event.name}`, error);
return { error };
});
promises.push(promise);
if (listenerWrapper.once) {
toRemove.push(listenerWrapper.id);
}
}
// 设置超时
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error('事件执行超时')), timeout);
});
try {
const results = await Promise.race([
Promise.all(promises),
timeoutPromise
]);
// 移除一次性监听器
toRemove.forEach(id => this.off(event.name, id));
return results;
} catch (error) {
console.error(`事件异步执行失败: ${event.name}`, error);
throw error;
}
}
// 应用中间件
applyMiddlewares(event) {
let processedEvent = event;
for (const middleware of this.middlewares) {
try {
processedEvent = middleware(processedEvent);
if (!processedEvent) {
break; // 中间件拦截了事件
}
} catch (error) {
console.error('事件中间件执行错误:', error);
}
}
return processedEvent;
}
// 添加中间件
use(middleware) {
this.middlewares.push(middleware);
// 返回移除中间件的函数
return () => {
const index = this.middlewares.indexOf(middleware);
if (index > -1) {
this.middlewares.splice(index, 1);
}
};
}
// 处理跨域事件
handleCrossOriginEvent(eventData) {
const { name, data, source, timestamp } = eventData;
// 验证事件来源
if (!this.isValidSource(source)) {
console.warn('忽略来自无效源的事件:', source);
return;
}
// 重新发布事件
this.emit(name, data, {
source: `cross-origin:${source}`,
namespace: 'cross-origin'
});
}
// 验证事件源
isValidSource(source) {
// 这里可以实现更复杂的源验证逻辑
return true;
}
// 跨域发送事件
emitCrossOrigin(eventName, data, targetOrigin = '*') {
const eventData = {
type: 'MICROFRONTEND_EVENT',
name: eventName,
data,
source: location.origin,
timestamp: Date.now()
};
window.postMessage(eventData, targetOrigin);
}
// 添加到历史记录
addToHistory(event) {
this.history.unshift(event);
if (this.history.length > this.maxHistoryLength) {
this.history = this.history.slice(0, this.maxHistoryLength);
}
}
// 生成监听器ID
generateListenerId() {
return `listener_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
// 生成事件ID
generateEventId() {
return `event_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
// 获取事件历史
getHistory(eventName) {
if (eventName) {
return this.history.filter(event => event.name === eventName);
}
return [...this.history];
}
// 获取所有监听器
getListeners(eventName) {
if (eventName) {
return this.events.get(eventName) || [];
}
const allListeners = {};
for (const [name, listeners] of this.events) {
allListeners[name] = listeners;
}
return allListeners;
}
// 清空所有监听器
clear(eventName) {
if (eventName) {
this.events.delete(eventName);
} else {
this.events.clear();
}
}
// 启用调试模式
enableDebug() {
this.debugMode = true;
}
// 禁用调试模式
disableDebug() {
this.debugMode = false;
}
// 销毁事件总线
destroy() {
this.events.clear();
this.middlewares = [];
this.history = [];
}
}
2. 架构设计与规划
2.1 应用拆分策略
// 应用拆分策略管理器
class ApplicationSplitStrategy {
constructor() {
this.strategies = {
byFeature: this.splitByFeature.bind(this),
byTeam: this.splitByTeam.bind(this),
byTechnology: this.splitByTechnology.bind(this),
byUserJourney: this.splitByUserJourney.bind(this),
hybrid: this.hybridSplit.bind(this)
};
this.criteria = {
complexity: 'high', // high, medium, low
teamSize: 'large', // large, medium, small
releaseFrequency: 'frequent', // frequent, regular, rare
technologyDiversity: 'high', // high, medium, low
userBase: 'large', // large, medium, small
performanceRequirements: 'high' // high, medium, low
};
}
// 按功能拆分
splitByFeature(application) {
const features = this.identifyFeatures(application);
const microApps = [];
features.forEach(feature => {
microApps.push({
name: `${application.name}-${feature.name}`,
type: 'feature',
feature: feature.name,
routes: feature.routes,
components: feature.components,
services: feature.services,
dependencies: feature.dependencies,
team: feature.team,
priority: feature.priority,
estimatedSize: this.estimateSize(feature),
complexity: this.assessComplexity(feature)
});
});
return {
strategy: 'byFeature',
microApps,
sharedComponents: this.identifySharedComponents(features),
sharedServices: this.identifySharedServices(features),
recommendations: this.generateFeatureSplitRecommendations(microApps)
};
}
// 按团队拆分
splitByTeam(application) {
const teams = this.identifyTeams(application);
const microApps = [];
teams.forEach(team => {
const teamFeatures = this.getTeamFeatures(application, team);
microApps.push({
name: `${application.name}-${team.name}`,
type: 'team',
team: team.name,
features: teamFeatures,
routes: this.getTeamRoutes(teamFeatures),
components: this.getTeamComponents(teamFeatures),
services: this.getTeamServices(teamFeatures),
technologies: team.technologies,
expertise: team.expertise,
capacity: team.capacity,
estimatedSize: this.estimateTeamAppSize(teamFeatures)
});
});
return {
strategy: 'byTeam',
microApps,
crossTeamDependencies: this.identifyCrossTeamDependencies(microApps),
sharedResources: this.identifySharedResources(teams),
recommendations: this.generateTeamSplitRecommendations(microApps)
};
}
// 按技术栈拆分
splitByTechnology(application) {
const technologies = this.identifyTechnologies(application);
const microApps = [];
technologies.forEach(tech => {
const techComponents = this.getTechnologyComponents(application, tech);
microApps.push({
name: `${application.name}-${tech.name}`,
type: 'technology',
technology: tech.name,
version: tech.version,
components: techComponents,
routes: this.getTechnologyRoutes(techComponents),
buildTools: tech.buildTools,
dependencies: tech.dependencies,
migrationPath: tech.migrationPath,
estimatedSize: this.estimateTechAppSize(techComponents)
});
});
return {
strategy: 'byTechnology',
microApps,
technologyBridge: this.createTechnologyBridge(technologies),
migrationPlan: this.createMigrationPlan(microApps),
recommendations: this.generateTechnologySplitRecommendations(microApps)
};
}
// 按用户旅程拆分
splitByUserJourney(application) {
const journeys = this.identifyUserJourneys(application);
const microApps = [];
journeys.forEach(journey => {
microApps.push({
name: `${application.name}-${journey.name}`,
type: 'userJourney',
journey: journey.name,
userTypes: journey.userTypes,
touchpoints: journey.touchpoints,
routes: journey.routes,
components: journey.components,
services: journey.services,
analytics: journey.analytics,
performance: journey.performance,
estimatedSize: this.estimateJourneyAppSize(journey)
});
});
return {
strategy: 'byUserJourney',
microApps,
userFlows: this.mapUserFlows(journeys),
sharedTouchpoints: this.identifySharedTouchpoints(journeys),
recommendations: this.generateJourneySplitRecommendations(microApps)
};
}
// 混合拆分策略
hybridSplit(application) {
// 结合多种策略
const featureSplit = this.splitByFeature(application);
const teamSplit = this.splitByTeam(application);
const techSplit = this.splitByTechnology(application);
// 分析最优组合
const analysis = this.analyzeStrategies([
featureSplit,
teamSplit,
techSplit
]);
// 生成混合策略
const hybridApps = this.generateHybridApps(analysis);
return {
strategy: 'hybrid',
microApps: hybridApps,
strategyMix: analysis.optimalMix,
tradeoffs: analysis.tradeoffs,
recommendations: this.generateHybridRecommendations(analysis)
};
}
// 识别功能模块
identifyFeatures(application) {
// 分析代码结构、路由、组件等识别功能模块
const features = [];
// 基于路由识别
const routeFeatures = this.identifyFeaturesByRoutes(application.routes);
// 基于组件识别
const componentFeatures = this.identifyFeaturesByComponents(application.components);
// 基于服务识别
const serviceFeatures = this.identifyFeaturesByServices(application.services);
// 合并和去重
const allFeatures = [...routeFeatures, ...componentFeatures, ...serviceFeatures];
const uniqueFeatures = this.deduplicateFeatures(allFeatures);
return uniqueFeatures;
}
// 基于路由识别功能
identifyFeaturesByRoutes(routes) {
const features = [];
const routeGroups = this.groupRoutesByPattern(routes);
routeGroups.forEach(group => {
features.push({
name: group.name,
type: 'route-based',
routes: group.routes,
priority: group.priority,
complexity: this.assessRouteComplexity(group.routes)
});
});
return features;
}
// 评估复杂度
assessComplexity(feature) {
let complexity = 0;
// 基于组件数量
complexity += feature.components.length * 0.1;
// 基于依赖数量
complexity += feature.dependencies.length * 0.2;
// 基于路由数量
complexity += feature.routes.length * 0.15;
// 基于服务数量
complexity += feature.services.length * 0.25;
if (complexity < 2) return 'low';
if (complexity < 5) return 'medium';
return 'high';
}
// 估算大小
estimateSize(feature) {
const componentSize = feature.components.length * 50; // 每个组件约50KB
const serviceSize = feature.services.length * 30; // 每个服务约30KB
const routeSize = feature.routes.length * 10; // 每个路由约10KB
return {
estimated: componentSize + serviceSize + routeSize,
unit: 'KB',
breakdown: {
components: componentSize,
services: serviceSize,
routes: routeSize
}
};
}
// 生成拆分建议
generateSplitRecommendations(application) {
const strategies = ['byFeature', 'byTeam', 'byTechnology', 'byUserJourney'];
const results = [];
strategies.forEach(strategy => {
const result = this.strategies[strategy](application);
results.push({
strategy,
score: this.scoreStrategy(result),
pros: this.getStrategyPros(strategy),
cons: this.getStrategyCons(strategy),
suitability: this.assessSuitability(strategy, application),
result
});
});
// 排序推荐
results.sort((a, b) => b.score - a.score);
return {
recommended: results[0],
alternatives: results.slice(1),
hybridOption: this.strategies.hybrid(application)
};
}
// 评分策略
scoreStrategy(result) {
let score = 0;
// 基于应用数量(适中最好)
const appCount = result.microApps.length;
if (appCount >= 3 && appCount <= 8) {
score += 20;
} else if (appCount >= 2 && appCount <= 12) {
score += 10;
}
// 基于复杂度分布
const complexityDistribution = this.analyzeComplexityDistribution(result.microApps);
if (complexityDistribution.balanced) {
score += 15;
}
// 基于依赖关系
const dependencies = this.analyzeDependencies(result.microApps);
score += Math.max(0, 20 - dependencies.crossAppDependencies * 2);
// 基于团队匹配度
const teamAlignment = this.assessTeamAlignment(result.microApps);
score += teamAlignment * 15;
// 基于技术一致性
const techConsistency = this.assessTechConsistency(result.microApps);
score += techConsistency * 10;
return Math.min(100, Math.max(0, score));
}
// 获取策略优点
getStrategyPros(strategy) {
const pros = {
byFeature: [
'功能边界清晰',
'业务逻辑内聚',
'独立发布能力强',
'用户体验一致'
],
byTeam: [
'团队自主性强',
'技能匹配度高',
'沟通成本低',
'责任边界明确'
],
byTechnology: [
'技术栈统一',
'迁移风险可控',
'技术债务隔离',
'专业化程度高'
],
byUserJourney: [
'用户体验优化',
'业务价值明确',
'性能优化针对性强',
'用户反馈直接'
]
};
return pros[strategy] || [];
}
// 获取策略缺点
getStrategyCons(strategy) {
const cons = {
byFeature: [
'可能存在功能重复',
'跨功能协调复杂',
'共享组件管理困难'
],
byTeam: [
'可能产生技术孤岛',
'功能边界模糊',
'代码重复风险'
],
byTechnology: [
'业务逻辑分散',
'用户体验割裂',
'功能协调困难'
],
byUserJourney: [
'技术栈可能分散',
'团队协作复杂',
'重复开发风险',
'维护成本较高'
]
};
return cons[strategy] || [];
}
// 评估适用性
assessSuitability(strategy, application) {
let suitability = 0;
switch (strategy) {
case 'byFeature':
if (this.criteria.complexity === 'high') suitability += 0.3;
if (this.criteria.releaseFrequency === 'frequent') suitability += 0.2;
if (application.features && application.features.length > 5) suitability += 0.2;
break;
case 'byTeam':
if (this.criteria.teamSize === 'large') suitability += 0.3;
if (this.criteria.technologyDiversity === 'high') suitability += 0.2;
if (application.teams && application.teams.length > 3) suitability += 0.2;
break;
case 'byTechnology':
if (this.criteria.technologyDiversity === 'high') suitability += 0.3;
if (application.legacyCode) suitability += 0.2;
if (application.migrationNeeded) suitability += 0.2;
break;
case 'byUserJourney':
if (this.criteria.userBase === 'large') suitability += 0.3;
if (this.criteria.performanceRequirements === 'high') suitability += 0.2;
if (application.userJourneys && application.userJourneys.length > 3) suitability += 0.2;
break;
}
return Math.min(1, suitability);
}
}
2.2 依赖管理策略
// 依赖管理策略
class DependencyManagementStrategy {
constructor() {
this.sharedDependencies = new Map();
this.versionConstraints = new Map();
this.dependencyGraph = new Map();
this.conflictResolution = {
strategy: 'semver', // semver, latest, pinned, custom
allowMajorUpdates: false,
allowMinorUpdates: true,
allowPatchUpdates: true
};
}
// 分析依赖关系
analyzeDependencies(microApps) {
const analysis = {
shared: new Map(),
unique: new Map(),
conflicts: [],
recommendations: []
};
// 收集所有依赖
const allDependencies = new Map();
microApps.forEach(app => {
app.dependencies.forEach(dep => {
if (!allDependencies.has(dep.name)) {
allDependencies.set(dep.name, []);
}
allDependencies.get(dep.name).push({
app: app.name,
version: dep.version,
type: dep.type // runtime, devDependency, peerDependency
});
});
});
// 分析共享和冲突
allDependencies.forEach((usages, depName) => {
if (usages.length > 1) {
// 多个应用使用的依赖
const versions = [...new Set(usages.map(u => u.version))];
if (versions.length === 1) {
// 版本一致,可以共享
analysis.shared.set(depName, {
version: versions[0],
usedBy: usages.map(u => u.app),
type: usages[0].type,
shareRecommended: true
});
} else {
// 版本冲突
analysis.conflicts.push({
dependency: depName,
versions: versions,
usages: usages,
severity: this.assessConflictSeverity(depName, versions),
resolution: this.suggestConflictResolution(depName, versions)
});
}
} else {
// 单个应用使用的依赖
analysis.unique.set(depName, usages[0]);
}
});
// 生成建议
analysis.recommendations = this.generateDependencyRecommendations(analysis);
return analysis;
}
// 评估冲突严重性
assessConflictSeverity(depName, versions) {
// 检查是否为主要版本差异
const majorVersions = versions.map(v => parseInt(v.split('.')[0]));
const uniqueMajorVersions = [...new Set(majorVersions)];
if (uniqueMajorVersions.length > 1) {
return 'high'; // 主要版本冲突
}
// 检查是否为次要版本差异
const minorVersions = versions.map(v => {
const parts = v.split('.');
return parseInt(parts[1] || 0);
});
const uniqueMinorVersions = [...new Set(minorVersions)];
if (uniqueMinorVersions.length > 1) {
return 'medium'; // 次要版本冲突
}
return 'low'; // 补丁版本冲突
}
// 建议冲突解决方案
suggestConflictResolution(depName, versions) {
const strategies = [];
// 策略1: 升级到最新兼容版本
const latestCompatible = this.findLatestCompatibleVersion(versions);
if (latestCompatible) {
strategies.push({
type: 'upgrade',
version: latestCompatible,
description: `升级所有应用到版本 ${latestCompatible}`,
effort: 'low',
risk: 'low'
});
}
// 策略2: 使用版本范围
const versionRange = this.calculateVersionRange(versions);
if (versionRange) {
strategies.push({
type: 'range',
range: versionRange,
description: `使用版本范围 ${versionRange}`,
effort: 'medium',
risk: 'medium'
});
}
// 策略3: 独立打包
strategies.push({
type: 'isolate',
description: '每个应用独立打包此依赖',
effort: 'high',
risk: 'low'
});
return strategies;
}
// 生成依赖建议
generateDependencyRecommendations(analysis) {
const recommendations = [];
// 共享依赖建议
analysis.shared.forEach((info, depName) => {
if (info.shareRecommended) {
recommendations.push({
type: 'share',
dependency: depName,
version: info.version,
apps: info.usedBy,
benefit: 'reduced bundle size',
implementation: 'external dependency'
});
}
});
// 冲突解决建议
analysis.conflicts.forEach(conflict => {
recommendations.push({
type: 'resolve-conflict',
dependency: conflict.dependency,
severity: conflict.severity,
strategies: conflict.resolution,
priority: conflict.severity === 'high' ? 'urgent' : 'normal'
});
});
// 优化建议
const optimizations = this.identifyOptimizations(analysis);
recommendations.push(...optimizations);
return recommendations;
}
// 识别优化机会
identifyOptimizations(analysis) {
const optimizations = [];
// 检查重复的小依赖
analysis.shared.forEach((info, depName) => {
if (info.usedBy.length > 2 && this.isSmallDependency(depName)) {
optimizations.push({
type: 'bundle-optimization',
dependency: depName,
suggestion: 'consider bundling with main application',
reason: 'small size, multiple usage'
});
}
});
// 检查大型依赖
analysis.unique.forEach((info, depName) => {
if (this.isLargeDependency(depName)) {
optimizations.push({
type: 'lazy-loading',
dependency: depName,
suggestion: 'consider lazy loading or code splitting',
reason: 'large size, single usage'
});
}
});
return optimizations;
}
// 创建依赖配置
createDependencyConfig(analysis) {
const config = {
shared: {},
external: [],
bundled: [],
lazyLoaded: []
};
// 配置共享依赖
analysis.shared.forEach((info, depName) => {
if (info.shareRecommended) {
config.shared[depName] = {
singleton: true,
version: info.version,
requiredVersion: info.version
};
}
});
// 配置外部依赖
const externalDeps = this.identifyExternalDependencies(analysis);
config.external = externalDeps;
return config;
}
}
2.3 技术栈选择
// 技术栈选择策略
class TechnologyStackStrategy {
constructor() {
this.supportedFrameworks = {
react: {
versions: ['16.8+', '17.x', '18.x'],
bundlers: ['webpack', 'vite', 'rollup'],
compatibility: 'high',
ecosystem: 'mature',
learningCurve: 'medium'
},
vue: {
versions: ['2.6+', '3.x'],
bundlers: ['webpack', 'vite', 'rollup'],
compatibility: 'high',
ecosystem: 'mature',
learningCurve: 'low'
},
angular: {
versions: ['12+', '13.x', '14.x', '15.x'],
bundlers: ['webpack', 'angular-cli'],
compatibility: 'medium',
ecosystem: 'comprehensive',
learningCurve: 'high'
},
svelte: {
versions: ['3.x', '4.x'],
bundlers: ['vite', 'rollup', 'webpack'],
compatibility: 'medium',
ecosystem: 'growing',
learningCurve: 'low'
}
};
this.integrationPatterns = {
'module-federation': {
frameworks: ['react', 'vue', 'angular'],
complexity: 'medium',
performance: 'high',
isolation: 'medium'
},
'single-spa': {
frameworks: ['react', 'vue', 'angular', 'svelte'],
complexity: 'high',
performance: 'medium',
isolation: 'high'
},
'iframe': {
frameworks: ['any'],
complexity: 'low',
performance: 'low',
isolation: 'high'
},
'web-components': {
frameworks: ['any'],
complexity: 'medium',
performance: 'medium',
isolation: 'medium'
}
};
}
// 评估技术栈兼容性
assessCompatibility(microApps) {
const frameworks = this.extractFrameworks(microApps);
const compatibility = {
score: 0,
issues: [],
recommendations: []
};
// 检查框架兼容性
const frameworkCompatibility = this.checkFrameworkCompatibility(frameworks);
compatibility.score += frameworkCompatibility.score * 0.4;
compatibility.issues.push(...frameworkCompatibility.issues);
// 检查版本兼容性
const versionCompatibility = this.checkVersionCompatibility(frameworks);
compatibility.score += versionCompatibility.score * 0.3;
compatibility.issues.push(...versionCompatibility.issues);
// 检查构建工具兼容性
const buildCompatibility = this.checkBuildToolCompatibility(microApps);
compatibility.score += buildCompatibility.score * 0.3;
compatibility.issues.push(...buildCompatibility.issues);
// 生成建议
compatibility.recommendations = this.generateCompatibilityRecommendations(
compatibility.issues
);
return compatibility;
}
// 推荐集成模式
recommendIntegrationPattern(microApps, requirements) {
const patterns = [];
Object.entries(this.integrationPatterns).forEach(([name, pattern]) => {
const score = this.scoreIntegrationPattern(pattern, microApps, requirements);
patterns.push({
name,
pattern,
score,
pros: this.getPatternPros(name),
cons: this.getPatternCons(name),
implementation: this.getImplementationGuide(name)
});
});
// 按分数排序
patterns.sort((a, b) => b.score - a.score);
return {
recommended: patterns[0],
alternatives: patterns.slice(1),
comparison: this.comparePatterns(patterns)
};
}
// 评分集成模式
scoreIntegrationPattern(pattern, microApps, requirements) {
let score = 0;
// 框架支持度
const frameworks = this.extractFrameworks(microApps);
const supportedFrameworks = frameworks.filter(f =>
pattern.frameworks.includes(f) || pattern.frameworks.includes('any')
);
score += (supportedFrameworks.length / frameworks.length) * 30;
// 性能要求匹配
const performanceScore = this.mapPerformanceScore(pattern.performance);
const requiredPerformance = this.mapPerformanceScore(requirements.performance);
score += Math.max(0, 25 - Math.abs(performanceScore - requiredPerformance) * 5);
// 隔离要求匹配
const isolationScore = this.mapIsolationScore(pattern.isolation);
const requiredIsolation = this.mapIsolationScore(requirements.isolation);
score += Math.max(0, 25 - Math.abs(isolationScore - requiredIsolation) * 5);
// 复杂度考虑(越简单越好)
const complexityPenalty = this.mapComplexityPenalty(pattern.complexity);
score -= complexityPenalty;
// 团队技能匹配
const skillMatch = this.assessSkillMatch(pattern, requirements.teamSkills);
score += skillMatch * 20;
return Math.max(0, Math.min(100, score));
}
}
3. 技术实现方案
3.1 Module Federation实现
// Module Federation配置管理器
class ModuleFederationManager {
constructor() {
this.federationConfig = {
name: '',
filename: 'remoteEntry.js',
exposes: {},
remotes: {},
shared: {},
library: { type: 'var', name: '' }
};
this.loadedModules = new Map();
this.moduleCache = new Map();
this.errorHandlers = new Map();
this.retryConfig = {
maxRetries: 3,
retryDelay: 1000,
backoffMultiplier: 2
};
}
// 配置宿主应用
configureHost(config) {
this.federationConfig = {
...this.federationConfig,
name: config.name || 'host',
remotes: config.remotes || {},
shared: this.buildSharedConfig(config.shared || {})
};
// 设置全局错误处理
this.setupGlobalErrorHandling();
// 预加载关键模块
if (config.preload) {
this.preloadModules(config.preload);
}
return this.generateWebpackConfig();
}
// 配置远程应用
configureRemote(config) {
this.federationConfig = {
...this.federationConfig,
name: config.name,
filename: config.filename || 'remoteEntry.js',
exposes: config.exposes || {},
shared: this.buildSharedConfig(config.shared || {}),
library: {
type: 'var',
name: config.name
}
};
return this.generateWebpackConfig();
}
// 构建共享配置
buildSharedConfig(shared) {
const sharedConfig = {};
// 默认共享依赖
const defaultShared = {
'react': {
singleton: true,
requiredVersion: '^17.0.0'
},
'react-dom': {
singleton: true,
requiredVersion: '^17.0.0'
},
'lodash': {
singleton: false,
requiredVersion: '^4.17.0'
}
};
// 合并配置
Object.assign(sharedConfig, defaultShared, shared);
// 处理版本兼容性
Object.keys(sharedConfig).forEach(dep => {
if (typeof sharedConfig[dep] === 'string') {
sharedConfig[dep] = {
requiredVersion: sharedConfig[dep]
};
}
// 添加错误处理
sharedConfig[dep].import = false; // 禁用自动导入
sharedConfig[dep].shareKey = dep;
sharedConfig[dep].shareScope = 'default';
});
return sharedConfig;
}
// 动态加载远程模块
async loadRemoteModule(remoteName, moduleName, options = {}) {
const {
timeout = 10000,
retry = true,
cache = true,
fallback = null
} = options;
const moduleKey = `${remoteName}/${moduleName}`;
// 检查缓存
if (cache && this.moduleCache.has(moduleKey)) {
return this.moduleCache.get(moduleKey);
}
try {
// 确保远程容器已加载
await this.ensureRemoteContainer(remoteName, timeout);
// 获取远程模块
const container = window[remoteName];
if (!container) {
throw new Error(`远程容器 ${remoteName} 未找到`);
}
// 初始化容器
await container.init(__webpack_share_scopes__.default);
// 获取模块工厂
const factory = await container.get(moduleName);
const module = factory();
// 缓存模块
if (cache) {
this.moduleCache.set(moduleKey, module);
}
// 记录加载成功
this.loadedModules.set(moduleKey, {
module,
loadTime: Date.now(),
remoteName,
moduleName
});
return module;
} catch (error) {
console.error(`加载远程模块失败: ${moduleKey}`, error);
// 重试机制
if (retry && this.shouldRetry(moduleKey)) {
return this.retryLoadModule(remoteName, moduleName, options);
}
// 降级处理
if (fallback) {
console.warn(`使用降级模块: ${moduleKey}`);
return fallback;
}
throw error;
}
}
// 确保远程容器已加载
async ensureRemoteContainer(remoteName, timeout) {
if (window[remoteName]) {
return window[remoteName];
}
const remoteConfig = this.federationConfig.remotes[remoteName];
if (!remoteConfig) {
throw new Error(`远程配置未找到: ${remoteName}`);
}
// 加载远程入口文件
const remoteUrl = this.resolveRemoteUrl(remoteConfig);
await this.loadScript(remoteUrl, timeout);
// 验证容器是否已加载
if (!window[remoteName]) {
throw new Error(`远程容器加载失败: ${remoteName}`);
}
return window[remoteName];
}
// 解析远程URL
resolveRemoteUrl(remoteConfig) {
if (typeof remoteConfig === 'string') {
return remoteConfig;
}
const { url, entry = 'remoteEntry.js' } = remoteConfig;
return `${url}/${entry}`;
}
// 加载脚本
loadScript(url, timeout = 10000) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = url;
const timeoutId = setTimeout(() => {
reject(new Error(`脚本加载超时: ${url}`));
}, timeout);
script.onload = () => {
clearTimeout(timeoutId);
resolve();
};
script.onerror = () => {
clearTimeout(timeoutId);
reject(new Error(`脚本加载失败: ${url}`));
};
document.head.appendChild(script);
});
}
// 重试加载模块
async retryLoadModule(remoteName, moduleName, options, attempt = 1) {
const moduleKey = `${remoteName}/${moduleName}`;
if (attempt > this.retryConfig.maxRetries) {
throw new Error(`模块加载重试次数超限: ${moduleKey}`);
}
// 计算延迟时间
const delay = this.retryConfig.retryDelay *
Math.pow(this.retryConfig.backoffMultiplier, attempt - 1);
console.warn(`重试加载模块 ${moduleKey}, 第 ${attempt} 次, 延迟 ${delay}ms`);
await new Promise(resolve => setTimeout(resolve, delay));
try {
return await this.loadRemoteModule(remoteName, moduleName, {
...options,
retry: false // 避免递归重试
});
} catch (error) {
return this.retryLoadModule(remoteName, moduleName, options, attempt + 1);
}
}
// 判断是否应该重试
shouldRetry(moduleKey) {
const errorCount = this.errorHandlers.get(moduleKey) || 0;
return errorCount < this.retryConfig.maxRetries;
}
// 预加载模块
async preloadModules(modules) {
const preloadPromises = modules.map(async ({ remote, module, priority = 'low' }) => {
try {
if (priority === 'high') {
// 高优先级立即加载
await this.loadRemoteModule(remote, module);
} else {
// 低优先级延迟加载
setTimeout(() => {
this.loadRemoteModule(remote, module).catch(error => {
console.warn(`预加载模块失败: ${remote}/${module}`, error);
});
}, 1000);
}
} catch (error) {
console.warn(`预加载模块失败: ${remote}/${module}`, error);
}
});
await Promise.allSettled(preloadPromises);
}
// 设置全局错误处理
setupGlobalErrorHandling() {
window.addEventListener('error', (event) => {
if (event.filename && event.filename.includes('remoteEntry.js')) {
this.handleRemoteError(event);
}
});
window.addEventListener('unhandledrejection', (event) => {
if (event.reason && event.reason.message &&
event.reason.message.includes('Loading chunk')) {
this.handleChunkLoadError(event);
}
});
}
// 处理远程错误
handleRemoteError(event) {
console.error('远程模块错误:', event);
// 尝试识别错误的远程应用
const remoteName = this.identifyRemoteFromError(event);
if (remoteName) {
this.markRemoteAsUnavailable(remoteName);
}
}
// 处理代码块加载错误
handleChunkLoadError(event) {
console.error('代码块加载错误:', event);
// 可以实现重新加载或降级策略
event.preventDefault();
}
// 生成Webpack配置
generateWebpackConfig() {
return {
mode: 'development',
plugins: [
new ModuleFederationPlugin(this.federationConfig)
],
resolve: {
fallback: {
'path': false,
'fs': false
}
},
optimization: {
splitChunks: {
chunks: 'async',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all'
}
}
}
}
};
}
// 获取已加载模块
getLoadedModules() {
return Array.from(this.loadedModules.entries()).map(([key, info]) => ({
key,
...info
}));
}
// 清理模块缓存
clearModuleCache(pattern) {
if (pattern) {
const regex = new RegExp(pattern);
for (const [key] of this.moduleCache) {
if (regex.test(key)) {
this.moduleCache.delete(key);
}
}
} else {
this.moduleCache.clear();
}
}
// 获取性能指标
getPerformanceMetrics() {
const metrics = {
totalModules: this.loadedModules.size,
cacheHitRate: 0,
averageLoadTime: 0,
errorRate: 0
};
if (this.loadedModules.size > 0) {
const loadTimes = Array.from(this.loadedModules.values())
.map(info => info.loadTime);
metrics.averageLoadTime = loadTimes.reduce((sum, time) => sum + time, 0) / loadTimes.length;
}
return metrics;
}
}
3.2 Single-SPA实现
// Single-SPA应用管理器
class SingleSPAManager {
constructor() {
this.applications = new Map();
this.lifecycleEvents = new EventTarget();
this.globalErrorHandler = null;
this.routingStrategy = 'browser'; // browser, hash, memory
this.loadingIndicator = null;
this.initializeSingleSPA();
}
// 初始化Single-SPA
initializeSingleSPA() {
// 设置路由策略
this.setupRouting();
// 设置全局错误处理
this.setupErrorHandling();
// 设置加载指示器
this.setupLoadingIndicator();
// 启动Single-SPA
singleSpa.start();
}
// 注册应用
registerApplication(config) {
const {
name,
app,
activeWhen,
customProps = {},
loadErrorTime = 5000,
unloadErrorTime = 5000
} = config;
// 验证配置
this.validateApplicationConfig(config);
// 包装应用加载函数
const wrappedApp = this.wrapApplication(app, name);
// 包装激活条件
const wrappedActiveWhen = this.wrapActiveWhen(activeWhen, name);
// 注册到Single-SPA
singleSpa.registerApplication({
name,
app: wrappedApp,
activeWhen: wrappedActiveWhen,
customProps: {
...customProps,
spaManager: this,
eventBus: this.lifecycleEvents
}
});
// 存储应用信息
this.applications.set(name, {
...config,
status: 'NOT_LOADED',
loadTime: null,
errorCount: 0,
lastError: null
});
console.log(`应用已注册: ${name}`);
return this.applications.get(name);
}
// 包装应用
wrapApplication(app, name) {
return async (props) => {
try {
this.updateApplicationStatus(name, 'LOADING');
this.showLoadingIndicator(name);
const startTime = performance.now();
// 加载应用
let loadedApp;
if (typeof app === 'function') {
loadedApp = await app(props);
} else {
loadedApp = app;
}
// 验证应用生命周期
this.validateLifecycleMethods(loadedApp, name);
// 包装生命周期方法
const wrappedLifecycle = this.wrapLifecycleMethods(loadedApp, name);
const loadTime = performance.now() - startTime;
this.updateApplicationLoadTime(name, loadTime);
this.updateApplicationStatus(name, 'LOADED');
this.hideLoadingIndicator(name);
return wrappedLifecycle;
} catch (error) {
this.handleApplicationError(name, 'load', error);
this.hideLoadingIndicator(name);
throw error;
}
};
}
// 包装激活条件
wrapActiveWhen(activeWhen, name) {
return (location) => {
try {
let result;
if (typeof activeWhen === 'string') {
result = location.pathname.startsWith(activeWhen);
} else if (typeof activeWhen === 'function') {
result = activeWhen(location);
} else if (activeWhen instanceof RegExp) {
result = activeWhen.test(location.pathname);
} else if (Array.isArray(activeWhen)) {
result = activeWhen.some(condition => {
if (typeof condition === 'string') {
return location.pathname.startsWith(condition);
} else if (condition instanceof RegExp) {
return condition.test(location.pathname);
}
return false;
});
} else {
result = false;
}
// 记录激活状态变化
const currentStatus = this.getApplicationStatus(name);
if (result && currentStatus !== 'MOUNTED') {
this.lifecycleEvents.dispatchEvent(new CustomEvent('app:activating', {
detail: { name, location }
}));
} else if (!result && currentStatus === 'MOUNTED') {
this.lifecycleEvents.dispatchEvent(new CustomEvent('app:deactivating', {
detail: { name, location }
}));
}
return result;
} catch (error) {
console.error(`激活条件检查失败: ${name}`, error);
return false;
}
};
}
// 包装生命周期方法
wrapLifecycleMethods(app, name) {
const wrappedApp = {};
// 包装bootstrap
if (app.bootstrap) {
wrappedApp.bootstrap = async (props) => {
try {
this.updateApplicationStatus(name, 'BOOTSTRAPPING');
this.lifecycleEvents.dispatchEvent(new CustomEvent('app:bootstrap:start', {
detail: { name, props }
}));
const result = await app.bootstrap(props);
this.updateApplicationStatus(name, 'NOT_MOUNTED');
this.lifecycleEvents.dispatchEvent(new CustomEvent('app:bootstrap:end', {
detail: { name, props }
}));
return result;
} catch (error) {
this.handleApplicationError(name, 'bootstrap', error);
throw error;
}
};
}
// 包装mount
if (app.mount) {
wrappedApp.mount = async (props) => {
try {
this.updateApplicationStatus(name, 'MOUNTING');
this.lifecycleEvents.dispatchEvent(new CustomEvent('app:mount:start', {
detail: { name, props }
}));
const result = await app.mount(props);
this.updateApplicationStatus(name, 'MOUNTED');
this.lifecycleEvents.dispatchEvent(new CustomEvent('app:mount:end', {
detail: { name, props }
}));
return result;
} catch (error) {
this.handleApplicationError(name, 'mount', error);
throw error;
}
};
}
// 包装unmount
if (app.unmount) {
wrappedApp.unmount = async (props) => {
try {
this.updateApplicationStatus(name, 'UNMOUNTING');
this.lifecycleEvents.dispatchEvent(new CustomEvent('app:unmount:start', {
detail: { name, props }
}));
const result = await app.unmount(props);
this.updateApplicationStatus(name, 'NOT_MOUNTED');
this.lifecycleEvents.dispatchEvent(new CustomEvent('app:unmount:end', {
detail: { name, props }
}));
return result;
} catch (error) {
this.handleApplicationError(name, 'unmount', error);
throw error;
}
};
}
// 包装update(可选)
if (app.update) {
wrappedApp.update = async (props) => {
try {
this.lifecycleEvents.dispatchEvent(new CustomEvent('app:update:start', {
detail: { name, props }
}));
const result = await app.update(props);
this.lifecycleEvents.dispatchEvent(new CustomEvent('app:update:end', {
detail: { name, props }
}));
return result;
} catch (error) {
this.handleApplicationError(name, 'update', error);
throw error;
}
};
}
return wrappedApp;
}
// 验证应用配置
validateApplicationConfig(config) {
const required = ['name', 'app', 'activeWhen'];
const missing = required.filter(field => !config[field]);
if (missing.length > 0) {
throw new Error(`应用配置缺少必需字段: ${missing.join(', ')}`);
}
if (this.applications.has(config.name)) {
throw new Error(`应用名称已存在: ${config.name}`);
}
}
// 验证生命周期方法
validateLifecycleMethods(app, name) {
const required = ['mount', 'unmount'];
const missing = required.filter(method => typeof app[method] !== 'function');
if (missing.length > 0) {
throw new Error(`应用 ${name} 缺少生命周期方法: ${missing.join(', ')}`);
}
}
// 更新应用状态
updateApplicationStatus(name, status) {
const app = this.applications.get(name);
if (app) {
app.status = status;
app.lastStatusChange = Date.now();
}
}
// 更新应用加载时间
updateApplicationLoadTime(name, loadTime) {
const app = this.applications.get(name);
if (app) {
app.loadTime = loadTime;
}
}
// 处理应用错误
handleApplicationError(name, phase, error) {
console.error(`应用 ${name} 在 ${phase} 阶段发生错误:`, error);
const app = this.applications.get(name);
if (app) {
app.errorCount++;
app.lastError = {
phase,
error: error.message,
timestamp: Date.now()
};
}
// 触发错误事件
this.lifecycleEvents.dispatchEvent(new CustomEvent('app:error', {
detail: { name, phase, error }
}));
// 调用全局错误处理器
if (this.globalErrorHandler) {
this.globalErrorHandler(name, phase, error);
}
}
// 设置路由策略
setupRouting() {
switch (this.routingStrategy) {
case 'hash':
// 使用hash路由
break;
case 'memory':
// 使用内存路由
break;
default:
// 使用浏览器路由
break;
}
}
// 设置错误处理
setupErrorHandling() {
singleSpa.addErrorHandler((error) => {
console.error('Single-SPA错误:', error);
if (this.globalErrorHandler) {
this.globalErrorHandler(null, 'global', error);
}
});
}
// 设置加载指示器
setupLoadingIndicator() {
this.loadingIndicator = document.createElement('div');
this.loadingIndicator.id = 'spa-loading-indicator';
this.loadingIndicator.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 4px;
background: linear-gradient(90deg, #007bff, #28a745);
z-index: 9999;
transform: translateX(-100%);
transition: transform 0.3s ease;
`;
document.body.appendChild(this.loadingIndicator);
}
// 显示加载指示器
showLoadingIndicator(appName) {
if (this.loadingIndicator) {
this.loadingIndicator.style.transform = 'translateX(0)';
}
}
// 隐藏加载指示器
hideLoadingIndicator(appName) {
if (this.loadingIndicator) {
this.loadingIndicator.style.transform = 'translateX(-100%)';
}
}
// 获取应用状态
getApplicationStatus(name) {
const app = this.applications.get(name);
return app ? app.status : 'NOT_REGISTERED';
}
// 卸载应用
async unloadApplication(name) {
try {
await singleSpa.unloadApplication(name);
const app = this.applications.get(name);
if (app) {
app.status = 'NOT_LOADED';
}
console.log(`应用已卸载: ${name}`);
} catch (error) {
console.error(`卸载应用失败: ${name}`, error);
throw error;
}
}
// 获取所有应用
getAllApplications() {
return Array.from(this.applications.entries()).map(([name, info]) => ({
name,
...info
}));
}
// 获取活跃应用
getActiveApplications() {
return singleSpa.getAppNames().filter(name => {
const status = singleSpa.getAppStatus(name);
return status === 'MOUNTED';
});
}
// 设置全局错误处理器
setGlobalErrorHandler(handler) {
this.globalErrorHandler = handler;
}
// 导航到应用
navigateToApp(appName, path = '/') {
const app = this.applications.get(appName);
if (!app) {
throw new Error(`应用未找到: ${appName}`);
}
// 构建完整路径
const fullPath = `${app.activeWhen}${path}`;
// 导航
singleSpa.navigateToUrl(fullPath);
}
}
3.3 iframe沙箱实现
// iframe沙箱管理器
class IframeSandboxManager {
constructor() {
this.sandboxes = new Map();
this.messageHandlers = new Map();
this.securityPolicies = {
allowScripts: true,
allowForms: true,
allowPopups: false,
allowSameOrigin: false,
allowTopNavigation: false
};
this.setupGlobalMessageHandler();
}
// 创建沙箱
createSandbox(config) {
const {
name,
url,
container,
sandbox = {},
allowedOrigins = [],
communicationProtocol = 'postMessage',
securityLevel = 'strict'
} = config;
// 验证配置
this.validateSandboxConfig(config);
// 创建iframe元素
const iframe = this.createIframeElement(name, url, sandbox, securityLevel);
// 设置容器
const containerElement = typeof container === 'string'
? document.querySelector(container)
: container;
if (!containerElement) {
throw new Error(`容器未找到: ${container}`);
}
// 创建沙箱实例
const sandboxInstance = {
name,
iframe,
container: containerElement,
url,
allowedOrigins,
communicationProtocol,
securityLevel,
status: 'created',
messageQueue: [],
eventListeners: new Map(),
loadPromise: null,
loadTime: null,
errorCount: 0
};
// 设置加载监听
this.setupLoadListeners(sandboxInstance);
// 设置通信
this.setupCommunication(sandboxInstance);
// 存储沙箱
this.sandboxes.set(name, sandboxInstance);
return sandboxInstance;
}
// 创建iframe元素
createIframeElement(name, url, sandbox, securityLevel) {
const iframe = document.createElement('iframe');
// 基本属性
iframe.name = name;
iframe.src = url;
iframe.style.cssText = `
width: 100%;
height: 100%;
border: none;
display: block;
`;
// 安全属性
const sandboxValue = this.buildSandboxAttribute(sandbox, securityLevel);
if (sandboxValue) {
iframe.sandbox = sandboxValue;
}
// CSP和其他安全头
if (securityLevel === 'strict') {
iframe.setAttribute('csp', "default-src 'self'; script-src 'self' 'unsafe-inline'");
iframe.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin');
}
// 禁用某些功能
iframe.setAttribute('allow', 'encrypted-media; fullscreen');
iframe.setAttribute('loading', 'lazy');
return iframe;
}
// 构建sandbox属性
buildSandboxAttribute(sandbox, securityLevel) {
const defaultSandbox = {
'allow-scripts': this.securityPolicies.allowScripts,
'allow-forms': this.securityPolicies.allowForms,
'allow-popups': this.securityPolicies.allowPopups,
'allow-same-origin': this.securityPolicies.allowSameOrigin,
'allow-top-navigation': this.securityPolicies.allowTopNavigation
};
// 根据安全级别调整
if (securityLevel === 'strict') {
defaultSandbox['allow-same-origin'] = false;
defaultSandbox['allow-popups'] = false;
defaultSandbox['allow-top-navigation'] = false;
}
// 合并用户配置
const finalSandbox = { ...defaultSandbox, ...sandbox };
// 构建属性值
const allowedFeatures = Object.entries(finalSandbox)
.filter(([key, value]) => value)
.map(([key]) => key);
return allowedFeatures.join(' ');
}
// 设置加载监听
setupLoadListeners(sandboxInstance) {
const { iframe, name } = sandboxInstance;
sandboxInstance.loadPromise = new Promise((resolve, reject) => {
const startTime = performance.now();
iframe.onload = () => {
const loadTime = performance.now() - startTime;
sandboxInstance.loadTime = loadTime;
sandboxInstance.status = 'loaded';
console.log(`沙箱加载完成: ${name}, 耗时: ${loadTime.toFixed(2)}ms`);
// 处理消息队列
this.processMessageQueue(sandboxInstance);
resolve(sandboxInstance);
};
iframe.onerror = (error) => {
sandboxInstance.status = 'error';
sandboxInstance.errorCount++;
console.error(`沙箱加载失败: ${name}`, error);
reject(error);
};
// 超时处理
setTimeout(() => {
if (sandboxInstance.status === 'created') {
sandboxInstance.status = 'timeout';
reject(new Error(`沙箱加载超时: ${name}`));
}
}, 10000);
});
}
// 设置通信
setupCommunication(sandboxInstance) {
const { name, communicationProtocol } = sandboxInstance;
if (communicationProtocol === 'postMessage') {
// 注册消息处理器
this.messageHandlers.set(name, (event) => {
this.handleSandboxMessage(sandboxInstance, event);
});
}
}
// 处理沙箱消息
handleSandboxMessage(sandboxInstance, event) {
const { name, allowedOrigins, iframe } = sandboxInstance;
// 验证来源
if (allowedOrigins.length > 0 && !allowedOrigins.includes(event.origin)) {
console.warn(`拒绝来自未授权源的消息: ${event.origin}`);
return;
}
// 验证来源窗口
if (event.source !== iframe.contentWindow) {
console.warn(`消息来源窗口不匹配: ${name}`);
return;
}
try {
const { type, payload, id } = event.data;
// 触发事件
const listeners = sandboxInstance.eventListeners.get(type) || [];
listeners.forEach(listener => {
try {
listener(payload, { sandboxName: name, messageId: id });
} catch (error) {
console.error(`消息处理器错误: ${name}`, error);
}
});
} catch (error) {
console.error(`处理沙箱消息失败: ${name}`, error);
}
}
// 挂载沙箱
async mountSandbox(name) {
const sandbox = this.sandboxes.get(name);
if (!sandbox) {
throw new Error(`沙箱未找到: ${name}`);
}
if (sandbox.status === 'mounted') {
console.warn(`沙箱已挂载: ${name}`);
return sandbox;
}
try {
// 添加到容器
sandbox.container.appendChild(sandbox.iframe);
sandbox.status = 'mounting';
// 等待加载完成
await sandbox.loadPromise;
sandbox.status = 'mounted';
console.log(`沙箱已挂载: ${name}`);
return sandbox;
} catch (error) {
sandbox.status = 'mount_error';
console.error(`挂载沙箱失败: ${name}`, error);
throw error;
}
}
// 卸载沙箱
unmountSandbox(name) {
const sandbox = this.sandboxes.get(name);
if (!sandbox) {
throw new Error(`沙箱未找到: ${name}`);
}
if (sandbox.status !== 'mounted') {
console.warn(`沙箱未挂载: ${name}`);
return;
}
try {
// 从容器移除
if (sandbox.iframe.parentNode) {
sandbox.iframe.parentNode.removeChild(sandbox.iframe);
}
sandbox.status = 'unmounted';
console.log(`沙箱已卸载: ${name}`);
} catch (error) {
console.error(`卸载沙箱失败: ${name}`, error);
throw error;
}
}
// 发送消息到沙箱
sendMessage(name, message) {
const sandbox = this.sandboxes.get(name);
if (!sandbox) {
throw new Error(`沙箱未找到: ${name}`);
}
if (sandbox.status !== 'mounted' && sandbox.status !== 'loaded') {
// 添加到消息队列
sandbox.messageQueue.push(message);
return;
}
try {
const targetOrigin = new URL(sandbox.url).origin;
sandbox.iframe.contentWindow.postMessage(message, targetOrigin);
} catch (error) {
console.error(`发送消息失败: ${name}`, error);
throw error;
}
}
// 处理消息队列
processMessageQueue(sandboxInstance) {
const { messageQueue, name } = sandboxInstance;
while (messageQueue.length > 0) {
const message = messageQueue.shift();
try {
this.sendMessage(name, message);
} catch (error) {
console.error(`处理队列消息失败: ${name}`, error);
}
}
}
// 监听沙箱事件
addEventListener(name, eventType, listener) {
const sandbox = this.sandboxes.get(name);
if (!sandbox) {
throw new Error(`沙箱未找到: ${name}`);
}
if (!sandbox.eventListeners.has(eventType)) {
sandbox.eventListeners.set(eventType, []);
}
sandbox.eventListeners.get(eventType).push(listener);
}
// 移除事件监听
removeEventListener(name, eventType, listener) {
const sandbox = this.sandboxes.get(name);
if (!sandbox) {
return;
}
const listeners = sandbox.eventListeners.get(eventType);
if (listeners) {
const index = listeners.indexOf(listener);
if (index > -1) {
listeners.splice(index, 1);
}
}
}
// 设置全局消息处理器
setupGlobalMessageHandler() {
window.addEventListener('message', (event) => {
// 查找对应的沙箱
for (const [name, sandbox] of this.sandboxes) {
if (event.source === sandbox.iframe.contentWindow) {
const handler = this.messageHandlers.get(name);
if (handler) {
handler(event);
}
break;
}
}
});
}
// 验证沙箱配置
validateSandboxConfig(config) {
const required = ['name', 'url', 'container'];
const missing = required.filter(field => !config[field]);
if (missing.length > 0) {
throw new Error(`沙箱配置缺少必需字段: ${missing.join(', ')}`);
}
if (this.sandboxes.has(config.name)) {
throw new Error(`沙箱名称已存在: ${config.name}`);
}
}
// 销毁沙箱
destroySandbox(name) {
const sandbox = this.sandboxes.get(name);
if (!sandbox) {
return;
}
// 卸载沙箱
if (sandbox.status === 'mounted') {
this.unmountSandbox(name);
}
// 清理资源
sandbox.eventListeners.clear();
sandbox.messageQueue.length = 0;
// 移除消息处理器
this.messageHandlers.delete(name);
// 移除沙箱
this.sandboxes.delete(name);
console.log(`沙箱已销毁: ${name}`);
}
// 获取所有沙箱
getAllSandboxes() {
return Array.from(this.sandboxes.entries()).map(([name, sandbox]) => ({
name,
status: sandbox.status,
url: sandbox.url,
loadTime: sandbox.loadTime,
errorCount: sandbox.errorCount
}));
}
// 获取沙箱性能指标
getPerformanceMetrics() {
const sandboxes = Array.from(this.sandboxes.values());
return {
totalSandboxes: sandboxes.length,
mountedSandboxes: sandboxes.filter(s => s.status === 'mounted').length,
averageLoadTime: sandboxes
.filter(s => s.loadTime)
.reduce((sum, s) => sum + s.loadTime, 0) / sandboxes.length || 0,
totalErrors: sandboxes.reduce((sum, s) => sum + s.errorCount, 0)
};
}
}
4. 状态管理与通信
4.1 全局状态管理
// 微前端全局状态管理器
class MicrofrontendStateManager {
constructor() {
this.globalStore = new Map();
this.subscribers = new Map();
this.stateHistory = [];
this.maxHistorySize = 100;
this.middleware = [];
this.devtools = null;
this.initializeDevtools();
}
// 设置全局状态
setState(key, value, options = {}) {
const {
silent = false,
source = 'unknown',
timestamp = Date.now(),
merge = false
} = options;
const oldValue = this.globalStore.get(key);
// 应用中间件
const action = {
type: 'SET_STATE',
key,
value,
oldValue,
source,
timestamp
};
const processedAction = this.applyMiddleware(action);
if (!processedAction) {
return; // 中间件阻止了状态更新
}
// 合并或替换值
let newValue = processedAction.value;
if (merge && typeof oldValue === 'object' && typeof newValue === 'object') {
newValue = { ...oldValue, ...newValue };
}
// 更新状态
this.globalStore.set(key, newValue);
// 记录历史
this.recordStateChange(key, oldValue, newValue, source, timestamp);
// 通知订阅者
if (!silent) {
this.notifySubscribers(key, newValue, oldValue);
}
// 更新开发工具
this.updateDevtools(action);
}
// 获取全局状态
getState(key) {
return this.globalStore.get(key);
}
// 获取所有状态
getAllState() {
return Object.fromEntries(this.globalStore);
}
// 订阅状态变化
subscribe(key, callback, options = {}) {
const {
immediate = false,
filter = null,
debounce = 0
} = options;
if (!this.subscribers.has(key)) {
this.subscribers.set(key, []);
}
// 包装回调函数
let wrappedCallback = callback;
// 添加过滤器
if (filter) {
const originalCallback = wrappedCallback;
wrappedCallback = (newValue, oldValue) => {
if (filter(newValue, oldValue)) {
originalCallback(newValue, oldValue);
}
};
}
// 添加防抖
if (debounce > 0) {
const originalCallback = wrappedCallback;
let timeoutId;
wrappedCallback = (newValue, oldValue) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
originalCallback(newValue, oldValue);
}, debounce);
};
}
const subscription = {
callback: wrappedCallback,
originalCallback: callback,
options
};
this.subscribers.get(key).push(subscription);
// 立即执行
if (immediate && this.globalStore.has(key)) {
wrappedCallback(this.globalStore.get(key), undefined);
}
// 返回取消订阅函数
return () => {
this.unsubscribe(key, callback);
};
}
// 取消订阅
unsubscribe(key, callback) {
const keySubscribers = this.subscribers.get(key);
if (keySubscribers) {
const index = keySubscribers.findIndex(sub => sub.originalCallback === callback);
if (index > -1) {
keySubscribers.splice(index, 1);
}
}
}
// 通知订阅者
notifySubscribers(key, newValue, oldValue) {
const keySubscribers = this.subscribers.get(key);
if (keySubscribers) {
keySubscribers.forEach(subscription => {
try {
subscription.callback(newValue, oldValue);
} catch (error) {
console.error(`状态订阅回调错误 (${key}):`, error);
}
});
}
// 通知通配符订阅者
const wildcardSubscribers = this.subscribers.get('*');
if (wildcardSubscribers) {
wildcardSubscribers.forEach(subscription => {
try {
subscription.callback({ key, newValue, oldValue });
} catch (error) {
console.error('通配符状态订阅回调错误:', error);
}
});
}
}
// 添加中间件
addMiddleware(middleware) {
this.middleware.push(middleware);
}
// 应用中间件
applyMiddleware(action) {
let processedAction = action;
for (const middleware of this.middleware) {
try {
processedAction = middleware(processedAction, this);
if (!processedAction) {
break; // 中间件阻止了操作
}
} catch (error) {
console.error('中间件执行错误:', error);
}
}
return processedAction;
}
// 记录状态变化
recordStateChange(key, oldValue, newValue, source, timestamp) {
const change = {
key,
oldValue,
newValue,
source,
timestamp
};
this.stateHistory.push(change);
// 限制历史记录大小
if (this.stateHistory.length > this.maxHistorySize) {
this.stateHistory.shift();
}
}
// 获取状态历史
getStateHistory(key) {
if (key) {
return this.stateHistory.filter(change => change.key === key);
}
return [...this.stateHistory];
}
// 重置状态
resetState(key) {
if (key) {
this.globalStore.delete(key);
this.notifySubscribers(key, undefined, this.globalStore.get(key));
} else {
const oldState = this.getAllState();
this.globalStore.clear();
// 通知所有订阅者
for (const [stateKey] of this.subscribers) {
if (stateKey !== '*') {
this.notifySubscribers(stateKey, undefined, oldState[stateKey]);
}
}
}
}
// 批量更新状态
batchUpdate(updates, source = 'batch') {
const timestamp = Date.now();
// 收集所有变化
const changes = [];
for (const [key, value] of Object.entries(updates)) {
const oldValue = this.globalStore.get(key);
this.globalStore.set(key, value);
changes.push({ key, oldValue, newValue: value });
this.recordStateChange(key, oldValue, value, source, timestamp);
}
// 批量通知
changes.forEach(({ key, newValue, oldValue }) => {
this.notifySubscribers(key, newValue, oldValue);
});
// 更新开发工具
this.updateDevtools({
type: 'BATCH_UPDATE',
updates,
source,
timestamp
});
}
// 初始化开发工具
initializeDevtools() {
if (typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION__) {
this.devtools = window.__REDUX_DEVTOOLS_EXTENSION__.connect({
name: 'Microfrontend State Manager'
});
this.devtools.init(this.getAllState());
}
}
// 更新开发工具
updateDevtools(action) {
if (this.devtools) {
this.devtools.send(action, this.getAllState());
}
}
// 创建命名空间状态管理器
createNamespace(namespace) {
return {
setState: (key, value, options = {}) => {
const namespacedKey = `${namespace}.${key}`;
this.setState(namespacedKey, value, { ...options, source: namespace });
},
getState: (key) => {
const namespacedKey = `${namespace}.${key}`;
return this.getState(namespacedKey);
},
subscribe: (key, callback, options = {}) => {
const namespacedKey = `${namespace}.${key}`;
return this.subscribe(namespacedKey, callback, options);
},
resetState: (key) => {
if (key) {
const namespacedKey = `${namespace}.${key}`;
this.resetState(namespacedKey);
} else {
// 重置整个命名空间
const keys = Array.from(this.globalStore.keys())
.filter(k => k.startsWith(`${namespace}.`));
keys.forEach(k => this.resetState(k));
}
}
};
}
}
4.2 应用间通信
// 微前端通信管理器
class MicrofrontendCommunicationManager {
constructor() {
this.channels = new Map();
this.messageQueue = new Map();
this.middleware = [];
this.security = {
allowedOrigins: new Set(),
encryptionKey: null,
validateMessage: null
};
this.setupGlobalMessageHandler();
}
// 创建通信通道
createChannel(name, config = {}) {
const {
persistent = false,
encrypted = false,
maxQueueSize = 100,
timeout = 5000,
retryAttempts = 3
} = config;
const channel = {
name,
subscribers: new Set(),
messageQueue: [],
config: {
persistent,
encrypted,
maxQueueSize,
timeout,
retryAttempts
},
stats: {
messagesSent: 0,
messagesReceived: 0,
errors: 0,
lastActivity: null
}
};
this.channels.set(name, channel);
return {
publish: (message, options) => this.publish(name, message, options),
subscribe: (callback, options) => this.subscribe(name, callback, options),
unsubscribe: (callback) => this.unsubscribe(name, callback),
getStats: () => channel.stats,
destroy: () => this.destroyChannel(name)
};
}
// 发布消息
async publish(channelName, message, options = {}) {
const {
target = '*',
priority = 'normal',
timeout = 5000,
requireAck = false,
metadata = {}
} = options;
const channel = this.channels.get(channelName);
if (!channel) {
throw new Error(`通道未找到: ${channelName}`);
}
// 构建消息对象
const messageObj = {
id: this.generateMessageId(),
channel: channelName,
type: 'message',
payload: message,
target,
priority,
timestamp: Date.now(),
source: this.getCurrentAppName(),
metadata,
requireAck
};
// 应用中间件
const processedMessage = await this.applyMiddleware(messageObj, 'outgoing');
if (!processedMessage) {
return; // 中间件阻止了消息发送
}
try {
// 加密消息(如果需要)
if (channel.config.encrypted) {
processedMessage.payload = await this.encryptMessage(processedMessage.payload);
processedMessage.encrypted = true;
}
// 发送消息
if (target === '*') {
// 广播消息
this.broadcastMessage(processedMessage);
} else {
// 发送到特定目标
this.sendToTarget(processedMessage, target);
}
// 更新统计
channel.stats.messagesSent++;
channel.stats.lastActivity = Date.now();
// 处理确认
if (requireAck) {
return this.waitForAcknowledgment(messageObj.id, timeout);
}
} catch (error) {
channel.stats.errors++;
console.error(`发送消息失败 (${channelName}):`, error);
throw error;
}
}
// 订阅消息
subscribe(channelName, callback, options = {}) {
const {
filter = null,
once = false,
priority = 'normal'
} = options;
let channel = this.channels.get(channelName);
if (!channel) {
// 自动创建通道
this.createChannel(channelName);
channel = this.channels.get(channelName);
}
// 包装回调函数
const wrappedCallback = async (message) => {
try {
// 应用过滤器
if (filter && !filter(message)) {
return;
}
// 解密消息(如果需要)
if (message.encrypted) {
message.payload = await this.decryptMessage(message.payload);
}
// 应用中间件
const processedMessage = await this.applyMiddleware(message, 'incoming');
if (!processedMessage) {
return;
}
// 执行回调
await callback(processedMessage.payload, processedMessage);
// 发送确认(如果需要)
if (message.requireAck) {
this.sendAcknowledgment(message.id, message.source);
}
// 一次性订阅
if (once) {
this.unsubscribe(channelName, callback);
}
} catch (error) {
console.error(`消息处理错误 (${channelName}):`, error);
channel.stats.errors++;
}
};
// 添加订阅者
const subscription = {
callback: wrappedCallback,
originalCallback: callback,
options
};
channel.subscribers.add(subscription);
// 处理持久化消息队列
if (channel.config.persistent && channel.messageQueue.length > 0) {
channel.messageQueue.forEach(queuedMessage => {
wrappedCallback(queuedMessage);
});
}
// 返回取消订阅函数
return () => {
this.unsubscribe(channelName, callback);
};
}
// 取消订阅
unsubscribe(channelName, callback) {
const channel = this.channels.get(channelName);
if (!channel) {
return;
}
for (const subscription of channel.subscribers) {
if (subscription.originalCallback === callback) {
channel.subscribers.delete(subscription);
break;
}
}
}
// 广播消息
broadcastMessage(message) {
// 通过postMessage发送到所有窗口
if (window.parent !== window) {
window.parent.postMessage(message, '*');
}
// 发送到所有iframe
const iframes = document.querySelectorAll('iframe');
iframes.forEach(iframe => {
try {
iframe.contentWindow.postMessage(message, '*');
} catch (error) {
// 忽略跨域错误
}
});
// 本地分发
this.distributeMessage(message);
}
// 发送到特定目标
sendToTarget(message, target) {
// 根据目标类型发送消息
if (target.startsWith('iframe:')) {
const iframeName = target.substring(7);
const iframe = document.querySelector(`iframe[name="${iframeName}"]`);
if (iframe) {
iframe.contentWindow.postMessage(message, '*');
}
} else if (target === 'parent') {
window.parent.postMessage(message, '*');
} else {
// 本地目标
this.distributeMessage(message, target);
}
}
// 分发消息
distributeMessage(message, target = null) {
const channel = this.channels.get(message.channel);
if (!channel) {
return;
}
// 过滤目标订阅者
const targetSubscribers = target
? Array.from(channel.subscribers).filter(sub =>
sub.options.target === target || !sub.options.target)
: Array.from(channel.subscribers);
// 分发消息
targetSubscribers.forEach(subscription => {
subscription.callback(message);
});
// 更新统计
channel.stats.messagesReceived++;
channel.stats.lastActivity = Date.now();
// 持久化消息
if (channel.config.persistent) {
channel.messageQueue.push(message);
// 限制队列大小
if (channel.messageQueue.length > channel.config.maxQueueSize) {
channel.messageQueue.shift();
}
}
}
// 设置全局消息处理器
setupGlobalMessageHandler() {
window.addEventListener('message', (event) => {
// 安全检查
if (!this.validateMessageSecurity(event)) {
return;
}
const message = event.data;
// 检查是否是微前端通信消息
if (message && message.channel && message.type === 'message') {
this.distributeMessage(message);
} else if (message && message.type === 'ack') {
this.handleAcknowledgment(message);
}
});
}
// 验证消息安全性
validateMessageSecurity(event) {
// 检查来源
if (this.security.allowedOrigins.size > 0 &&
!this.security.allowedOrigins.has(event.origin)) {
console.warn(`拒绝来自未授权源的消息: ${event.origin}`);
return false;
}
// 自定义验证
if (this.security.validateMessage) {
return this.security.validateMessage(event);
}
return true;
}
// 等待确认
waitForAcknowledgment(messageId, timeout) {
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
this.messageQueue.delete(messageId);
reject(new Error(`消息确认超时: ${messageId}`));
}, timeout);
this.messageQueue.set(messageId, {
resolve: (ack) => {
clearTimeout(timeoutId);
resolve(ack);
},
reject: (error) => {
clearTimeout(timeoutId);
reject(error);
}
});
});
}
// 发送确认
sendAcknowledgment(messageId, target) {
const ackMessage = {
type: 'ack',
messageId,
timestamp: Date.now(),
source: this.getCurrentAppName()
};
this.sendToTarget(ackMessage, target);
}
// 处理确认
handleAcknowledgment(ackMessage) {
const pending = this.messageQueue.get(ackMessage.messageId);
if (pending) {
this.messageQueue.delete(ackMessage.messageId);
pending.resolve(ackMessage);
}
}
// 生成消息ID
generateMessageId() {
return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
// 获取当前应用名称
getCurrentAppName() {
return window.name || 'unknown';
}
// 销毁通道
destroyChannel(name) {
const channel = this.channels.get(name);
if (channel) {
channel.subscribers.clear();
channel.messageQueue.length = 0;
this.channels.delete(name);
}
}
}
5. 性能优化策略
5.1 资源加载优化
// 微前端性能优化管理器
class MicrofrontendPerformanceOptimizer {
constructor() {
this.loadingStrategies = new Map();
this.resourceCache = new Map();
this.performanceMetrics = {
loadTimes: new Map(),
bundleSizes: new Map(),
errorRates: new Map(),
cacheHitRates: new Map()
};
this.preloadQueue = [];
this.lazyLoadObserver = null;
this.initializeLazyLoading();
}
// 配置加载策略
configureLoadingStrategy(appName, strategy) {
const {
type = 'lazy', // lazy, eager, preload, prefetch
priority = 'normal', // high, normal, low
conditions = [],
timeout = 10000,
retryAttempts = 3,
fallback = null
} = strategy;
this.loadingStrategies.set(appName, {
type,
priority,
conditions,
timeout,
retryAttempts,
fallback,
loadCount: 0,
errorCount: 0,
lastLoadTime: null
});
}
// 智能预加载
async intelligentPreload(apps, options = {}) {
const {
maxConcurrent = 3,
networkThreshold = 'fast-2g',
memoryThreshold = 1024, // MB
batteryThreshold = 0.2
} = options;
// 检查设备条件
const deviceConditions = await this.checkDeviceConditions({
networkThreshold,
memoryThreshold,
batteryThreshold
});
if (!deviceConditions.suitable) {
console.log('设备条件不适合预加载:', deviceConditions.reasons);
return;
}
// 按优先级排序
const sortedApps = this.sortAppsByPriority(apps);
// 分批预加载
const batches = this.createLoadingBatches(sortedApps, maxConcurrent);
for (const batch of batches) {
await Promise.allSettled(
batch.map(app => this.preloadApp(app))
);
// 检查是否需要暂停
const currentConditions = await this.checkDeviceConditions({
networkThreshold,
memoryThreshold,
batteryThreshold
});
if (!currentConditions.suitable) {
console.log('设备条件变化,停止预加载');
break;
}
}
}
// 检查设备条件
async checkDeviceConditions(thresholds) {
const conditions = {
suitable: true,
reasons: []
};
// 检查网络条件
if ('connection' in navigator) {
const connection = navigator.connection;
const networkSpeed = this.getNetworkSpeedRating(connection.effectiveType);
const thresholdSpeed = this.getNetworkSpeedRating(thresholds.networkThreshold);
if (networkSpeed < thresholdSpeed) {
conditions.suitable = false;
conditions.reasons.push(`网络速度过慢: ${connection.effectiveType}`);
}
if (connection.saveData) {
conditions.suitable = false;
conditions.reasons.push('用户启用了数据节省模式');
}
}
// 检查内存条件
if ('memory' in performance) {
const memoryInfo = performance.memory;
const availableMemory = (memoryInfo.jsHeapSizeLimit - memoryInfo.usedJSHeapSize) / 1024 / 1024;
if (availableMemory < thresholds.memoryThreshold) {
conditions.suitable = false;
conditions.reasons.push(`可用内存不足: ${availableMemory.toFixed(2)}MB`);
}
}
// 检查电池条件
if ('getBattery' in navigator) {
try {
const battery = await navigator.getBattery();
if (battery.level < thresholds.batteryThreshold) {
conditions.suitable = false;
conditions.reasons.push(`电池电量过低: ${(battery.level * 100).toFixed(1)}%`);
}
} catch (error) {
// 忽略电池API错误
}
}
return conditions;
}
// 获取网络速度评级
getNetworkSpeedRating(effectiveType) {
const ratings = {
'slow-2g': 1,
'2g': 2,
'3g': 3,
'fast-2g': 4,
'4g': 5
};
return ratings[effectiveType] || 3;
}
// 按优先级排序应用
sortAppsByPriority(apps) {
return apps.sort((a, b) => {
const strategyA = this.loadingStrategies.get(a.name) || { priority: 'normal' };
const strategyB = this.loadingStrategies.get(b.name) || { priority: 'normal' };
const priorityOrder = { high: 3, normal: 2, low: 1 };
return priorityOrder[strategyB.priority] - priorityOrder[strategyA.priority];
});
}
// 创建加载批次
createLoadingBatches(apps, batchSize) {
const batches = [];
for (let i = 0; i < apps.length; i += batchSize) {
batches.push(apps.slice(i, i + batchSize));
}
return batches;
}
// 预加载应用
async preloadApp(app) {
const startTime = performance.now();
try {
// 检查缓存
if (this.resourceCache.has(app.url)) {
console.log(`应用已缓存: ${app.name}`);
return this.resourceCache.get(app.url);
}
// 预加载资源
const resources = await this.preloadResources(app);
// 缓存资源
this.resourceCache.set(app.url, resources);
// 记录性能指标
const loadTime = performance.now() - startTime;
this.recordLoadTime(app.name, loadTime);
console.log(`应用预加载完成: ${app.name}, 耗时: ${loadTime.toFixed(2)}ms`);
return resources;
} catch (error) {
console.error(`应用预加载失败: ${app.name}`, error);
this.recordError(app.name);
throw error;
}
}
// 预加载资源
async preloadResources(app) {
const resources = {
scripts: [],
styles: [],
manifest: null
};
// 获取应用清单
if (app.manifestUrl) {
resources.manifest = await this.fetchResource(app.manifestUrl, 'json');
}
// 预加载脚本
if (app.scripts) {
resources.scripts = await Promise.all(
app.scripts.map(url => this.preloadScript(url))
);
}
// 预加载样式
if (app.styles) {
resources.styles = await Promise.all(
app.styles.map(url => this.preloadStyle(url))
);
}
return resources;
}
// 预加载脚本
async preloadScript(url) {
return new Promise((resolve, reject) => {
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'script';
link.href = url;
link.crossOrigin = 'anonymous';
link.onload = () => resolve(url);
link.onerror = () => reject(new Error(`脚本预加载失败: ${url}`));
document.head.appendChild(link);
});
}
// 预加载样式
async preloadStyle(url) {
return new Promise((resolve, reject) => {
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'style';
link.href = url;
link.crossOrigin = 'anonymous';
link.onload = () => resolve(url);
link.onerror = () => reject(new Error(`样式预加载失败: ${url}`));
document.head.appendChild(link);
});
}
// 获取资源
async fetchResource(url, type = 'text') {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`资源获取失败: ${url}`);
}
switch (type) {
case 'json':
return response.json();
case 'blob':
return response.blob();
case 'arrayBuffer':
return response.arrayBuffer();
default:
return response.text();
}
}
// 初始化懒加载
initializeLazyLoading() {
if ('IntersectionObserver' in window) {
this.lazyLoadObserver = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const appName = entry.target.dataset.appName;
if (appName) {
this.triggerLazyLoad(appName);
this.lazyLoadObserver.unobserve(entry.target);
}
}
});
},
{
rootMargin: '100px',
threshold: 0.1
}
);
}
}
// 触发懒加载
async triggerLazyLoad(appName) {
const strategy = this.loadingStrategies.get(appName);
if (!strategy || strategy.type !== 'lazy') {
return;
}
try {
await this.preloadApp({ name: appName, url: strategy.url });
} catch (error) {
console.error(`懒加载失败: ${appName}`, error);
}
}
// 记录加载时间
recordLoadTime(appName, loadTime) {
if (!this.performanceMetrics.loadTimes.has(appName)) {
this.performanceMetrics.loadTimes.set(appName, []);
}
const times = this.performanceMetrics.loadTimes.get(appName);
times.push(loadTime);
// 保持最近100次记录
if (times.length > 100) {
times.shift();
}
}
// 记录错误
recordError(appName) {
const current = this.performanceMetrics.errorRates.get(appName) || 0;
this.performanceMetrics.errorRates.set(appName, current + 1);
}
// 获取性能报告
getPerformanceReport() {
const report = {
apps: {},
overall: {
totalApps: this.loadingStrategies.size,
cachedApps: this.resourceCache.size,
averageLoadTime: 0,
totalErrors: 0
}
};
// 计算每个应用的指标
for (const [appName, strategy] of this.loadingStrategies) {
const loadTimes = this.performanceMetrics.loadTimes.get(appName) || [];
const errorCount = this.performanceMetrics.errorRates.get(appName) || 0;
report.apps[appName] = {
strategy: strategy.type,
priority: strategy.priority,
loadCount: strategy.loadCount,
errorCount,
averageLoadTime: loadTimes.length > 0
? loadTimes.reduce((sum, time) => sum + time, 0) / loadTimes.length
: 0,
cached: this.resourceCache.has(appName)
};
report.overall.totalErrors += errorCount;
}
// 计算总体平均加载时间
const allLoadTimes = Array.from(this.performanceMetrics.loadTimes.values())
.flat();
if (allLoadTimes.length > 0) {
report.overall.averageLoadTime =
allLoadTimes.reduce((sum, time) => sum + time, 0) / allLoadTimes.length;
}
return report;
}
// 清理缓存
clearCache(pattern) {
if (pattern) {
const regex = new RegExp(pattern);
for (const [key] of this.resourceCache) {
if (regex.test(key)) {
this.resourceCache.delete(key);
}
}
} else {
this.resourceCache.clear();
}
}
}
6. 最佳实践与总结
6.1 架构设计原则
微前端架构设计最佳实践
// 微前端架构最佳实践管理器
class MicrofrontendBestPracticesManager {
constructor() {
this.designPrinciples = {
independence: {
name: '独立性原则',
description: '每个微前端应用应该能够独立开发、测试、部署和运行',
guidelines: [
'避免共享可变状态',
'使用独立的构建流程',
'保持技术栈的灵活性',
'实现独立的错误边界'
]
},
consistency: {
name: '一致性原则',
description: '在用户体验和开发体验上保持一致性',
guidelines: [
'统一的设计系统',
'一致的路由策略',
'标准化的通信协议',
'统一的错误处理'
]
},
performance: {
name: '性能优化原则',
description: '确保微前端架构不会显著影响应用性能',
guidelines: [
'智能的资源加载策略',
'有效的缓存机制',
'代码分割和懒加载',
'性能监控和优化'
]
},
maintainability: {
name: '可维护性原则',
description: '保持代码的可维护性和可扩展性',
guidelines: [
'清晰的应用边界',
'标准化的开发流程',
'完善的文档和测试',
'版本管理和兼容性'
]
}
};
this.commonPitfalls = [
{
name: '过度拆分',
description: '将应用拆分得过于细粒度',
solution: '基于业务域和团队结构进行合理拆分'
},
{
name: '共享状态滥用',
description: '过度依赖全局状态共享',
solution: '优先使用事件通信,谨慎使用全局状态'
},
{
name: '技术栈不一致',
description: '不同应用使用完全不同的技术栈',
solution: '在灵活性和一致性之间找到平衡'
},
{
name: '性能问题',
description: '忽视了微前端带来的性能开销',
solution: '实施性能监控和优化策略'
}
];
}
// 评估架构设计
evaluateArchitecture(config) {
const evaluation = {
score: 0,
maxScore: 100,
recommendations: [],
strengths: [],
weaknesses: []
};
// 评估独立性
const independenceScore = this.evaluateIndependence(config);
evaluation.score += independenceScore.score;
evaluation.recommendations.push(...independenceScore.recommendations);
// 评估一致性
const consistencyScore = this.evaluateConsistency(config);
evaluation.score += consistencyScore.score;
evaluation.recommendations.push(...consistencyScore.recommendations);
// 评估性能
const performanceScore = this.evaluatePerformance(config);
evaluation.score += performanceScore.score;
evaluation.recommendations.push(...performanceScore.recommendations);
// 评估可维护性
const maintainabilityScore = this.evaluateMaintainability(config);
evaluation.score += maintainabilityScore.score;
evaluation.recommendations.push(...maintainabilityScore.recommendations);
// 生成总体评价
evaluation.grade = this.calculateGrade(evaluation.score);
return evaluation;
}
// 评估独立性
evaluateIndependence(config) {
const result = { score: 0, recommendations: [] };
const maxScore = 25;
// 检查应用拆分策略
if (config.splitStrategy && config.splitStrategy !== 'monolithic') {
result.score += 8;
} else {
result.recommendations.push('建议采用合适的应用拆分策略');
}
// 检查技术栈独立性
if (config.allowDifferentTechStacks) {
result.score += 6;
} else {
result.recommendations.push('考虑允许不同应用使用不同技术栈');
}
// 检查部署独立性
if (config.independentDeployment) {
result.score += 6;
} else {
result.recommendations.push('实现独立部署能力');
}
// 检查错误隔离
if (config.errorBoundaries) {
result.score += 5;
} else {
result.recommendations.push('实现应用级错误边界');
}
return result;
}
// 评估一致性
evaluateConsistency(config) {
const result = { score: 0, recommendations: [] };
const maxScore = 25;
// 检查设计系统
if (config.designSystem) {
result.score += 8;
} else {
result.recommendations.push('建立统一的设计系统');
}
// 检查路由策略
if (config.routingStrategy && config.routingStrategy !== 'none') {
result.score += 6;
} else {
result.recommendations.push('制定统一的路由策略');
}
// 检查通信协议
if (config.communicationProtocol) {
result.score += 6;
} else {
result.recommendations.push('标准化应用间通信协议');
}
// 检查开发规范
if (config.developmentStandards) {
result.score += 5;
} else {
result.recommendations.push('制定开发规范和标准');
}
return result;
}
// 评估性能
evaluatePerformance(config) {
const result = { score: 0, recommendations: [] };
const maxScore = 25;
// 检查加载策略
if (config.loadingStrategy && config.loadingStrategy !== 'eager') {
result.score += 8;
} else {
result.recommendations.push('实施智能加载策略(懒加载、预加载)');
}
// 检查缓存策略
if (config.cachingStrategy) {
result.score += 6;
} else {
result.recommendations.push('实现有效的缓存机制');
}
// 检查代码分割
if (config.codeSplitting) {
result.score += 6;
} else {
result.recommendations.push('实施代码分割和按需加载');
}
// 检查性能监控
if (config.performanceMonitoring) {
result.score += 5;
} else {
result.recommendations.push('建立性能监控体系');
}
return result;
}
// 评估可维护性
evaluateMaintainability(config) {
const result = { score: 0, recommendations: [] };
const maxScore = 25;
// 检查文档
if (config.documentation) {
result.score += 8;
} else {
result.recommendations.push('完善架构和API文档');
}
// 检查测试策略
if (config.testingStrategy) {
result.score += 6;
} else {
result.recommendations.push('制定全面的测试策略');
}
// 检查版本管理
if (config.versionManagement) {
result.score += 6;
} else {
result.recommendations.push('实施版本管理和兼容性策略');
}
// 检查监控和日志
if (config.monitoringAndLogging) {
result.score += 5;
} else {
result.recommendations.push('建立监控和日志系统');
}
return result;
}
// 计算等级
calculateGrade(score) {
if (score >= 90) return 'A+';
if (score >= 80) return 'A';
if (score >= 70) return 'B+';
if (score >= 60) return 'B';
if (score >= 50) return 'C+';
if (score >= 40) return 'C';
return 'D';
}
// 生成实施建议
generateImplementationPlan(evaluation) {
const plan = {
phases: [],
timeline: '6-12个月',
resources: [],
risks: []
};
// 第一阶段:基础设施
plan.phases.push({
name: '基础设施建设',
duration: '2-3个月',
tasks: [
'选择微前端技术方案',
'建立开发和部署流程',
'实现基础的应用加载器',
'建立监控和日志系统'
]
});
// 第二阶段:应用拆分
plan.phases.push({
name: '应用拆分',
duration: '2-3个月',
tasks: [
'分析现有应用架构',
'制定拆分策略',
'逐步拆分核心功能',
'实现应用间通信'
]
});
// 第三阶段:优化完善
plan.phases.push({
name: '优化完善',
duration: '2-3个月',
tasks: [
'性能优化',
'用户体验优化',
'完善测试覆盖',
'文档和培训'
]
});
return plan;
}
}
6.2 核心价值与收益
微前端架构为现代前端开发带来了显著的价值和收益:
技术收益
- 技术栈灵活性:不同团队可以选择最适合的技术栈
- 独立部署:应用可以独立发布,降低部署风险
- 代码隔离:应用间代码完全隔离,避免相互影响
- 渐进式升级:可以逐步升级或重构单个应用
团队收益
- 团队自治:团队可以独立决策和开发
- 并行开发:多个团队可以同时开发不同功能
- 责任明确:每个团队负责特定的业务域
- 技能专业化:团队可以专注于特定技术领域
业务收益
- 快速迭代:功能可以独立快速上线
- 风险隔离:单个应用的问题不会影响整体
- 扩展性强:可以根据业务需要灵活扩展
- 维护成本低:降低了大型应用的维护复杂度
结语
微前端架构作为现代前端开发的重要趋势,为解决大型应用的复杂性问题提供了有效方案。通过本文的深度实践,我们探讨了从架构设计到技术实现的完整解决方案。
成功实施微前端架构需要在技术选型、团队协作、性能优化等多个维度进行综合考虑。关键在于找到独立性与一致性、灵活性与标准化之间的平衡点。
随着前端技术的不断发展,微前端架构也在持续演进。未来我们可以期待更多标准化的解决方案、更好的开发工具支持,以及与云原生、边缘计算等新技术的深度融合。
更多推荐



所有评论(0)