关于微前端,你理解到究极奥义了么?

2022-11-15 09:13:05 +08:00
 fantasticsoul

hel-micro,模块联邦 sdk 化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解

微前端的起源

微前端这个概念出现之前,我们或多或少都能够联想到另一个词性上有些相似的概念微服务,它从出现后便一直都很火热,并不断催生着后端架构体系的演进,而此刻我们如果细品一下这微字头的两兄弟,探究他们的诞生原因,会有很多有意思的点。

我们暂且忘掉这兄弟两,到一个更高的角度会发现,很多新概念的诞生,一定能够顺藤摸瓜的追溯到一个某个原点上,这个原点我们可以把它比作宇宙诞生的奇点,压抑了足够久之后发生了大爆炸,然后逐渐向外扩散生成万物原型,so...... 我们复盘一下处在这个信息高速时代,当网络带宽越来越大,覆盖范围越来越广,延迟越来越低,触达人群越来越多的时候,让 web 从 1.0 进化 2.0 、3.0 、4.0 ,在这个全民入网的时代,网络条件如此优越的时代,是什么开始按捺不住那庞大的能量,开始肆无忌惮的爆炸起来了呢?

爆炸的数据

聪明的你一定意识到了,它就是数据,优越的网络条件如同肥沃的土壤,让全民皆参与到内容生产当中,于是乎海量的数据疯狂生长,让我们进入了大数据时代,面对如此磅礴的体量,云计算分布式等新概念蜂拥而出,有了用武之地,或者说数据的爆炸倒逼着这些技术的产生与发展。

再回到微服务微前端两兄弟上,想一下是不是同样的也正因为数据的爆炸,需要精细化的运营各种场景,让我们传统的单体服务架构上不得不承载着越来越多的业务呢?

这种包含 n 个服务构成的一个后台项目,从开发侧看,只能在既有的技术栈上不停的叠加新功能,当新的技术福利诞生时想作替换将是一场噩梦,从运维测看,因整个项目打包在一起构成了一个产物,而不得不面对任何一点修改都必须全部一起发布的繁琐。

于是乎微服务诞生了,将这种巨石服务或按各职责、或按功能、或按业务等维度作为拆分的维度,拆解成一个个服务,可独立构建、独立部署,通过rpc通信做到应用的语言架构无关,让开发者不再捆绑到某一个编程语言上,当然了,作为拆的代价,服务注册、服务治理、服务发现、服务熔断、服务监控、链路追踪等新机制的引入带来了更高的复杂度,所以服务的拆分一定是一个渐进式的过程,为了拆而拆必然带来运维上的更高成本与挑战。

重刷存在感的微前端

微服务不一样的是,如果我们不死磕微前端概念,而是从字这个角度来看,其实微前端其实从 html 诞生那天开始一直都存在,我么仔细回想一下,传统的服务器端渲染,是不是一个路由对应着服务器端一个 html 页面的字符串返回呢,这一个返回对应着后端的一个页面模板,不管它是静态生成的还是动态生成的,它在后端的目录结构里都是一个个独立存在的文件,所以我们一直都是在用微前端搭建项目的视图部分。

随着前端的业务复杂度极巨爬升,传统的服务端渲染方式给前端工程化带来了巨大的挑战,因为工程化的基础是组件化,而后端的模板引擎所支持的组件化天生有着用绵软无力的感觉,无论是书写体验还是调试体验都远远弱于浏览器端渲染,而随着作为浏览器端主战场的不二人选 js ,生态周边越来越丰富与强大,如 node 的诞生为前端工程化催生了大量优秀的构建工具、编译工具,js 引擎的性能也一直在攀升,js 自身的规范和语言特性也不断的进化,以及和相关组件化开发的优秀库如春笋版冒出( react 、vue 、angular 、svelte...),良好的 npm 生态让库共享易如反掌等,在这种有利于前端工程化的土壤培育下,让我们面对复杂的前端项目时,如可忽略 seo 优化,首屏速度等因素时(尽管也有类似的解决方案),倾向于从服务器渲染迁移到浏览器端渲染了。

微前端之 5 个核心思想

前端工程化也面临着后端同样的问题,一个工程随着时间流逝会逐渐堆叠大量业务,从而让一个前端项目慢慢演变成一个巨石应用,基于此背景下在micro-frontends上对微前端做了如下阐述:

微前端背后的想法是将网站或 Web 应用程序视为由独立团队拥有功能的组合。每个团队都有不同的业务领域任务,它关心和专注于,一个团队是跨职能的,从数据库到用户界面,端到端地开发其功能,但这个想法并不新鲜,它与自包含系统的概念有很多共同之处。在过去,这种方法被称为垂直系统的前端集成。但微前端显然是一个更友好、更简洁的术语。

并进一步提炼出以下 5 点微前端的核心思想

微前端之模块联邦

以上阶段 1 里强调的 5 点特性看起来似乎给微前端下了一个相当完美的定义,以至于后来的各种微前端框架都在这 5 个核心思想指导下去做实现,直到 2020 年 webpack 5 module federation(以下我们简称 MF )模块联邦诞生,并对此特性在官网做了一个很简单的介绍:

模块联合的动机,让多个单独的构建应该可组合为一个应用程序,这些单独的构建之间不应该有依赖关系,因此它们可以单独开发和部署,这通常被称为微前端,但不限于此。

细细玩味这段话,我们发现 webpack 5 视角下的微前端仅需要包含 3 个特点:独立开发、独立部署、运行时组合。

如果你基于webpack 5 MF发布过远程模块,你会知道它并不包含 micro-frontends 站点里提到的隔离团队代码这个关键点,尽管我们知道涉及到代码运行隔离需要用上 shadowrealm(未来的隔离方案)、proxy window 、iframe 等方案,但 MF 并未强调这一点,所以看起来 MF 理解下的微前端是阉割版的微前端?

再思考微前端

我们将 micro-frontends 和 webpack 5 两个出处的微前端定义做一个对比,并提出一个灵魂的拷问,是否以下表达成立?

事实上随着模块联邦这个概念开始逐渐深入人心,微前端架构已经分裂出两个方向:

试想一下,你不会极端到以运行时隔离的方式去渲染多个按钮吧?

微容器微模块在开源社区均有很多实现,它们的特点很明显

所以基于两种方案搭建的微前端架构也是区别非常明显的

微前端技术该如何选型

我们只要深刻理解到微模块是天然就假定运行在同一个宿主里(即同个一 js 环境里),它要解决的核心问题是大规模独立构建的应用间如何快速动态共享公共模块这个棘手问题。

例如你有 100 个内部的前端项目依赖了 lodash-1.0.0 ,突然该库暴露了一个漏洞,你需要 100 个前端项目全部重新构建升级到 1.0.1 才代表安全解决此漏洞问题,而基于模块联邦的 lodash ,你仅需要构建一次 mf-lodash ,其他项目即可引用到最新的安全代码。

再综合考虑到两个以下关键点,就很容易得出技术如何选型的结论了:

因为微模块是微观态的组合方式,它可以迅速的将你逐渐庞大的应用拆为一个个可独立部署的组件并再次组合起来,相对于微容器方案,大多数时候或许你的新项目并不需要介入微容器

当你需要组合一些第三方应用或自己的其他技术栈应用,并需要让它的就是被隔离起来安全的运行时,微容器是你武器库里适合拿出来的强力武器。

事实上它们搭配起来混合使用将是相辅相成的完美组合,你可以先使用微容器再接入微模块做跨应用模块动态共享,或先使用微模块再套上微容器做运行时隔离,取决于你的项目发展到了什么阶段。

混合架构的微前端实践

实际上,我们在这方面已经做了大量的工程实践,微容器推出了无界,微模块推出了hel-micro

这里给出一个混合架构的例子可供大家参考:wujie 和 hel-mico 搭建微前端,大家可以将此思路复制到其他社区方案,例如( micro-app + mf )( qiankun + hel-micro )等。

例子里有无界容器里加载远程 react 组件的示例

有无界容器里加载远程 lodash 模块的示例

关于 hel-micro 与 wujie

hel-micro是业内里首个模块联邦 sdk 化,免构建、热更新、工具链无关的微模块方案,让模块联邦技术从构建工具插件层面提升到 sdk 层面,使用更灵活,模块流通性更好(工具链无关)。

无界微前端是一款基于 Web Components + iframe 微前端框架,具备成本低、速度快、原生隔离、功能强等一系列优点。

它们均已在腾讯云、腾讯新闻的多个 toB 、toC 场景经历考验,期待你的关注与了解,让我们一起在微前端领域探索出更多的可能性。

总结

本文讨论了很多关于微前端的新理解,你理解到究极奥义了么,是不是和你和你之前所接触的微前端概念有所不同呢,期望你能在 容器型微前端模块型微前端 之间找到最佳的平衡点并付诸实践。

5961 次点击
所在节点    程序员
46 条回复
nasa
2022-11-15 11:02:15 +08:00
一直在使用 https://single-spa.js.org/

效率提升了很多,复用子应用很方便~

应对公司的一些 POC 演示需求都能快速的拼装出来。
rodrick
2022-11-15 11:02:56 +08:00
@rodrick 确实是漏看了 有个 versionId 挺好的
RealJacob
2022-11-15 11:10:53 +08:00
@yaphets666 当然,这些场景肯定也会有别的解决方案,但微前端肯定也属于其中一个,加上接入改造的成本其实并不太高,所以会有需求
yaphets666
2022-11-15 11:16:57 +08:00
@RealJacob 这种需求之前常用的做法,如果不做到一个系统里,那就做统一认证登录,现在微前端是一个解决方案。但是和统一认证登录没有什么本质的区别。
RealJacob
2022-11-15 11:22:19 +08:00
@yaphets666 这个 sso 有啥关系呢?做了 sso 以后如何把多系统放到同一个页面中呢?
shakukansp
2022-11-15 12:07:33 +08:00
不是很懂楼上喷的
webpack 冷启动夹在 20000 个模块,ci/cd 要半个小时的很常见吧
微前端是能很好解决这个问题
虽然引入的新问题也挺多的,但是不至于没卵用
GentleFifth
2022-11-15 12:12:28 +08:00
总感觉这个东西引入的管理复杂度会超过这个东西带来的利益
cxzweb
2022-11-15 13:36:02 +08:00
@zed1018 你是什么品种 无脑喷
cxzweb
2022-11-15 13:39:05 +08:00
前端研究点新东西就是花活,有没强制你用这种技术,不知道楼里某些人哪来的优越感
yaphets666
2022-11-15 13:42:03 +08:00
@RealJacob 做到一个页面中做一个系统就可以了啊
shijingshijing
2022-11-15 13:50:26 +08:00
造词整活儿还是你们前端厉害。
Envov
2022-11-15 14:49:51 +08:00
我认真看了,微模块假如是一个组件,那么怎么能和技术栈无关呢
远程加载函数和发包有什么本质区别,发到生产环境的远程函数能随便动吗
如果只是 **为了在不影响任何人的情况下修复远程函数的漏洞** ,值的造这么大的概念吗
RealJacob
2022-11-15 15:06:19 +08:00
@yaphets666 你这不就是另一个需求了么,事实上没办法所有情况都有一个基座去做“一套”系统,如果只有两个业务方可能 ok ,那如果有二十个业务方需要协同开发呢?如何做到一个系统里?每个系统可能又是非常复杂庞大的,逻辑也都是不一样的,做到一起的话后续的维护如何维护?很显然是没法像你想的那样简单
RealJacob
2022-11-15 15:13:03 +08:00
@Envov
1. 和技术栈无关,那就是各个微前端方案要解决的问题。你可以理解为 iframe 也是一种微前端,主应用和子应用是技术栈无关的
2. 微前端加载和发包的区别,无需主应用发版。生产环境的子应用在经过测试后,可以直接发,不通过主应用。而发包不行。而发包也比较难避免“技术栈无关”这件事,react 项目怎么用 vue 包,反之亦然。(当然是有解决方案的,但也是有成本的,并且需要对当前项目有侵入性改动的)
3. 我理解子应用不影响主应用修复漏洞只是其中一个小的场景,还是有其他场景会用得到的
jjwjiang
2022-11-15 15:49:43 +08:00
这概念其实不新了,没必要喷

据我所知微软应该用了很久了,他们的 SAAS 提供内嵌 react 组件的功能
yaphets666
2022-11-15 16:38:33 +08:00
@RealJacob 我雀食没搞过 20 个业务方这种需求
RealJacob
2022-11-15 17:09:51 +08:00
@yaphets666 只是举个例子,可能略有夸张了。但我确实实际遇到过类似的情况,我就是那个基座。一个需要兼容老系统,新系统,n 多业务方的系统。
你要说 iframe 能做吧,也能,但需要砍掉非常多需求。目前的情况个人感觉是一个微前端不错的实践,我觉得是有用的
RealJacob
2022-11-15 17:12:53 +08:00
btw ,在我的场景里,20 个业务方还是往少了说,感觉算上写老系统的 rd 的话,历史上前前后后需要参与的 rd 应该是大于 100 人的,这里仅说 rd ,不算 pm 、qa 等。
RealJacob
2022-11-15 17:13:25 +08:00
yaphets666
2022-11-15 17:30:01 +08:00
@RealJacob 这就是我说的嘛,整合老项目,这种需求微前端很好啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/895285

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX