关于微前端的技术思考

1,132 阅读4分钟

目前微前端的概念已经火了一段时间了,社区也有相对来说比较出名的解决方案,如single-spaqiankun等。但是关于本篇文章将抛开框架来谈一下对于微前端的思考。

微前端的优点

微前端为什么能火,当然有其优点,比较突出的主要有以下几点:

  1. 技术栈无关(很多项目由于历史包袱等原因可能技术栈比较老)
  2. 独立开发、独立部署(一些大型的项目,动辄几十上百个页面,每次开发跑起来都要很久,同时也可能存在node内存不足的问题。同时,独立的环境能比较业务模块间的互相影响)
  3. 各业务模块独立,便于升级和重构等

微前端的难点

微前端有其特点,但是其在技术实现上也有一定的技术难点。我在内部自研的微前端解决方案实现的过程中也遇到了一些相关的问题。

路由切换

微前端给用户感知其实仍然是接近于单页面应用的,微前端的路由仍然可以采用单页面应用的路由导航方案,这一点相对来说比较容易解决。 大部分的前端单页面路由都是通过hash或者history来实现,微前端也不例外,也需要通过这种方式来实现路由的切换。 我在实现自己的解决方案时直接借用了vue-router的能力,有兴趣的也可以直接看一下相关的框架的路由实现或去了解一下浏览器的history api

子应用挂载

应用挂载的本质上还是在html上添加子应用的cssjs。这里的实现思路主要是监测路由的变化,在路由变化的同时开始挂载子应用的资源。这个过程其实和webpack打包后的路由懒加载的原理有点相似。

在实践中,我也是通过监听路由,同时将各个子应用的资源存在对应的变量中,当进入应用是,直接将对应的资源挂载,这里在实现过程中是和路由切换一起实现的。

子应用的通信

由于各个子应用间是相互独立的,所以一些数据并不能共享,但我们的业务是不可能完全分割的,所以需要进行应用间的通信。我目前使用的有两种

  1. 借助框架的实现,例如可以借助vue或者vuex,利用vue来实现一个简单的Event Bus进行通信或者直接使用vuex提供的功能即可,这里详细的可以看vuex的源码,不再赘述
  2. 使用浏览器本身事件机制,通过事件的监听和主动触发来实现,具体api是的CustomEvent

css隔离

css隔离主要有几种方法

  1. css样式的添加和移除。可以通过主应用的脚本来监测子应用的挂载和销毁,同时对css样式进行添加和移除。但这里有一个要注意的点就是要对子应用的打包进行改造,获取打包后的css样式地址
  2. 使用scope-css。开发过程中不设置全局样式,全部使用scope-css,全局样式存放在主应用。这种方式相对比较简单
  3. 对子应用的样式全部添加前缀,这个和方式2原理相似,可以借助使用postcss来实现
  4. 使用shadow DOM。这个方式存在兼容性问题,同时如果要做样式穿透比较麻烦,有兴趣可以了解一下,我感觉它的功能不止这些。官方文档

js隔离

js隔离相对来说比较麻烦,因为即使你移除了js,但是其运行后的影响仍然存在,比如全局变量的污染、定时器等问题。好在现在很多项目基本都是基于webpack构建,全局变量较少,处理起来也相对简单,同时在子应用开发的过程中及时清理定时任务即可。

在实践的过程中,主要是在主应用定义可预测的全局变量,同时,实现了一个快照的功能,对应用的运行时状态保存,当子应用销毁时,根据快照恢复应用状态即可。但这个仍然不是完全的沙箱,还是存在js互相影响的可能。期待社区有更好的解决方案。

写在最后

微前端我的理解是现在并没有什么最好的解决方案,他是一种思想,一种解耦的思想,而不是具体到某个框架。其实只要符合你的业务需求,同时利用好微前端的优点即可。比如我在实践的过程中,也是借助vue的一些能力去进行微前端的实现,虽然目前存在些许不足,但减少了对原有代码的改造,同时学习成本也较低,这也是我比较满意的地方,