微前端的诞生:微服务是为了解决庞大的后端服务带来的变更与拓展方面的限制,而将一个大型的服务应用分割成若干个颗粒度较小的可独立开发、测试及部署的单个子应用。而越来越复杂的前端项目也面临同样的问题。于是有了微前端的诞生
微前端与微服务类似,都是将一个复杂大型的应用程序拆解成颗粒度更小的可以独立开发、测试及部署的小模块,并通过一些策略方案来确定这些模块之间的依赖关系。
概念:微前端是构建一个现代 Web 应用所需要的技术、策略和方法,并具备多个团队独立开发、部署的特性——-它不是新技术,只是一种宏观上的架构模式
特点:
(一)代码库更小,可维护性更高
比起传统的一整个项目代码块,微前端架构下的代码块更小、更容易开发。还可以避免模块之间的隐式耦合。独立性更强,维护性更高。
(二) 渐进式升级与迭代
微前端架构可以让新旧代码和谐共存,在重构时,可以一边将旧的应用逐步翻新,一边继续提供新功能,直到整个重构完成。这种增量升级的能力意味着能够对产品功能进行低风险的局部替换,包括升级依赖项、更替架构、UI 改版等。另一方面,也带来了技术选型上的灵活性,有助于新技术、新交互模式的实验性试错。
(三) 独立部署
独立部署在微前端中非常重要,子模块之间只有部署,才能减轻依赖,降低耦合。独立部署能够缩小项目变更范围,降低生产风险。无论前端代码在何处托管,每个微前端都应该有连续交付通道,该通道可以构建、测试并将其一直部署到生产环境中。
实现方式:
(一) 打包之后的 Bundle 如何集成
在微前端架构中一般会有一个容器应用将各子应用集成起来。比如统一的 Header、Footer、Navigator 等。提供一些公共的方法。然后把各个子模块整合到一个页面上,并控制渲染区域和时机。
集成方式一般分为三种。
服务端集成
每个子服务负责独立渲染对应的微前端应用,由主服务向各个子服务发起请求。
构建时集成
常见的构建时集成是 NPM 包形式抽离和引用,可以将各个子应用发布成独立的 NPM 包,并作为主应用的依赖项,构建成一个可以直接部署的 Bundle。不过这种方式会在发布阶段造成应用之间的强耦合,任何一个子应用变更都要重新构建整个项目。
运行时集成
将集成时机从构建时推迟到运行时,就能避免发布阶段的耦合。常见的运行时集成方式有:
iframe
支持样式隔离及全局变量隔离。性能差,通信复杂,灵活性差。
JS:比如前端路由
由每个子应用暴露出渲染函数,主应用在启动时加载各个子应用的独立 Bundle,之后根据路由规则渲染相应的子应用。目前看来,是最灵活的方式
Web Components
将每个子应用封装成自定义 HTML 元素(而不是前端路由方案中的渲染函数),以获得Shadow DOM带来的样式隔离等好处。
(二) 子应用之间如何隔离
子应用之间,子应用和主应用之间的样式、作用域隔离是必须要考虑的问题。常用的解决方案如下:
样式隔离:开发规范(如BEM)、CSS 预处理(如SASS)、模块定义(如CSS Module)、用 JS 来写(CSS-in-JS)、以及shadow DOM特性
作用域隔离:各种模块定义(如ES Module、AMD、Common Module、UMD)
(三) 子应用之间如何通信
通过自定义事件间接通信
该方式是一种避免直接耦合的常用方式。
React 的单向数据流模型
React 的单向数据流模型也能让依赖关系更加明确,对应到微前端中,从容器应用向子应用传递数据与回调函数。
路由参数
路由参数除了能用于分享、书签等场景外,也可以作为一种通信手段
其实无论采用哪种方式,都应该尽可能减少子应用间的通信,以避免大量弱依赖造成的强耦合。
(四) 公共资源如何复用
公共资源可以大致分为以下三种:
基础资源
项目中需要使用到的图片、图标、标签、按钮等。
UI 组件
含有一定逻辑的 UI组件。如搜索框(自动完成)、表格(如排序、筛选、分页)等。
业务组件
含有业务逻辑的业务组件,不建议跨子应用复用业务组件,因为会造成高度耦合,增加变更成本。
资源复用对于呈现给用户的 UI 界面非常重要。但是组件复用并非项目一启动就能够完全确定。前期开发时可以有一些代码冗余,可以由各个子模块在代码中去创建自己的公共组件,等到业务模块已经完全确定再提取最终可供复用的公共组件。公共资源应当遵循统一规范,其归属和管理最好由专人负责。
本文来自 余 倩倩 投稿,不代表 PmTemple 立场,如若转载,请注明出处:
。如有涉及侵权行为,请发送相关证明材料至邮箱admin@pmtemple.com