微前端架构:从理论到实践
大家好,我是欧阳瑞(Rich Own)。今天想和大家聊聊微前端架构。作为一个全栈开发者,我参与过多个大型前端项目,微前端是解决大型项目复杂度的有效方案。今天就来分享一下微前端的核心概念和实践经验。
什么是微前端?
微前端是一种将大型前端应用拆分成多个小型、独立的子应用的架构模式。每个子应用可以独立开发、测试和部署。
微前端的优势
| 优势 | 说明 |
|---|---|
| 技术栈无关 | 每个子应用可以使用不同的技术栈 |
| 独立部署 | 单个子应用更新不影响其他应用 |
| 团队自治 | 不同团队可以独立负责不同子应用 |
| 渐进迁移 | 可以逐步迁移旧系统 |
微前端架构模式
1. 基座模式
javascript
// 基座应用
class MicroFrontend {
constructor() {
this.apps = {};
}
registerApp(name, app) {
this.apps[name] = app;
}
mount(appName) {
const app = this.apps[appName];
if (app) {
app.mount(document.getElementById('app-container'));
}
}
unmount(appName) {
const app = this.apps[appName];
if (app) {
app.unmount();
}
}
}
2. 路由分发
javascript
// 基于路由的微前端
const routes = [
{ path: '/home', app: 'home-app' },
{ path: '/dashboard', app: 'dashboard-app' },
{ path: '/settings', app: 'settings-app' },
];
function handleRouteChange(pathname) {
const route = routes.find(r => pathname.startsWith(r.path));
if (route) {
loadApp(route.app);
}
}
3. 模块联邦
javascript
// webpack.config.js - 宿主应用
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'host',
remotes: {
home: 'home@http://localhost:3001/remoteEntry.js',
dashboard: 'dashboard@http://localhost:3002/remoteEntry.js',
},
}),
],
};
javascript
// webpack.config.js - 子应用
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'home',
filename: 'remoteEntry.js',
exposes: {
'./App': './src/App',
},
}),
],
};
实战案例
使用Single-SPA
bash
npm install single-spa
javascript
// src/index.js
import { registerApplication, start } from 'single-spa';
registerApplication({
name: '@my-org/home',
app: () => System.import('@my-org/home'),
activeWhen: ['/', '/home'],
});
registerApplication({
name: '@my-org/dashboard',
app: () => System.import('@my-org/dashboard'),
activeWhen: '/dashboard',
});
start();
使用Qiankun
bash
npm install qiankun
javascript
// main.js
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'home',
entry: '//localhost:7101',
container: '#subapp-container',
activeRule: '/home',
},
{
name: 'dashboard',
entry: '//localhost:7102',
container: '#subapp-container',
activeRule: '/dashboard',
},
]);
start();
通信机制
基于Event Bus
javascript
class EventBus {
constructor() {
this.listeners = {};
}
on(event, callback) {
if (!this.listeners[event]) {
this.listeners[event] = [];
}
this.listeners[event].push(callback);
}
emit(event, data) {
if (this.listeners[event]) {
this.listeners[event].forEach(callback => callback(data));
}
}
}
const eventBus = new EventBus();
基于Shared State
javascript
// 共享状态管理
const sharedState = {
user: null,
theme: 'light',
};
function setState(key, value) {
sharedState[key] = value;
eventBus.emit('stateChange', { key, value });
}
function getState(key) {
return sharedState[key];
}
样式隔离
css
/* CSS Modules */
.container {
padding: 20px;
}
/* CSS-in-JS */
const styles = {
container: {
padding: '20px',
},
};
/* Shadow DOM */
const shadowRoot = document.createElement('div').attachShadow({ mode: 'open' });
最佳实践
1. 独立仓库
projects/
├── host/ # 宿主应用
├── home-app/ # 子应用1
├── dashboard-app/ # 子应用2
└── shared/ # 共享组件
2. 统一构建
yaml
# docker-compose.yml
version: '3'
services:
host:
build: ./host
ports:
- "80:80"
home:
build: ./home-app
ports:
- "3001:3001"
3. 自动化测试
yaml
# .github/workflows/test.yml
name: MicroFrontend Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm test
总结
微前端架构是构建大型前端应用的有效方式。通过将应用拆分成独立的子应用,可以提高开发效率和可维护性。
我的鬃狮蜥Hash对微前端也有自己的理解------它总是把晒太阳、吃饭、睡觉分成独立的"子任务",这也许就是自然界的"微服务"吧!
如果你对微前端感兴趣,欢迎留言交流!我是欧阳瑞,极客之路,永无止境!
技术栈:微前端 · Single-SPA · Qiankun · Module Federation