无界微前端的通信与样式隔离

问题

工作流平台要集成多个团队的子应用,选了无界(wujie)。落地时最头疼的不是加载,是通信和样式串味——子应用的弹窗挂到了 body 上,样式直接污染全局。

结论

无界的隔离原理是 iframe 跑 JS + webcomponent 挂 DOM,所以 JS 天然隔离,但 DOM 仍然挂在主应用的 document 里。这意味着:

样式隔离要靠 shadowRoot,但它不是默认开的,而且开了之后弹窗类组件会出问题。

通信三种方式,按场景选

// 1. props:一次性传值,子应用 props 变化时不会自动更新
<WujieVue name="flow" :url="url" :props="{ token, userInfo }" />

// 2. eventBus:主子双向,适合事件型通信
import { bus } from 'wujie'
bus.$on('flow-saved', handler)
bus.$emit('refresh-list')

// 3. window 通信:子应用里拿主应用的 window
window.$wujie.props
window.parent

选型建议:配置类用 props,动作类用 bus,不要用 bus 传大量状态——没有响应式,容易两边不同步。

弹窗为什么要特殊处理

子应用的 Modal / Dropdown 默认 appendToBody,渲染到主应用 document 上,拿不到子应用的样式,表现就是"弹窗没样式"。

解法是把弹窗挂载点改到子应用容器内:

// 子应用入口,以 element-plus 为例
app.use(ElementPlus)
// 或单独指定
ElMessageBox 的 appendTo 指向 #app 内部节点

另一种更省事的做法:主应用统一提供一套弹窗样式,子应用全部走主应用的组件(需要约定版本)。

为什么选无界而不是 qiankun

  • qiankun 是基于 single-spa 的路由劫持,样式隔离要开 strictStyleIsolation(也是 shadow DOM,同样有弹窗问题)
  • 无界的 JS 沙箱是 iframe,比 qiankun 的 Proxy 沙箱更彻底,子应用用了哪些全局变量都不用管
  • 代价:无界对 Vite 子应用的支持需要额外处理(dev 模式的 module script)

待补充

  • Vite 子应用在 dev 模式下的接入方式
  • 子应用之间共享依赖(Vue/React 单例)怎么避免重复打包
← 返回知识库