微前端介绍
Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. -- Micro Frontends
微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。
什么是微前端?
微前端这个术语于 2016 年底首次出现在ThoughtWorks Technology Radar中。它将微服务的概念延伸到了前端世界。当前的趋势是构建功能丰富且功能强大的浏览器应用程序,又称单页应用程序,它位于微服务架构之上。随着时间的推移,通常由单独团队开发的前端层会不断增长并且变得更加难以维护。这就是我们所说的前端单体。
微前端背后的想法是将网站或网络应用程序视为独立团队拥有的功能的组合。每个团队都有其关心和擅长的不同业务或任务领域。团队是跨职能的,并从数据库到用户界面****端到端地开发其功能。
然而,这个想法并不新鲜。它与独立系统概念有很多共同点。在过去,此类方法被称为垂直系统的前端集成。但微前端显然是一个更友好、更简洁的术语。
整体前端
垂直组织
什么是现代 Web 应用程序?
在简介中,我使用了“构建现代 Web 应用程序”这一短语。让我们定义与该术语相关的假设。
为了从更广泛的角度来看这一点,Aral Balkan撰写了一篇关于他所谓的“文档到应用程序连续体”的博客文章。他提出了滑动比例的概念,其中由静态文档构建并通过链接连接的网站位于左端,而纯粹行为驱动的、无内容的应用程序(如在线照片编辑器)位于右端。
如果您将您的项目定位在该范围的左侧,那么网络服务器级别的集成是一个不错的选择。使用此模型,服务器从构成用户请求的页面的所有组件收集并**连接 HTML 字符串。**更新是通过从服务器重新加载页面或通过 ajax 替换部分页面来完成的。古斯塔夫·尼尔森·科特 (Gustaf Nilsson Kotte)就此主题撰写了一篇综合文章。
当您的用户界面必须提供即时反馈时,即使在不可靠的连接上,纯服务器呈现的站点也不再足够。要实现诸如Optimistic UI或Skeleton Screens之类的技术,您还需要能够更新****设备本身上的UI 。Google 的术语“渐进式 Web 应用程序”恰当地描述了成为网络好公民(渐进式增强)与提供类似应用程序的性能之间的平衡行为。这种应用程序位于site-app-Continum 中间的某个位置。在这里,仅仅基于服务器的解决方案已经不够了。我们必须移动集成到浏览器中,这就是本文的重点。
微前端背后的核心思想
- 与技术无关 每个团队都应该能够选择和升级他们的堆栈,而无需与其他团队协调。自定义元素是隐藏实现细节同时向其他人提供中立界面的好方法。
- 隔离团队代码 即使所有团队使用相同的框架,也不要共享运行时。构建独立的独立应用程序。不要依赖共享状态或全局变量。
- 建立团队前缀 在尚无法实现隔离的情况下就命名约定达成一致。命名空间 CSS、事件、本地存储和 Cookie,以避免冲突并澄清所有权。
- 优先使用本机浏览器功能而不是自定义 API 使用浏览器事件进行通信,而不是构建全局 PubSub 系统。如果您确实必须构建跨团队 API,请尝试使其尽可能简单。
- 构建弹性站点 即使 JavaScript 失败或尚未执行,您的功能也应该很有用。使用通用渲染和渐进增强来提高感知性能。
DOM 就是 API
自定义元素(来自 Web 组件规范的互操作性方面)是浏览器中集成的良好原语。每个团队都使用他们选择的 Web 技术构建他们的组件,并将其包装在自定义元素中(例如<order-minicart></order-minicart>
)。这个特定元素(标签名称、属性和事件)的 DOM 规范充当其他团队的合同或公共 API。优点是他们可以使用组件及其功能而无需了解实现。他们只需要能够与 DOM 交互即可。
但仅自定义元素并不能解决我们所有的需求。为了解决渐进增强、通用渲染或路由问题,我们需要额外的软件。
该页面分为两个主要区域。首先,我们将讨论页面组合- 如何用不同团队拥有的组件组装页面。之后,我们将展示实现客户端页面转换的示例。
页面构成
除了不同框架本身编写的****客户端和服务器端代码集成之外,还有很多侧面主题值得讨论:隔离js 的机制、避免 css 冲突、按需加载资源、在团队之间共享公共资源、处理****数据获取并为用户考虑良好的**加载状态。**我们将一步一步地讨论这些主题。
基础原型
该模型拖拉机商店的产品页面将作为以下示例的基础。
它具有一个变体选择器,可以在三种不同的拖拉机型号之间切换。产品图片、名称、价格和建议发生变化时都会更新。还有一个购买按钮,可将选定的变体添加到购物篮中,并且顶部的迷你购物篮会相应更新。
所有 HTML 都是使用纯 JavaScript和 ES6 模板字符串在客户端生成的,没有依赖关系。该代码使用简单的状态/标记分离,并在每次更改时重新渲染整个 HTML 客户端 -目前没有花哨的 DOM 比较,也没有通用渲染。也没有团队分离——代码写在一个 js/css 文件中。
客户端集成
在此示例中,页面被分为三个团队拥有的单独组件/片段。Team Checkout(蓝色)现在负责与购买流程相关的一切 - 即购买按钮和迷你购物篮。Team Inspire(绿色)管理此页面上的产品推荐。该页面本身归团队产品(红色)所有。
各组
团队产品决定包含哪些功能以及它在布局中的位置。该页面包含团队产品本身可以提供的信息,例如产品名称、图像和可用变体。但它还包括来自其他团队的片段(自定义元素)。
微前端架构具备以下几个核心价值:
技术栈无关 主框架不限制接入应用的技术栈,微应用具备完全自主权
独立开发、独立部署 微应用仓库独立,前后端可独立开发,部署完成后主框架自动完成同步更新
增量升级
在面对各种复杂场景时,我们通常很难对一个已经存在的系统做全量的技术栈升级或重构,而微前端是一种非常好的实施渐进式重构的手段和策略
独立运行时 每个微应用之间状态隔离,运行时状态不共享
微前端架构旨在解决单体应用在一个相对长的时间跨度下,由于参与的人员、团队的增多、变迁,从一个普通应用演变成一个巨石应用(Frontend Monolith)后,随之而来的应用不可维护的问题。这类问题在企业级 Web 应用中尤其常见。
更多关于微前端的相关介绍,推荐大家可以去看这几篇文章: