微前端架构 - childlabor/blog GitHub Wiki

传统架构

MPA 方案的优点在于 部署简单、各应用之间硬隔离,天生具备技术栈无关、独立开发、独立部署的特性。缺点则也很明显,应用之间切换会造成浏览器重刷,由于产品域名之间相互跳转,流程体验上会存在断点。

SPA 则天生具备体验上的优势,应用直接无刷新切换,能极大的保证多产品之间流程操作串联时的流程性。缺点则在于各应用技术栈之间是强耦合的。

架构对比

微前端

微前端是一种多个团队通过独立发布功能的方式来共同构建现代化web应用的技术手段及方法策略。 微前端架构旨在解决单体应用在一个相对长的时间跨度下,由于参与的人员、团队的增多、变迁,从一个普通应用演变成一个巨石应用(Frontend Monolith)后, 随之而来的应用不可维护的问题。这类问题在企业级 Web 应用中尤其常见。

微前端架构具备以下几个核心价值

  • 技术栈无关:主框架不限制接入应用的技术栈,子应用具备完全自主权

  • 独立开发、独立部署:子应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新

  • 独立运行时:每个子应用之间状态隔离,运行时状态不共享

技术选型

微前端架构的优势,正是 MPA 与 SPA 架构优势的合集。

技术选型

主框架与子应用集成的方式
  • 构建时组合 主、子应用间可以做打包优化,共享依赖包等,但是子应用每次发布依赖主应用需要重新打包发布。

  • 运行时组合: 主、子应用间解耦,子应用间完全技术栈无关,但是会多出一些运行时的复杂度和overhead(额外开销)。

很显然,要实现真正的技术栈无关跟独立部署两个核心目标,大部分场景下我们需要使用运行时加载子应用这种方案。

资源渲染入口
  • JS Entry 子应用的所有资源打包到一个 js bundle 里,包括 css、图片等资源。除了打出来的包可能体积庞大之外的问题之外,资源的并行加载等特性也无法利用上。

  • HTMLEntry 子应用打出来 HTML作为入口,主框架可以通过 fetch html 的方式获取子应用的静态资源,同时将 HTML document 作为子节点塞到主框架的容器中。可以天然的解决子应用之间样式隔离的问题。

选择HTML Entry 更加灵活,解决样式隔离问题。

模块导入

我们需要获取到子应用暴露出的一些钩子引用,如 bootstrap、mount、unmout 等(参考 single-spa),从而能对接入应用有一个完整的生命周期控制。而由于子应用通常又有集成部署、独立部署两种模式同时支持的需求,使得我们只能选择 umd 这种兼容性的模块格式打包我们的子应用。

我们只需要走 umd 包格式中的 global export 方式获取子应用的导出即可,大体的思路是通过给 window变量打标记,记住每次最后添加的全局变量,这个变量一般就是应用 export 后挂载到 global 上的变量。

应用隔离
  • 样式隔离 由于微前端场景下,不同技术栈的子应用会被集成到同一个运行时中,所以我们必须在框架层确保各个子应用之间不会出现样式互相干扰的问题。

Dynamic Stylesheet:在应用切出/卸载后,同时卸载掉其样式表。

  • JS 隔离 确保各个子应用之间的全局变量不会互相干扰,从而保证每个子应用之间的软隔离。

DEMO

micro-frontends-demo