微前端是一种将一个大型前端应用拆分为多个独立的小型应用,由主应用统一调度、组合呈现的架构模式。它的核心价值在于允许不同团队独立开发、独立部署、独立技术栈,最终在同一个浏览器窗口内协同工作。对于 Vue 项目而言,常见的落地框架是 qiankun 和 wujie。
qiankun:成熟的微前端框架
qiankun 基于 single-spa,提供了更开箱即用的 API 和沙箱机制。
主应用接入步骤(通常是 Vue 3 项目)
- 安装 qiankun
npm install qiankun
- 在主应用中注册子应用
// micro-apps.js
import { registerMicroApps, start } from 'qiankun'
registerMicroApps([
{
name: 'sub-app-vue2',
entry: '//localhost:8081', // 子应用开发服务器地址
container: '#sub-app-container',
activeRule: '/app-vue2', // 匹配此路径时激活子应用
props: { parentData: '来自主应用的数据' } // 可传递数据给子应用
}
])
start()
- 主应用页面预留容器
<template>
<div id="sub-app-container"></div>
</template>
子应用接入(以 Vue 2/3 项目为例)
子应用需要打包成符合 qiankun 规范的格式,关键在于导出生命周期钩子:
- 如果是 Vue 2,需修改
main.js:
let instance = null
function render(props = {}) {
const { container } = props
instance = new Vue({
router,
store,
render: h => h(App)
}).$mount(container ? container.querySelector('#app') : '#app')
}
// 独立运行时直接渲染
if (!window.__POWERED_BY_QIANKUN__) {
render()
}
// 导出 qiankun 期待的生命周期
export async function bootstrap() { console.log('sub app bootstraped') }
export async function mount(props) { render(props) }
export async function unmount() {
instance.$destroy()
instance.$el.innerHTML = ''
instance = null
}
- 对 Vue 3 子应用,逻辑类似,只是改用
createApp,并返回unmount方法。同时注意vue-router的 base 需要设为对应的activeRule前缀,避免路由冲突。
- 打包配置调整(Vue CLI 或 Vite)
- 使用 Vue CLI 时,
vue.config.js需设置output.libraryTarget为umd,确保子应用作为 UMD 模块输出。 - Vite 子应用需要安装插件
vite-plugin-qiankun,并配置:
import qiankun from 'vite-plugin-qiankun'
export default {
plugins: [qiankun('sub-app-name')]
}
实际使用中的关键问题
- 样式隔离:qiankun 默认开启沙箱(
sandbox: { strictStyleIsolation: true }或experimentalStyleIsolation),但严格模式可能使弹窗挂载到 body 的组件样式丢失。通常会使用约定式命名空间(如 BEM 前缀)或css-scoped辅助。 - JS 沙箱:qiankun 会为每个子应用创建独立的代理环境,避免全局变量污染。但在子应用中使用
window.xxx需特别注意作用域。 - 主子通信:通过注册时的
props传递基座数据给子应用,也可使用 qiankun 提供的initGlobalState共享状态。 - 公共依赖处理:可用 webpack 的
externals排除 Vue、Vue Router 等公共依赖,由主应用统一加载,减少子应用体积和重复实例化。但在微前端环境下,不同子应用可能使用不同版本,权衡后常选择各自打包。
wujie:新一代微前端方案
wujie 是腾讯开源的微前端框架,通过 WebComponent + iframe 来加载子应用,天然提供比 qiankun 更强的沙箱隔离和更简单的接入方式,特别适合适配老旧应用的嵌入。
核心特点
- 基于 iframe 实现 JS 隔离,同时将子应用的 DOM 提升到主应用文档流中(iframe 仅作环境容器),解决了传统 iframe 的体验问题。
- 支持预加载、保活、降级等模式。
- 接入代码量极少,不需要子应用改造过多。
主应用接入 wujie
npm install wujie-vue3 # 或 wujie-vue2
// main.js 引入
import WujieVue from 'wujie-vue3'
app.use(WujieVue)
模板中直接使用组件:
<WujieVue
width="100%"
height="100%"
name="sub-app"
url="http://localhost:8081"
:sync="true" <!-- 开启路由同步 -->
/>
子应用需要做的
基本无需改造,只需确保支持跨域请求。如果需要主子通信,wujie 提供了 $wujie 对象:
// 子应用中获取 props
const props = window.$wujie?.props
主应用可以通过 :props 属性传递数据,或使用事件总线通信。
wujie 的优势
- 接入简单:子应用几乎不改,天然兼容各种技术栈(jQuery、React、Vue 等)。
- 隔离性好:iframe 沙箱隔离 JS,避免全局变量冲突;CSS 也能通过 Shadow DOM 严格隔离。
- 性能模式:支持“保活”模式,让子应用在后台不销毁,下次打开时瞬间恢复。
- 降级处理:如果子应用无法加载,可以配置降级页面。
适用场景选择
- 如果你的环境可控,子应用都由你开发且愿意遵循 qiankun 规范,qiankun 是久经考验的生产级方案,社区生态丰富。
- 如果系统存在老旧应用、非 Webpack 打包的页面,或你想最小成本地集成,wujie 是更省心的选择。
无论选哪种,在主应用内将子应用的路由分配、状态共享和异常监控统一封装是必要的工程实践。