微前端原理

2,166 阅读4分钟

为什么需要微前端

微前端就是将不同的功能按照不同的维度拆分成多个子应用,通过主应用来加载这些子应用。微前端的核心在于拆,拆完后再合。

为什么要使用

  • 不同团队开发同一个应用技术栈不同,vue、react、angular
  • 希望每个团队可以独立开发,独立部署
  • 项目中还有老得应用代码 将一个应用划分成若干个子应用,将子应用打包成一个个的lib包。当路径切换时,加载不同的子应用。这样每个子应用都是独立的,技术栈也不受限制,从而解决了前端协同开发的问题。

怎么落地微前端

把前端页面当成操作系统。2018年Single-SPA诞生,但是本身没有处理样式隔离,没有js沙箱机制,只是实现了路由劫持和应用加载。原理就是听过主应用的调用,把子应用挂载到主应用的div上。

如何解决这些问题:

  1. 子应用之间的样式隔离,动态样式表,当应用切换时,移除老应用样式,添加新应用样式
  2. 主应用和子应用样式隔离,约定项目前缀,css-modules打包时生成不冲突的选择器名(主流),shadow DOM真正意义上的隔离(qiankun),通过dom的api,声明一个影子元素,document.getElementById('shadow').attachShadow({mode:'closed'}),但是不能在body上挂载影子元素,会失效(比如弹框)
  3. js沙箱,创造一个干净的环境给子应用使用(不同应用会在window上挂载不同的属性造成污染),当应用切换时,可以选择丢弃属性和恢复属性
  4. 快照沙箱,1年前拍一张,再拍一张,将区别保存起来,再回到一年前
  5. 如果是多个子应用就要用es6的proxy,代理沙箱可以实现多应用沙箱,把不同的应用用不同的代理来处理

qiankun诞生

2019年qiankun基于Single-SPA做的封装,提供了开箱即用的API,(single-spa,sanbox,import-html-entry),做到了,技术无关、并且接入简单(就像iframe一样简单),支持样式隔离,js沙箱,预加载 总结:子应用可以独立构建,运行时动态加载,主子应用完全解偶,技术栈无关,靠的是协议接入(子应用必须到处bootstrap、mount、unmount方法)

为什么不是iframe

如果使用iframe,iframe中的子应用切换路由时,用户刷新页面,iframe中的切换后的路由状态都不能保持,浏览器原生支持,能够天然的解决CSS、Js的污染问题。但是问题也很明显:每次都需要重新加载,占用额外的内存,使用体验欠佳、不支持SEO、需要我们自定义应用管理与应用通讯机制。

为什么不是NG反向代理

实现起来非常简单,并且也能够做到独立开发、独立部署,但这更像是多个前端应用的聚合,我们只是将这些不同的前端应用拼凑到一起,前后端分离不彻底,用户体验不好

为什么不是webpack多入口

webpack多入口是多页应用

应用通信

  • 基于url来进行数据传递,但是传递消息能力弱
  • 基于customEvent实现通信,window原生api
  • 基于props主子应用间通信
  • 使用全局变量、redux进行通信

公共依赖

  • CDN-externals
  • webpack联邦模块

qiankun

用例配置参照qiankun官网即可,一些坑在官网上也列出来了

主应用请求转发

实践过程中,发现主应用会转发子应用的请求,如果主应用、子应用以及后端 API 都是同一个域名,则天然地不用解决这个问题。主应用和子应用目前都在公司的同一个域名下,如果不是同一个域名,需要在主应用中将请求转发到子应用的node中。