个人主页:Guiat
归属专栏:Vue
正文
微前端是一种前端架构模式,它将前端应用分解成一系列小型、自治的应用,可以独立开发、测试和部署。这些小型应用最终组合成一个完整的应用。微前端架构借鉴了微服务的理念,旨在解决大型前端应用开发和维护的复杂性问题。
微前端架构有多种实现方式:
qiankun(乾坤)是蚂蚁金服推出的一个基于 single-spa 的微前端实现库,旨在让微前端的使用更加简单。其名字取自中国传统文化中的"乾坤",寓意为包罗万象。
// main.js
import { registerMicroApps, start } from 'qiankun';
// 注册子应用
registerMicroApps([
{
name: 'vue-app', // 子应用名称
entry: '//localhost:8080', // 子应用入口
container: '#vue-app', // 子应用挂载的DOM节点
activeRule: '/vue-app', // 激活规则(路由匹配)
},
{
name: 'react-app',
entry: '//localhost:3000',
container: '#react-app',
activeRule: '/react-app',
}
]);
// 启动微前端服务
start();
// vue.config.js
const { name } = require('./package');
module.exports = {
devServer: {
port: 8080,
headers: {
'Access-Control-Allow-Origin': '*',
},
},
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`,
},
},
};
// main.js
import Vue from 'vue';
import App from './App.vue';
import router from './router';
let instance = null;
// 子应用生命周期 - 挂载前
function render(props = {}) {
const { container } = props;
instance = new Vue({
router,
render: h => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// 导出生命周期函数
export async function bootstrap() {
console.log('[vue] vue app bootstraped');
}
export async function mount(props) {
console.log('[vue] props from main framework', props);
render(props);
}
export async function unmount() {
instance.$destroy();
instance.$el.innerHTML = '';
instance = null;
}
qiankun 提供了多种应用间通信方式:
// 主应用
import { registerMicroApps, start } from 'qiankun';
const sharedData = {
user: { name: 'Zhang San' },
};
registerMicroApps([
{
name: 'vue-app',
entry: '//localhost:8080',
container: '#vue-app',
activeRule: '/vue-app',
props: {
sharedData,
onEvent: (data) => console.log(data)
}
}
]);
// 子应用
export async function mount(props) {
console.log(props.sharedData.user.name); // 'Zhang San'
props.onEvent('Event from sub-app');
}
// 主应用
import { registerMicroApps, start, initGlobalState } from 'qiankun';
// 初始化全局状态
const actions = initGlobalState({
user: { name: 'Zhang San' },
theme: 'dark',
});
// 监听全局状态变化
actions.onGlobalStateChange((state, prev) => {
console.log('主应用观察到状态变化:', state, prev);
});
// 更新状态
actions.setGlobalState({ theme: 'light' });
// 子应用
export function mount(props) {
// 获取全局状态并监听变化
const { onGlobalStateChange, setGlobalState } = props;
onGlobalStateChange((state, prev) => {
console.log('子应用观察到状态变化:', state, prev);
});
// 更新状态
setGlobalState({ user: { name: 'Li Si' } });
}
Micro-App 是由京东零售推出的一款基于 Web Components 的微前端框架,它使用自定义元素(Custom Elements)的方式实现微前端,简化了微前端的开发和使用。
npm i @micro-zoe/micro-app --save
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import microApp from '@micro-zoe/micro-app'
// 初始化 micro-app
microApp.start()
createApp(App).mount('#app')
主应用
对于子应用,Micro-App 框架对子应用的侵入性很小,只需在子应用的入口文件中导出相应生命周期函数即可:
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
let app = null
let history = null
// 将生命周期函数挂载到 window 上
window[`micro-app-vue-app`] = {
bootstrap() {
console.log('vue app bootstraped')
},
mount(props) {
console.log('vue app mount with props:', props)
app = createApp(App)
app.use(router)
app.mount('#app')
},
unmount() {
console.log('vue app unmount')
app.unmount()
app = null
history = null
}
}
// 子应用中获取数据
import microApp from '@micro-zoe/micro-app'
// 获取主应用传递的数据
const data = microApp.getData()
console.log(data) // { msg: 'hello from main app' }
// 监听数据变化
window.addEventListener('datachange', (e) => {
console.log('数据已更新:', e.detail.data)
})
// 主应用
import microApp from '@micro-zoe/micro-app'
// 向子应用发送数据
microApp.dispatch({ name: 'vue-app' }, { type: 'global-data', data: { value: 'hello' } })
// 监听子应用发送的数据
microApp.addDataListener('vue-app', (data) => {
console.log('来自子应用的数据:', data)
})
// 子应用
import microApp from '@micro-zoe/micro-app'
// 向主应用发送数据
microApp.dispatch({ type: 'from-child', data: 'some data' })
// 监听主应用发送的数据
window.addEventListener('global-data', (e) => {
console.log('来自主应用的数据:', e.detail.data)
})
特性 | qiankun | Micro-App |
---|---|---|
技术实现 | 基于 single-spa | 基于 Web Components |
使用方式 | API 调用 | 自定义标签 |
子应用改造 | 中等 | 较少 |
沙箱隔离 | JavaScript 沙箱 | Shadow DOM |
样式隔离 | 严格模式/实验性 | Shadow DOM 隔离 |
子应用预加载 | 支持 | 支持 |
通信方式 | Props、全局状态 | Data属性、发布订阅 |
社区活跃度 | 高 | 中等 |
// qiankun 主应用路由配置
import { registerMicroApps } from 'qiankun';
registerMicroApps([
{
name: 'vue-app',
entry: '//localhost:8080',
container: '#container',
activeRule: '/vue-app',
}
]);
// 子应用路由配置
const router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? '/vue-app' : '/',
mode: 'history',
routes: [...]
});
// 主应用配置共享依赖
import { registerMicroApps, start } from 'qiankun';
import Vue from 'vue';
import ElementUI from 'element-ui';
// 将共享依赖挂载到全局
window.Vue = Vue;
window.ElementUI = ElementUI;
registerMicroApps([...]);
start({
sandbox: {
strictStyleIsolation: false,
experimentalStyleIsolation: true,
// 配置不需要沙箱隔离的全局变量
patchers: [
(globalWindow) => {
globalWindow.Vue = window.Vue;
globalWindow.ElementUI = window.ElementUI;
return globalWindow;
}
]
}
});
// qiankun 预加载配置
import { registerMicroApps, start, prefetchApps } from 'qiankun';
// 注册子应用
registerMicroApps([...]);
// 预加载配置
prefetchApps([
{ name: 'vue-app', entry: '//localhost:8080' },
{ name: 'react-app', entry: '//localhost:3000' }
]);
// 或在启动时配置预加载策略
start({
prefetch: 'all' // 可选值: boolean | 'all' | string[] | function
});
mindmap
root((微前端生态))
框架层
qiankun
Micro-App
single-spa
Module Federation
工具层
构建工具
开发工具
调试工具
规范层
接口规范
通信规范
生命周期规范
最佳实践
设计模式
部署策略
监控方案
大型企业在实施微前端架构时的常见策略:
结语
感谢您的阅读!期待您的一键三连!欢迎指正!