微前端技术主要被应用在企业的后台管理系统,这是因为后台管理系统动辄就是几年前的老项目,技术栈老,代码量庞大,代码重复率高,同一份逻辑可能存在多个版本。
而一般我们为了快速迭代,还不得不在这基础上继续添加逻辑,而老的代码逻辑基于时间不足,或是业务风险,都不敢大刀阔斧的删改。
但是随着代码量与业务复杂度的提升,系统变得越加庞大难以维护,体验也越来越差。为了解决此类问题,后台系统就需要有新的解决方案,该方案应解决如下问题:
- 应可以自由拆分应用,且应用间技术栈可以自由组合不受限制。
- 旧系统做少量改造即可集成到新架构。
- 新旧系统均可独立开发,独立部署,互不影响。
为了解决上述问题,前端领域涌现了好几种方案,以下将逐个介绍并对比分析。
iframe方案是最简单直接的一种微前端架构解决方案。由于天然利用了浏览器沙箱隔离的优势,所以iframe具备以下特点:
- 天然的全局样式以及全局变量的隔离。
- 各应用间技术栈可以做到互相独立,也可以做到独立开发独立发布。
- 天然的应用间资源懒加载,没有加载子应用,其资源也不会被加载。
但是iframe方案也存在一些问题:
- URL状态保持,当主应用刷新时,iframe会自动重置到加载时的初始URL
- 布局问题,比如子应用需要弹出一个全局居中的弹窗,只能通过通知主应用弹出,或者根据布局模拟居中。
- 主应用与子应用的数据同步与共享问题。
- 对于非后台管理系统,应当还需要注意网站SEO,兼容性,加载速度等问题。
npm的方案很好理解,就是将子应用单独打包成一个npm依赖库,然后在主应用进行依赖安装,并根据路由渲染不同的子应用即可。基于模块打包封装的思想,它的特点也有很多:
- 不同依赖库间没有强依赖,可以使用不同的技术栈进行开发。
- 不需要单独的服务器进行部署以及资源托管,只需要发布到npm仓库即可。
- 复用性好,可以任意组合成不同的微前端系统。
- 可以共享同一个渲染进行,上下文及内存数据。
但是于此同时,npm方案也有一些问题:
- 如何处理主应用与各个微应用之间的全局变量,CSS样式和储存数据之间的冲突问题。
- 微应用的构建需要做额外的配置,因为构建的不是应用,而是依赖库。
- 需要着重设计实现主子应用间的通信标准,并严格按照标准编码。
- 微应用发布新版本后,主应用都需要重新安装并构建部署。
- 当微应用过多,还需要考虑体积过大的优化问题,比如公共框架抽离,代码分割等。
该方案与NPM方案整体类似,区别在于NPM方案打包出依赖库,但是动态Script方案打包出的还是应用程序,只不过打包后的JS并非直接运行,而是实现对应的挂载与卸载的钩子函数供主应用调用。而主应用可以通过接口服务动态的获取到微应用列表,以及其对应的JS资源,根据路由规则去选择卸载旧应用,挂载新应用。
基于以上描述,其具有以下优点:
- 主应用可以动态调增子应用的数量,以及其脚本。
- 微应用可以如正常应用一样进行优化,如代码分割,静态资源分离,CDN加速等。
- 不需要如NPM库一样,配置额外的配置文件使其打包成依赖库。
其问题也是与npm方案一样:
- 主应用与微应用的全局变量、CSS样式、本地存储的数据无法做到很好的隔离。
Web Comonents方案整体加载流程上与动态Script方案类似, 只不过不是通过自定义的挂载与卸载的钩子供主应用使用,而是利用Web Components的生命周期钩子进行挂载与卸载。
对比于动态Script方案,Web Components方案有以下特点:
- 不需要对外抛出全局API(挂载与卸载),可复用性更强。
- 更标准化,Web Components的能力后续会随着标准的指定逐步提升。
当然,Web Components还是存在一些不足:
- 兼容性问题。对旧版本浏览器兼容性不好。
- 有一定上手难度,对比以上提到的几种方案,开发者需要额外学习Web Components相关知识。
这个方案也是目前国内前端社区较为主流的方案。是基于single-spa的微前端实现库。 它具有以下特点:
- 技术栈无关,主子应用都可以使用任何框架实现。
- 独立开发,独立部署。各应用间无耦合,互相独立。
- 独立运行时,支持各应用间的样式隔离以及变量隔离。
缺点:
- 没有提供较完整可靠的应用间通信解决方案。
- 不支持主子应用间的组件复用,需要通过组件库的方法实现。
- 存在一定兼容性问题。
- 相对于其他方案,有一定学习成本,并且功能升级拓展需要依靠qiankun社区的发展。
这里,我也基于qiankun搭了一个简单的后台系统的架子,支持了多子应用的tab管理,主子应用数据同步等功能。
这篇文章将目前国内前端比较主流的微前端方案进行了罗列,以及指出其优缺点,但是其中实现细节没有太多的展开,因为我认为其实现都不是很复杂,也没有花太多心思在如何实现上。其实有经验的前端开发者看看方案名称,以及描述,大概就能了解其工作原理,以及如何实现,只不过在其实现细节把控上面可能会有疏漏。但是这都不是什么大事。
希望这篇文章能给阅读者带来一定的启发,或者加深一下微前端相关知识。以此共勉,砥砺前行。