微前端是什么
微前端是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立运行、独立开发、独立部署。
简单来说,就是利用一系列工具和技术,将各个团队的UI页面 组装成用户可以连贯的应用程序。
后端解耦,前端聚合
采用微服务的原因主要还是在于,使用微服务架构来解耦服务间依赖。
而在前端微服务化上,则是恰恰与之相反的,人们更想要的结果是聚合,尤其是那些 To B(to Bussiness)的应用。
在这两三年里,移动应用出现了一种趋势,用户不想装那么多应用了。而往往一家大的商业公司,会提供一系列的应用。这些应用也从某种程度上,反应了这家公司的组织架构。然而,在用户的眼里他们就是一家公司,他们就只应该有一个产品。相似的,这种趋势也在桌面 Web 出现。聚合成为了一个技术趋势,体现在前端的聚合就是微服务化架构。
目的
- 减少团队件的等待时间
- 不再有前端巨石架构
优点
- 可独立部署
- 将故障风险的粒度隔离到更小的范围
- 职责范围更窄,更加易于理解
- 拥有更小的代码库,有利于重构和替换
- 状态更易于预测,因为它不与其他系统共享状态
缺点
- 冗余
- 各个团队需要建立维护自己的服务器,构建流程和持续集成的管道,可能还加载冗余的js/css
- 一致性
- 后端团队有独立的数据库,团队之间需要定期复制数据,一旦出现错误,容易引起数据不一致
- 异质性
- 技术栈可选择性多
- 更多的前端代码
微前端实施方式
路由分发式微前端
通过路由将不同的业务分发到不同的、独立前端应用上。其通常可以通过 HTTP 服务器的反向代理来实现,又或者是应用框架自带的路由来解决。
http { server { listen 80; server_name www.phodal.com; location /api/ { proxy_pass http://http://172.31.25.15:8000/api; } location /web/admin { proxy_pass http://172.31.25.29/web/admin; } location /web/notifications { proxy_pass http://172.31.25.27/web/notifications; } location / { proxy_pass /; } } }
- 不同技术栈之间差异比较大,难以兼容、迁移、改造
- 项目不想花费大量的时间在这个系统的改造上
- 现有的系统在未来将会被取代
- 系统功能已经很完善,基本不会有新需求
iframe
顾名思义,通过iframe加载子应用。 通信可以通过postMessage进行通信。
优点
- 简单
- 隔离
- 安全
缺点
- 布局约束
- 性能开销
- 破坏了语义化,对无障碍可访问性支持不好哦
- 不利于seo,会当成2个页面
- url 不同步。浏览器刷新 iframe url 状态丢失、后退前进按钮无法使用。
- UI 不同步,DOM 结构不共享。想象一下屏幕右下角 1/4 的 iframe 里来一个带遮罩层的弹框,同时我们要求这个弹框要浏览器居中显示,还要浏览器 resize 时自动居中..
- 全局上下文完全隔离,内存变量不共享。iframe 内外系统的通信、数据同步等需求,主应用的 cookie 要透传到根域名都不同的子应用中实现免登效果。
- 慢。每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。
ajax
ajax 请求服务端,直接在主页面区域返回拼装好的html
优点
- 简单
- 自然的文档流
- 利于seo
- 利于无障碍可访问性
- 渐进式增强
- 灵活的错误处理
缺点
- 异步加载
- 缺少隔离性
- 需要向服务器发送请求
- 脚步缺少生命周期
web component
将前端应用程序分解为自定义 HTML 元素。 基于CustomEvent实现通信
Shadow DOM天生的作用域隔离
重写现有的前端应用,使用 Web Components 来完成整个系统的功能。
- 被Web标准广泛支持
- 自定义元素 shadow DOM 支持隔离
- 引入了生命周期
- shadow 兼容性支持度不够好
single-spa
- 实现一套生命周期,在 load 时加载子 app,由开发者自己玩,别的生命周期里要干嘛的,还是由开发者造的子应用自己玩
- 监听 url 的变化,url 变化时,会使得某个子 app 变成 active 状态,然后走整套生命周期
- 子应用最关键的一步就是导出 bootstrap, mount, unmount 三个生命周期钩子。
- 基于浏览器原生的事件系统,无框架耦合,全局开箱可用。
- load 方法需要知道子项目的入口文件
- 把多个应用的运行时集成起来需要项目间自行处理内存泄漏,样式污染问题
- 没有提供父子数据通信的方式
qiankun
qiankun基于single-spa进行了二次开发
- 主应用:只需要输入子应用的html入口
- 子应用:与single-spa基本一致,导出了三个生命周期函数。
- js隔离
- Proxy沙箱,它将window上的所有属性遍历拷贝生成一个新的fakeWindow对象,紧接着使用proxy代理这个fakeWindow,用户对window操作全部被拦截下来,只作用于在这个fakeWindow之上
- css隔离
- ShadowDOM样式沙箱会被开启。在这种模式下 qiankun 会为每个微应用的容器包裹上一个 shadow dom 节点,从而确保微应用的样式不会对全局造成影响。
- Scoped CSS,qiankun会遍历子应用中所有的CSS选择器,通过对选择器前缀添加一个固定的带有该子应用标识的属性选择器的方式来限制其生效范围,从而避免子应用间、主应用与子应用的样式相互污染。
- 但如果用户在运行时引入了新的外联样式或者自行创建了新的内联标签,那么qiankun并不会做出反应
- qiankun在框架内部预先设计实现了完善的发布订阅模式