Skip to content

微前端能解决什么问题

  • 大型项目复杂度高,打包时间长
  • 团队协作技术栈不统一
  • 增量迁移

微前端就是将不同功能按照不同维度拆分成多个子应用,通过主应用来加载子应用

如何实现微前端

我们可以将一个应用划分为若干个子应用,将子应用打包成一个个模块,当路径切换时加载不同的子应用

实现微前端需要解决哪些问题

  • 数据间如何通信
  • 应用间如何隔离(js隔离和css隔离)

实现方案

iframe

  • 通过iframe加载子应用
  • 通信可以通过postMessage进行通信
  • 完美的沙盒机制自带应用隔离

缺点: 用户体验差(弹窗只能在iframe中、滚动条、内部切换刷新就会丢失状态)

web Components

  • 将前端应用分解为自定义HTML元素
  • 基于customEvent实现通信
  • Shadow DOM天生作用域隔离

缺点:兼容性差、学习成本高、调试困难、修改样式困难

single-spa

  • single-spa通过路由劫持实现应用加载,采用SystemJS加载应用或则模块
  • 基于props主子应用通信
  • 无沙盒机制,需要自己实现JS沙盒以及CSS沙盒

缺点: 学习成本、无沙盒机制,需要对原有的应用进行改造,子应用间相同资源重复加载问题

模块联邦

  • 通过模块联邦将组件进行打包导出使用
  • 共享模块的方式进行通信
  • 无CSS沙盒和JS沙盒

systemJs

原理

  1. 动态扫描依赖映射表,加载依赖源
  2. 通过script动态导入打包好的子应用JS文件,加载好后,子应用会执行System.register方法来注册子应用需要的依赖
  3. 动态加载子应用需要的依赖,加载完成后通过快照获取windows上的全局依赖的对象
  4. 通过子应用的setter方法给子应用注入依赖
  5. 最后执行子应用的业务逻辑代码渲染子应用

single-spa

原理

  1. 基座应用是管理所有子应用的生命周期
  2. 基座在初始化的时候会注册子应用
  3. 当子应用的路由匹配到时,基座获取加载子应用的实例,然后获取并调用子应用的生命周期方法
  4. 通过hashchangepopState监听路由变化,当路由变化时,基座会先卸载子应用,然后加载新的子应用,新的子应用加载完成后,会调用子应用的bootstrapmount方法,渲染子应用

乾坤

TIP

乾坤微前端框架未采用SystemJS加载子应用,是多重因素交织作用的结果,涉及架构设计理念、应用隔离需求、资源加载效率及生态适配性等多个维度。以下从核心原因展开详细分析:

乾坤的核心设计目标之一是降低微前端接入成本,而SystemJS作为JavaScript模块加载器,其加载逻辑基于import语句,仅能处理JavaScript模块。相比之下,乾坤采用HTML Entry方案(通过import-html-entry库解析子应用的HTML入口),直接将HTML作为资源入口,可自动提取其中的CSS、JavaScript、图片等所有依赖资源,并按顺序加载执行。

这种方案的优势在于:

  • 无需改造子应用:子应用无需遵循SystemJS的模块规范(如UMD、ES Module),只需提供标准HTML入口即可接入,极大降低了老项目或第三方应用的迁移成本;
  • 资源加载更全面:HTML Entry可自动处理子应用的所有资源(包括CSS、图片、字体等),而SystemJS需手动管理这些资源的加载,增加了开发复杂度;
  • 兼容性更好:HTML作为Web的标准入口,支持所有前端框架(React、Vue、Angular等),而SystemJS对非JavaScript资源的支持需额外配置。

微前端的核心需求之一是子应用间的隔离(JS沙箱、CSS隔离),而SystemJS本身不具备这些能力,需依赖外部库或手动实现。

乾坤通过沙箱机制彻底解决了这一问题:

  • JS沙箱:提供SnapshotSandbox(快照沙箱,适用于低版本浏览器)、LegacySandbox(遗留沙箱,适用于单应用场景)、ProxySandbox(代理沙箱,适用于多应用场景)三种沙箱方案,通过Proxy或快照技术隔离子应用的window对象,避免全局变量污染;

  • CSS隔离:提供strictStyleIsolation(严格样式隔离,通过Shadow DOM实现)、experimentalStyleIsolation(实验性样式隔离,通过CSS前缀实现)两种方案,彻底隔离子应用的样式,避免样式冲突。

    相比之下,SystemJS需结合single-spa-css等外部库实现CSS隔离,且JS隔离需手动管理window对象,增加了开发和维护成本。

乾坤的资源加载机制更符合微前端的动态性需求

  • 动态加载:通过import-html-entry解析子应用的HTML入口,动态加载其JavaScript和CSS资源,无需提前打包所有子应用,减少了主应用的体积;

  • 预加载优化:支持prefetch策略(如visible(可见时预加载)、all(全部预加载)),提前加载子应用的资源,提升应用切换的流畅性。

    而SystemJS的加载逻辑基于System.import,需手动管理资源的加载顺序和依赖关系,且预加载支持较弱,无法满足微前端的高性能需求。

在微前端里如何实现css隔离

css-module,vue的scopedshadowDOM天然的作用域隔离

乾坤css隔离原理:属性选择器原理同理于vuescoped样式隔离

缺点:子应用的元素不能动态挂载到基座的元素上,会有样式丢失的问题。

shadowDOM原理:把子应用打包动态渲染到shadowDOM的标签元素中,shadowDOM有天然的样式隔离。

js沙盒proxy代理处理window隔离:

1.在a应用渲染前新建一个沙盒,把沙盒的代理作为window传给子应用,在a应用的副作用中可能会在windows上挂载一些沙盒属性,可以通过proxy代理劫持修改或者新增属性,存储到沙盒中,在子应用切换的时候还原windows上的属性,同理在子应用b上做相同的操作。最后在a应用重新激活的时候把沙盒中的修改和新增的属性重新加回到windows上。

缺点:ab应用一起渲染的时候只有一个windows就错乱了。

最终优化方案:多沙盒代理模式

为每一个应用创建单独的沙盒,通过proxy代理一个空对象,如果应用中要获取window上的属性先从proxy空对象中获取没有再从window上获取,如果应用要修改window上属性直接修改proxy代理对象的属性,这样就不会污染window,如果在应用失活的时候通过变量组织代理对象的修改。