什么是微前端
# 微前端出现背景
微前端的发展,并不是凭空出现的。随着最初的项目在不断发展过程中积累为巨石应用,而这些巨石应用就会伴随着很多问题.
# 工程膨胀
随着应用添加越来越多的功能,会导致项目越来越大。而项目一大就会影响开发速度(本地服务的编译打包时间、需求发布时的打包时间)。随着业务的复杂度提升,在某些场景下的打包会加越来越多的环境变量判断,从而导致应用打包的配置逻辑会越来越臃肿
# 分支混乱
当多人协作开发,或者多团队协作开发时。在一个项目中会有可能导致分支混乱,而且经常性会出现代码冲突,或者是由于修改公共组件引发的bug。
项目由多团队协同开发的时候,可能存在需求依赖关系,即一个功能需要等其他团队开发好之后,才能接着开发下个功能。
# 维护困难
随着时间的推移,长时间下,一个巨石项目会存在遗留模块、代码组织结构太老等诸多维护性问题,有时候开发一个新的功能,为了兼容他,限制了整个项目的发展。
如果项目开发人员流动太大,一些祖传代码难以维护,一般人都不想去修改。或者修改某个小模块,项目在发布时是全量发布,也可能导致该项目挂掉
# 微前端是什么?能做什么?
很明显,微前端可以解决上文中描述的各种场景问题。当然,也不止这些。
# 微前端是什么
微前端是由一个个微应用来组成一个巨石应用,而这些微应用之间的代码是可以相互隔离(JS运行沙箱、CSS代码隔离),也可以共用同一份数据、复用相同业务逻辑
# 微前端能做啥
简单、松耦合的代码库
- 微前端架构倾向于编写和维护更小、更简单、更容易开发的项目
- 技术栈无关,由一个巨石应用可以拆分为各个小项目后,可以在小项目中使用任何技术栈
增量升级
- 支持渐进式重构,先让新旧代码和谐共存,在逐步转化旧代码,知道整个重构完成
独立部署
- 每一个子应用都具备独立开发,持续部署,独立运行的能力。
团队自治
- 各子项目之间不存在依赖关系,保持隔离(js运行沙箱、css隔离)。
- 单一职责,每个子项目只做和自己相关的业务工作。
# 落地场景
在实际项目中,如果遇到以下问题,可以考虑使用微前端
- 项目太大,成为了典型的巨石应用,打包很慢。
- 项目开发者太多,多个同学开发同一套代码,经常出现代码冲突、或修改公共组件引发的 Bug。
- 项目太老,存在遗留模块,为了兼容它,限制了整个项目的发展。
- 项目技术栈不统一,使用了多种不同框架,每一种框架又有多个版本共存的情况。
- 项目由多个团队协同开发,一个功能需要等其他团队开发好之后,才能接着开发。
- 项目每次发布都是全量发布,即使是上线一个小模块,也可能导致整个项目挂掉。
- 项目由多个系统组成,完成一个功能需要不断地跳转多个系统页。
- 项目开发人员流动大,存在一些祖传代码难以维护,一般人都不好改。
- 项目需要一些试验田方案,即需要在某些模块做一些新技术尝试、框架升级等。
- ...
# 微前端存在的问题
当然,微前端也不是万能的,它也存在以下问题
- 拆分的粒度越小,便意味着架构变得复杂、维护成本变高。
- 技术栈一旦多样化,便意味着技术栈混乱。
- 管理版本复杂、依赖复杂。
- 开发体验不太友好,开发时可能需要同时启动多个项目。
这些问题大多是因为项目拆分成多个项目之后,引发的沟通协作问题
# 微前端的技术演变
# 以前的微前端方案
在前端没有出现MV*和打包工具之前,对于巨石应用的微前端方案
# 路由分发式
- 通过http服务其的反向代理功能,将请求路由到对应的应用上。
- 这种方式只是在路由层面看起来是一个项目,但实际上只是通过a标签连接了多个项目。
- 或者直接拆分巨石应用,由a标签来连接多个项目。
# 前端容器化
- 使用 iframe 作为容器
- seo 不友好。
- 需要考虑同源策略 cookie 管理。
- 需要自建一套应用管理、应用通信机制。
- 弹窗不友好。
- 浏览器后退按钮不友好。
# 现代微前端方案
# 前端微服务化
- 在不同的框架之上设计通讯、加载机制,以在一个页面内加载对应的应用。
- 常用的框架:qiankun,single-spa 都是这样做的。
- 最常用的方案,适合于快速上手。
# 微件化
- 打包出可以直接嵌入在页面上运行的代码,可能是一段 js,使用时直接引入即可。
- 需要实现一套微件管理机制,成本太高。
# 微应用化
- 通过软件工程的方式,在部署构建环境中通过 webpack 打包,组合多个独立应用成一个单体应用。
- 需要将多个项目打包成一个,所以技术栈需要保持统一。
# 应用组件化
- 将子项目都打包成 webComponent,在主项目中组合。
- 需要考虑 webComponent 兼容性。
# 各方案的优缺点
方式 | 开发成本 | 维护成本 | 可行性 | 同一框架要求 | 实现难度 | 潜在风险 |
---|---|---|---|---|---|---|
路由分发 | 低 | 低 | 高 | 否 | ☆ | 这个方案太普通了 |
iFrame | 低 | 低 | 高 | 否 | ☆ | 这个方案太普通了 |
应用微服务化 | 高 | 低 | 中 | 否 | ☆☆☆☆ | 针对每个框架做定制及Hook |
微件化 | 高 | 中 | 低 | 是 | ☆☆☆☆☆ | 针对构建系统,如webpack进行hack |
微应用化 | 中 | 中 | 高 | 是 | ☆☆☆ | 统一不同应用的构建规范 |
纯Web Components | 高 | 低 | 高 | 是 | ☆☆ | 新技术,浏览器兼容问题 |
结合Web Components | 高 | 低 | 高 | 否 | ☆☆ | 新技术,浏览器兼容问题 |
这么多方案,各有利弊,我们应该如何选择呢?
如果只是想简单快速的做分离,不考虑 seo,可以用 iframe。
如果想做分离的同时,保持良好的单页体验,可以考虑 single-spa、qiankun 框架。
如果公司有很强的技术能力,再考虑自研或其他方案。