微前端
介绍
微前端(Micro Frontends)是一种架构模式,它将大型前端应用拆分为多个独立、可维护的小型前端应用,每个应用可以由不同的团队开发、部署和维护。微前端允许团队使用不同的技术栈、独立发布,并保持代码库的小型化和可维护性。
核心价值
- 技术栈无关:各团队可以选择最适合自己的技术栈
- 独立部署:每个微应用可以独立部署,不会影响其他应用
- 代码隔离:避免代码冲突和依赖地狱
- 团队自治:提高团队自主性和开发效率
- 增量升级:可以逐步迁移旧系统,降低风险
- 可扩展性:更容易扩展和维护大型应用
- 故障隔离:一个微应用的故障不会影响整个系统
架构模式
1. 基座模式(Host-Child)
- 有一个主应用(基座)负责加载和管理多个子应用
- 子应用可以独立开发和部署
- 主应用提供共享资源和通信机制
2. 路由分发模式
- 通过路由将请求分发到不同的微应用
- 每个微应用有自己的路由系统
- 适合完全独立的页面
3. 微件模式(Micro Widgets)
- 将应用拆分为独立的组件(微件)
- 微件可以嵌入到任何页面中
- 适合跨应用共享的UI组件
4. 组合式应用路由
- 结合了基座模式和路由分发模式的优点
- 支持更复杂的应用场景
实现方案
1. Single-SPA
Single-SPA是最早的微前端框架之一,它允许在同一个页面中加载多个框架。
// 主应用配置
import { registerApplication, start } from 'single-spa';
// 注册子应用
registerApplication(
'react-app',
() => import('./src/react-app.js'),
location => location.pathname.startsWith('/react')
);
registerApplication(
'vue-app',
() => import('./src/vue-app.js'),
location => location.pathname.startsWith('/vue')
);
// 启动应用
start();
// React子应用配置
import React from 'react';
import ReactDOM from 'react-dom';
import singleSpaReact from 'single-spa-react';
import App from './App';
const lifecycles = singleSpaReact({
React,
ReactDOM,
rootComponent: App,
errorBoundary(err, info, props) {
return <div>发生错误: {err.message}</div>;
}
});
export const { bootstrap, mount, unmount } = lifecycles;
// Vue子应用配置
import Vue from 'vue';
import singleSpaVue from 'single-spa-vue';
import App from './App.vue';
const vueLifecycles = singleSpaVue({
Vue,
appOptions: {
render: h => h(App)
}
});
export const { bootstrap, mount, unmount } = vueLifecycles;
2. Qiankun
Qiankun是阿里巴巴开源的微前端框架,基于Single-SPA,提供了更完善的功能。
// 主应用配置
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'react-app',
entry: '//localhost:3001',
container: '#container',
activeRule: '/react'
},
{
name: 'vue-app',
entry: '//localhost:3002',
container: '#container',
activeRule: '/vue'
}
]);
// 启动qiankun
start();
// React子应用配置
import { registerMicroApps, start } from 'qiankun';
if (window.__POWERED_BY_QIANKUN__) {
__webpack_share_scopes__('default', {
react: {
singleton: true,
requiredVersion: deps.react,
import: () => {
return Promise.resolve().then(() => ({
default: React,
}));
},
},
});
}
function render(props) {
const { container } = props;
ReactDOM.render(
<App />,
container ? container.querySelector('#root') : document.querySelector('#root')
);
}
export async function bootstrap() {
console.log('react app bootstraped');
}
export async function mount(props) {
console.log('react app mounted', props);
render(props);
}
export async function unmount(props) {
console.log('react app unmounted', props);
ReactDOM.unmountComponentAtNode(props.container.querySelector('#root'));
}
3. Web Components
使用Web Components实现微前端,无需额外框架。
// 定义微组件
class MicroWidget extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
connectedCallback() {
// 加载组件内容
this.loadContent();
}
async loadContent() {
try {
// 从CDN或其他来源加载组件
const response = await fetch('https://example.com/micro-widget-content');
const html = await response.text();
this.shadowRoot.innerHTML = html;
// 加载CSS
const style = document.createElement('style');
style.textContent = await fetch('https://example.com/micro-widget-style.css').then(res => res.text());
this.shadowRoot.appendChild(style);
// 加载JavaScript
const script = document.createElement('script');
script.textContent = await fetch('https://example.com/micro-widget-script.js').then(res => res.text());
this.shadowRoot.appendChild(script);
} catch (error) {
console.error('Failed to load micro widget:', error);
}
}
}
// 注册组件
customElements.define('micro-widget', MicroWidget);
// 使用微组件
// 在HTML中:
// <micro-widget></micro-widget>
方案对比
| 框架 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| Single-SPA | 成熟稳定,支持多种框架 | 配置复杂,需要手动处理共享依赖 | 简单的微前端场景 |
| Qiankun | 功能完善,开箱即用,支持依赖共享 | 基于Single-SPA,有一定学习曲线 | 中大型应用,企业级项目 |
| Web Components | 原生支持,无需额外框架 | 浏览器兼容性问题,功能相对简单 | 简单的微组件场景 |
| Module Federation | Webpack原生支持,无需额外依赖 | 仅支持Webpack,生态相对较新 | 使用Webpack的项目 |
| 自研框架 | 完全定制化,符合特定需求 | 开发和维护成本高,风险大 | 有特殊需求的大型项目 |
最佳实践
1. 合理划分微应用
- 按业务域划分:基于清晰的业务边界划分微应用,例如电商应用可分为商品、订单、用户、支付等微应用
- 规模控制:每个微应用代码量建议控制在10万行以内,团队人数不超过10人
- 避免过度拆分:不要将功能过度拆分,导致微应用数量过多,增加维护成本
- 示例:
// 基于业务域的微应用划分
const microApps = [
{ name: 'product', entry: '//localhost:3001', container: '#container', activeRule: '/product' },
{ name: 'order', entry: '//localhost:3002', container: '#container', activeRule: '/order' },
{ name: 'user', entry: '//localhost:3003', container: '#container', activeRule: '/user' },
{ name: 'payment', entry: '//localhost:3004', container: '#container', activeRule: '/payment' }
];
2. 共享依赖管理
- 提取公共依赖:将React、Vue等框架和常用库提取为共享依赖
- 版本控制:确保共享依赖的版本一致性,避免版本冲突
- 按需加载:使用Webpack的externals或Module Federation实现共享依赖的按需加载
- 示例(Qiankun共享依赖):
// 主应用配置共享依赖
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{ name: 'app1', entry: '//localhost:3001', container: '#container', activeRule: '/app1' },
{ name: 'app2', entry: '//localhost:3002', container: '#container', activeRule: '/app2' }
], {
// 共享依赖配置
shared: {
react: {
singleton: true,
requiredVersion: '^17.0.0'
},
'react-dom': {
singleton: true,
requiredVersion: '^17.0.0'
}
}
});
3. 样式隔离
- CSS Modules:使用CSS Modules实现组件级样式隔离
- Shadow DOM:对于Web Components微应用,使用Shadow DOM实现样式隔离
- 命名空间:为每个微应用添加唯一的CSS命名空间前缀
- CSS-in-JS:使用Styled Components、Emotion等库实现样式隔离
- PostCSS插件:使用postcss-plugin-namespace等插件自动添加命名空间
- 示例(CSS Modules):
/* styles.module.css */
.container {
padding: 20px;
background-color: #f5f5f5;
}
.title {
font-size: 24px;
color: #333;
}
// 使用CSS Modules
import styles from './styles.module.css';
function App() {
return (
<div className={styles.container}>
<h1 className={styles.title}>微应用标题</h1>
</div>
);
}
4. 通信机制
- 发布-订阅模式:实现全局事件总线,支持微应用间通信
- 共享状态管理:使用Redux、Vuex等状态管理库实现跨应用状态共享
- URL参数:通过URL参数传递简单数据
- LocalStorage/SessionStorage:使用存储API共享数据
- 接口调用:通过封装的API接口进行通信
- 示例(增强版事件总线):
// 增强版事件总线,支持类型安全和命名空间
class EventBus {
constructor(namespace = 'global') {
this.namespace = namespace;
this.events = {};
}
on(event, callback) {
const key = `${this.namespace}:${event}`;
if (!this.events[key]) {
this.events[key] = [];
}
this.events[key].push(callback);
return () => this.off(event, callback); // 返回取消订阅函数
}
emit(event, data) {
const key = `${this.namespace}:${event}`;
if (this.events[key]) {
this.events[key].forEach(callback => {
try {
callback(data);
} catch (error) {
console.error(`Error in event listener for ${key}:`, error);
}
});
}
}
off(event, callback) {
const key = `${this.namespace}:${event}`;
if (this.events[key]) {
this.events[key] = this.events[key].filter(cb => cb !== callback);
}
}
clear() {
this.events = {};
}
}
// 创建全局事件总线实例
const globalEventBus = new EventBus();
export default globalEventBus;
5. 版本控制
- 语义化版本:遵循语义化版本规范(MAJOR.MINOR.PATCH)
- 版本标识:在微应用入口文件中添加版本标识
- 版本检查:主应用加载微应用时进行版本兼容性检查
- 示例:
// 微应用入口文件中添加版本标识
const appVersion = '1.2.3';
// 导出供主应用检查的版本信息
export const version = appVersion;
// 主应用版本检查
function checkVersionCompatibility(appName, appVersion) {
// 从配置中心获取兼容版本范围
const compatibleVersions = getCompatibleVersions(appName);
// 检查版本兼容性
return isVersionCompatible(appVersion, compatibleVersions);
}
6. 独立部署
- CI/CD管道:为每个微应用建立独立的CI/CD管道
- 自动化测试:部署前执行自动化测试
- 灰度发布:支持灰度发布和金丝雀测试
- 自动回滚:监控部署后性能和错误率,异常时自动回滚
- 示例(GitLab CI/CD配置):
# .gitlab-ci.yml
stages:
- test
- build
- deploy
test:
stage: test
script:
- npm install
- npm run test
build:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
deploy:
stage: deploy
script:
- echo "Deploying to production"
- scp -r dist/* user@server:/path/to/deployment/
environment:
name: production
when: manual
7. 统一构建和CI/CD
- 共享构建配置:提取共享的Webpack、Babel配置
- 统一CI/CD模板:使用统一的CI/CD模板,确保一致性
- 构建缓存:使用构建缓存加速构建过程
- 并行构建:支持多微应用并行构建
- 示例(共享Webpack配置):
// webpack.shared.js - 共享Webpack配置
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'production',
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource'
}
]
},
resolve: {
extensions: ['.js', '.jsx', '.json']
}
};
// 微应用webpack.config.js
const { merge } = require('webpack-merge');
const sharedConfig = require('./webpack.shared');
module.exports = merge(sharedConfig, {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html'
})
]
});
8. 监控和日志
- 错误监控:使用Sentry等工具监控前端错误
- 性能监控:监控首屏加载时间、白屏时间等指标
- 用户行为分析:追踪用户交互和转化率
- 日志聚合:使用ELK等工具聚合和分析日志
- 告警机制:设置异常指标告警阈值
- 示例(Sentry集成):
// 主应用中初始化Sentry
import * as Sentry from '@sentry/browser';
import { Integrations } from '@sentry/tracing';
Sentry.init({
dsn: 'https://your-dsn@sentry.io/12345',
integrations: [
new Integrations.BrowserTracing()
],
tracesSampleRate: 1.0
});
// 微应用中使用Sentry
// 无需重复初始化,直接使用
import * as Sentry from '@sentry/browser';
try {
// 可能出错的代码
} catch (error) {
Sentry.captureException(error, {
tags: {
microApp: 'app1',
version: '1.2.3'
}
});
}
9. 文档和规范
- API文档:为微应用间通信API编写详细文档
- 架构文档:绘制架构图,说明微应用间关系
- 开发规范:制定统一的代码规范、命名规范
- README模板:为每个微应用提供统一的README模板
- 示例(API文档):
# 微应用通信API文档
## 事件总线
### 用户登录事件
- 事件名: `user:login`
- 触发时机: 用户成功登录后
- 数据结构:
```javascript
{
userId: string, // 用户ID
username: string, // 用户名
token: string, // 认证令牌
roles: string[] // 用户角色
}
- 示例:
// 发布事件
eventBus.emit('user:login', {
userId: '123',
username: 'John',
token: 'abc123',
roles: ['admin', 'user']
});
// 订阅事件
eventBus.on('user:login', (data) => {
console.log('用户登录:', data.username);
});
## 性能优化
### 1. 懒加载
- **路由懒加载**:使用动态import()实现路由懒加载
- **组件懒加载**:按需加载非首屏组件
- **微应用懒加载**:仅在访问时加载对应微应用
- **预加载关键资源**:使用`<link rel="preload">`预加载关键资源
- **示例(微应用懒加载)**:
```javascript
// 使用动态import延迟加载微应用
registerApplication(
'heavy-app',
() => import('./src/heavy-app.js'), // 懒加载
location => location.pathname.startsWith('/heavy')
);
// 路由懒加载(React)
import { lazy, Suspense } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = lazy(() => import('./Home'));
const About = lazy(() => import('./About'));
function App() {
return (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Switch>
</Suspense>
</Router>
);
}
2. 预加载策略
- 预测性预加载:根据用户行为预测即将访问的微应用并预加载
- 空闲时预加载:利用requestIdleCallback在浏览器空闲时预加载
- 视口预加载:当微应用入口元素进入视口时预加载
- 示例(预测性预加载):
// 主应用中实现预测性预加载
function preloadMicroApp(appName) {
// 检查是否已加载
if (isAppLoaded(appName)) return;
// 根据appName获取微应用配置
const appConfig = getAppConfig(appName);
if (!appConfig) return;
// 预加载微应用资源
const link = document.createElement('link');
link.rel = 'preload';
link.as = 'script';
link.href = appConfig.entry;
document.head.appendChild(link);
console.log(`Preloaded micro app: ${appName}`);
}
// 监听用户行为,预测可能访问的微应用
document.addEventListener('mouseover', (e) => {
if (e.target.matches('[data-preload-app]')) {
const appName = e.target.getAttribute('data-preload-app');
preloadMicroApp(appName);
}
});
3. 共享依赖优化
- 按需加载共享依赖:只加载微应用实际使用的依赖部分
- 依赖预构建:使用Webpack 5的module federation预构建共享依赖
- 版本统一:确保所有微应用使用相同版本的共享依赖
- 示例(Webpack 5 Module Federation):
// 主应用webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'host',
remotes: {
app1: 'app1@http://localhost:3001/remoteEntry.js',
app2: 'app2@http://localhost:3002/remoteEntry.js'
},
shared: {
react: {
singleton: true,
requiredVersion: '^17.0.0'
},
'react-dom': {
singleton: true,
requiredVersion: '^17.0.0'
}
}
})
]
};
// 微应用webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container;
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'app1',
filename: 'remoteEntry.js',
exposes: {
'./App': './src/App'
},
shared: {
react: {
singleton: true,
requiredVersion: '^17.0.0'
},
'react-dom': {
singleton: true,
requiredVersion: '^17.0.0'
}
}
})
]
};
4. 资源缓存策略
- 强缓存:设置合理的Cache-Control和Expires头
- 协商缓存:使用ETag和Last-Modified实现协商缓存
- CDN加速:将静态资源部署到CDN
- Service Worker缓存:使用Service Worker缓存关键资源
- 示例(Service Worker缓存):
// service-worker.js
const CACHE_NAME = 'micro-app-cache-v1';
const PRECACHE_URLS = [
'/',
'/index.html',
'/main.js',
'/styles.css',
'/logo.png'
];
// 安装阶段:缓存关键资源
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(PRECACHE_URLS))
.then(() => self.skipWaiting())
);
});
// 激活阶段:清理旧缓存
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cacheName => {
if (cacheName !== CACHE_NAME) {
return caches.delete(cacheName);
}
})
);
})
);
});
// 拦截请求:缓存优先策略
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request)
.then(response => {
if (response) {
return response; // 缓存命中
}
return fetch(event.request).then(
networkResponse => {
// 缓存新请求的响应
caches.open(CACHE_NAME).then(cache => {
cache.put(event.request, networkResponse.clone());
});
return networkResponse;
}
).catch(() => {
// 网络错误时的降级处理
return caches.match('/offline.html');
});
})
);
});
5. 代码拆分与优化
- 按路由拆分:将不同路由的代码拆分为独立的chunk
- 按组件拆分:将大型组件拆分为更小的可复用组件
- 树摇(Tree Shaking):移除未使用的代码
- 代码压缩:使用Terser等工具压缩JavaScript代码
- 示例(Webpack代码拆分):
// webpack.config.js
module.exports = {
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\/]node_modules[\/]/,
name: 'vendors',
chunks: 'all'
},
common: {
minChunks: 2,
name: 'common',
chunks: 'all',
priority: -10,
reuseExistingChunk: true
}
}
}
}
};
6. 通信性能优化
- 批量通信:将多个小消息合并为一个批量消息
- 节流和防抖:对频繁触发的事件进行节流或防抖处理
- 避免不必要的通信:仅传递必要的数据,避免过度通信
- 使用更高效的数据格式:如Protocol Buffers代替JSON
- 示例(批量通信):
// 批量事件处理器
class BatchedEventProcessor {
constructor(batchTime = 100) {
this.batchTime = batchTime;
this.queue = [];
this.timer = null;
}
add(event) {
this.queue.push(event);
this.scheduleFlush();
}
scheduleFlush() {
if (!this.timer) {
this.timer = setTimeout(() => {
this.flush();
}, this.batchTime);
}
}
flush() {
if (this.queue.length === 0) {
this.timer = null;
return;
}
const batch = [...this.queue];
this.queue = [];
this.timer = null;
// 处理批量事件
eventBus.emit('batch:process', batch);
}
}
// 使用示例
const batchedProcessor = new BatchedEventProcessor();
// 添加事件到批量处理器
batchedProcessor.add({ type: 'click', data: { x: 100, y: 200 } });
batchedProcessor.add({ type: 'hover', data: { element: 'button' } });
7. 服务端渲染(SSR)优化
- 关键页面SSR:对首屏和关键页面实施SSR
- 静态生成(SSG):对不常变化的页面使用静态生成
- 增量静态再生(ISR):定期重新生成静态页面
- 服务器缓存:对SSR结果进行缓存
- 示例(Next.js中使用ISR):
// pages/products/[id].js
export default function Product({ product }) {
return (
<div>
<h1>{product.title}</h1>
<p>{product.description}</p>
<p>Price: ${product.price}</p>
</div>
);
}
export async function getStaticPaths() {
// 获取所有产品ID
const res = await fetch('https://api.example.com/products');
const products = await res.json();
const paths = products.map(product => ({
params: { id: product.id.toString() }
}));
return {
paths,
fallback: 'blocking' // 对未预生成的页面进行按需生成
};
}
export async function getStaticProps({ params }) {
const res = await fetch(`https://api.example.com/products/${params.id}`);
const product = await res.json();
return {
props: { product },
revalidate: 60 // 每60秒重新生成页面
};
}
8. 性能监控与分析
- 核心性能指标:监控LCP、FID、CLS等Web Vitals指标
- 自定义性能指标:监控微应用加载时间、组件渲染时间等
- 性能分析工具:使用Chrome DevTools、Lighthouse等工具进行分析
- 性能可视化:将性能数据可视化,便于分析和优化
- 示例(监控Web Vitals):
// 监控Web Vitals
import { getCLS, getFID, getLCP } from 'web-vitals';
function sendToAnalytics(metric) {
const body = JSON.stringify(metric);
// 发送到分析服务
navigator.sendBeacon('/analytics', body);
}
getCLS(sendToAnalytics);
getFID(sendToAnalytics);
getLCP(sendToAnalytics);
// 自定义性能指标 - 微应用加载时间
function measureAppLoadTime(appName) {
const startTime = performance.now();
// 微应用加载完成后调用
return function() {
const loadTime = performance.now() - startTime;
console.log(`${appName} loaded in ${loadTime.toFixed(2)}ms`);
// 发送到分析服务
sendToAnalytics({
name: `app_load_time_${appName}`,
value: loadTime,
rating: loadTime < 1000 ? 'good' : loadTime < 2000 ? 'needs-improvement' : 'poor'
});
};
}
// 使用示例
const appLoadedCallback = measureAppLoadTime('app1');
// 微应用加载完成后调用
appLoadedCallback();
9. 渲染优化
- 虚拟滚动:对长列表使用虚拟滚动,仅渲染可见区域
- 按需渲染:仅在需要时渲染组件
- 避免不必要的重渲染:使用React.memo、useMemo等优化渲染性能
- CSS动画优化:使用transform和opacity实现高性能动画
- 示例(React虚拟滚动):
import { useState, useRef, useEffect } from 'react';
import { FixedSizeList as List } from 'react-window';
function VirtualizedList({ items }) {
return (
<List
height={400}
itemCount={items.length}
itemSize={40}
width="100%"
>
{({ index, style }) => (
<div style={style} className="list-item">
{items[index]}
</div>
)}
</List>
);
}
// 使用示例
function App() {
const [data, setData] = useState([]);
useEffect(() => {
// 模拟加载大量数据
const largeData = Array.from({ length: 10000 }, (_, i) => `Item ${i + 1}`);
setData(largeData);
}, []);
return (
<div className="app">
<h1>虚拟滚动列表</h1>
<VirtualizedList items={data} />
</div>
);
}
10. 网络请求优化
- 请求合并:合并多个相似请求
- 请求缓存:缓存API响应,避免重复请求
- CDN加速:使用CDN加速API请求
- HTTP/2多路复用:利用HTTP/2的多路复用特性
- 示例(请求缓存):
// 带缓存的fetch函数
const requestCache = new Map();
async function fetchWithCache(url, options = {}) {
const cacheKey = `${url}:${JSON.stringify(options)}`;
// 检查缓存
if (requestCache.has(cacheKey)) {
const cachedResponse = requestCache.get(cacheKey);
// 检查缓存是否过期
if (cachedResponse.expires > Date.now()) {
console.log(`Cache hit for ${url}`);
return cachedResponse.data;
}
// 缓存过期,移除
requestCache.delete(cacheKey);
}
// 发送请求
console.log(`Cache miss for ${url}, fetching...`);
const response = await fetch(url, options);
const data = await response.json();
// 缓存响应,默认1分钟
const ttl = options.ttl || 60000;
requestCache.set(cacheKey, {
data,
expires: Date.now() + ttl
});
return data;
}
// 使用示例
fetchWithCache('https://api.example.com/products', {
ttl: 300000 // 5分钟缓存
}).then(products => {
console.log(products);
});
通信机制
1. 发布-订阅模式
// 事件总线实现
class EventBus {
constructor() {
this.events = {};
}
on(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
}
emit(event, data) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(data));
}
}
off(event, callback) {
if (this.events[event]) {
this.events[event] = this.events[event].filter(cb => cb !== callback);
}
}
}
// 创建全局事件总线
const eventBus = new EventBus();
export default eventBus;
// 使用示例
// 发布事件
eventBus.emit('userLogin', { userId: 123, username: 'John' });
// 订阅事件
eventBus.on('userLogin', (data) => {
console.log('User logged in:', data);
});
2. 共享状态管理
// 共享状态管理器
class SharedState {
constructor() {
this.state = {};
this.listeners = {};
}
set(key, value) {
this.state[key] = value;
if (this.listeners[key]) {
this.listeners[key].forEach(listener => listener(value));
}
}
get(key) {
return this.state[key];
}
subscribe(key, listener) {
if (!this.listeners[key]) {
this.listeners[key] = [];
}
this.listeners[key].push(listener);
// 返回取消订阅函数
return () => {
this.listeners[key] = this.listeners[key].filter(l => l !== listener);
};
}
}
// 创建共享状态实例
const sharedState = new SharedState();
export default sharedState;
适用场景
- 大型企业应用:需要多个团队协作开发
- 遗留系统迁移:逐步迁移旧系统,降低风险
- 多技术栈应用:不同团队使用不同技术栈
- 频繁发布需求:需要独立快速发布功能
- 业务域清晰划分:业务模块之间耦合度低
- 高可用要求:需要故障隔离和独立部署
工具推荐
- Qiankun:阿里巴巴开源的微前端框架
- Single-SPA:最早的微前端框架之一
- Webpack 5 Module Federation:原生支持的模块联邦功能
- MicroApp:京东开源的微前端框架
- Piral:基于React的微前端框架
- Nx:支持微前端的构建系统
- Bit:组件共享和协作平台
- Storybook:UI组件开发和测试工具