微前端

52 阅读4分钟

概念

业务过大,如果把一个业务系统内的东西都放在一个代码仓库中,随着功能和模块越来越多,一个团队或者说一个仓库是负责不过来的。这时候就需要把项目拆分为多个模块,让各模块能独立开发,部署更新,但是为了维持整体统一性以及用户体验,各模块依然会挂载统一入口下。 image.png

上面的就是典型的微前端场景案例,把一个web应用由单一的单体应用分为多个小型前端应用聚合为一的应用,目前其实已经有一个iframe的方式能够实现,入口框架中使用iframe显示子模块的内容页面,切换的时候,ifram也能切换对应的子模块页面url。但是iframe有部分问题

  1. 显示区域受限,比如子模块显示弹窗的蒙层,只能作用与iframe的区域,内容肯定也无法居中
  2. 页面浏览记录无法纪录,history无法堆积,刷新页面,iframe又回到原始状态
  3. 页面间通信麻烦,只能采用postmesage或者websocket
  4. 速度慢,每次进入子页面都要重新构建# 微前端框架

single-spa

这个方案结果mpa和spa优势,可以在单页面中集成多个应用,并且不需要技术栈关联 image.png

**资源模块加载器:**用来加载子项目初始化资源。我们将子项目的入口js构建成umd格式,然后使用模块加载器远程加载,通常会使用SystemJs(不是必须)通用模块加载器来进行加载。 **子应用资源配置表:**用来记录各个子应用的入口资源url信息,以便在切换不同子应用时使用模块加载器去远程加载。因为每次子应用更新后入口资源的hash通常会变化,所以需要服务端定时去更新该配置表,以便框架能及时加载子应用最新的资源。 **注意:**single-spa本身是不支持子应用资源列表的,每个子应用只能将自己所有初始化资源打包到一个入口js中。如果子应用初始化资源有多个文件(可以通过webpack-manifest-plugin生成应用初始化资源清单),就需要按照上述方式来添加额外处理。 不足:

  1. 如上面提到过,如果子应用初始化资源有多个文件(比如通常我们会将css、npm模块抽离成一个单独的文件),那么我们就要自行维护一个子应用资源列表并做一些额外处理,这个工作往往也是比较繁琐的;
  2. 将多个子应用都集成在一个页面中,css和js都是很有可能产生冲突的。虽然我们可以制定规范,比如各子项目使用唯一地命名前缀等,但这种人为约定往往又是不那么靠谱。对于css,我们还可以在构建时使用一些工具自动添加前缀,这样可以比较靠谱的避免冲突;对于js来说,比较靠谱的方式可能就是人为制造沙箱,让子应用的js都运行在各自的沙箱中,但这实现起来就比较复杂了。## qiankun 这是基于single-spa开发的框架,目前已开源,有如下特征
  • 解析子应用入口时,不是解析的js文件,二是直接解析子应用的html文件。就算子应用更新了,其入口html文件的url始终不会变,并且完整的包含了所有的初始化资源url,所以不用再自行维护子应用的资源列表了。
  • 子应用挂载时,会自动进行一些特殊处理,可以确保子应用所有的资源dom(包括js添加的style标签等)都集中在子应用根节点dom下。子应用卸载时,对应的整个dom都移除了,这样也就避免了样式冲突。
  • 提供了js沙箱,子应用挂载时,会对全局window对象代理、对全局事件监听进行劫持等,确保各子应用都运行在自己的沙箱内,这样也就避免了js冲突。image.png

micro-app