V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fantasticsoul
V2EX  ›  程序员

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

  •  
  •   fantasticsoul · 77 天前 · 4358 次点击
    这是一个创建于 77 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    微前端的起源

    image.png

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

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

    爆炸的数据

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

    image.png

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

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

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

    重刷存在感的微前端

    image.png

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

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

    微前端之 5 个核心思想

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

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

    image.png

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

    • 与技术无关
      每个团队都应该能够选择和升级他们的堆栈,而无需与其他团队协调。自定义元素是隐藏实现细节同时为其他人提供中性界面的好方法。
    • 隔离团队代码
      不要共享运行时,即使所有团队都使用相同的框架。构建自包含的独立应用程序。不要依赖共享状态或全局变量。
    • 建立团队前缀
      就尚无法隔离的命名约定达成一致。命名空间 CSS 、事件、本地存储和 Cookie ,以避免冲突并明确所有权。
    • 优先使用本机浏览器功能而不是自定义 API
      使用浏览器事件进行通信,而不是构建全局 PubSub 系统。如果你真的需要构建一个跨团队的 API ,尽量让它尽可能简单。
    • 构建弹性站点
      即使 JavaScript 失败或尚未执行,您的功能也应该很有用。使用通用渲染和渐进增强来提高感知性能。

    微前端之模块联邦

    以上阶段 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 两个出处的微前端定义做一个对比,并提出一个灵魂的拷问,是否以下表达成立?

    image.png

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

    • 容器型微前端

      我们把以 single-spa 为代表的这一类方案统称为微容器,在 single-spa 走红之后市面很多基于 single-spa 二次封装的库如雨后春笋般涌出,典型的代表作如阿里的 qiankun ,意在解决一些 single-spa 未解决的问题并让其更适合企业级开发,同时也诞生了很多非 singlespa 系的框架,如京东的 micro-app 、腾讯的 wujie 等,它们的细节实现各有差异,包含 js 沙箱隔离、css 隔离、iframe 编排、启用 web-component 、window 代理、接入过程等各个地方的细节也各有千秋,但它们都一个很显著的特点,对应的模块粒度是整个应用,做出的产品可以理解为一种以宏观态的方式来组合多个应用交付给用户使用。

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

    • 模块型微前端

      相较于微容器宏观态的组合应用方式,微模块则可以形容为微观态的组合方式,它的粒度更小,小到可以是一个函数,一个基础的组件,对于开发者来说,引入微模块和引入一个普通的 js 包没有任何区别,他们在使用上也并无任何区别,但恰恰是这一点!是它和微容器最大差异之一,微模块的使用方式回归到了 js 语法本身。

    image.png

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

    image.png

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

    image.png

    微前端技术该如何选型

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

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

    image.png

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

    • 1 是否需要多技术栈混合开发( react 、vue...)

    • 2 是否需要多版本技术栈同时迭代等(vue2, vue3...)

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

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

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

    混合架构的微前端实践

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

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

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

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

    关于 hel-micro 与 wujie

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

    image.png

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

    image.png

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

    image.png

    总结

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

    45 条回复    2022-11-16 11:47:28 +08:00
    Rache1
        1
    Rache1  
       77 天前   ❤️ 5
    我以为这个概念都凉透了,没想到是换了个锅炒。
    dqzcwxb
        2
    dqzcwxb  
       77 天前   ❤️ 2
    大前端 微前端 下次换什么名字炒
    yaphets666
        3
    yaphets666  
       77 天前   ❤️ 1
    我一直觉得,微前端的唯一作用就是整合老旧项目,新项目用微前端拆分我是想不通为啥,没事找事纯属闲的
    iapplebear
        4
    iapplebear  
       77 天前   ❤️ 2
    前端娱乐圈
    tommyzhang
        5
    tommyzhang  
       77 天前
    扯犊子放屁
    wangtian2020
        6
    wangtian2020  
       77 天前   ❤️ 5
    看到有人骂我就放心了
    hay313955795
        7
    hay313955795  
       77 天前
    .....微前端 打包最后还是打在一起的吗...
    ccyu220
        8
    ccyu220  
       77 天前   ❤️ 1
    真要扯的话「微前端」一直以来有且只有一个,那就是 iFrame ,其它就是脱裤子放屁。
    q474818917
        9
    q474818917  
       77 天前   ❤️ 1
    其实引入了很多新的概念和技术,后面发现生产力并没有提高,矛盾却不断地增加,这是可喜还是可悲
    Desiree
        10
    Desiree  
       77 天前
    为了卷而卷的技术,为了 KPI 绩效好看一点,不是为了创新方便和管理更优
    DualWield
        11
    DualWield  
       77 天前   ❤️ 6
    微前端的适用场景,你们甚至不愿意打开谷歌搜一下。

    你们没有遇到过一个复杂的中台系统,但是由多个团队维护的吗?
    你们没有遇到过一个老的中台系统,现在一个全新模块,可以用微前端改造的吗?
    lvma0shu1gua1
        12
    lvma0shu1gua1  
       77 天前   ❤️ 1
    在国内互联网公司,前端团队很大,老板也喜欢做平台型的产品:自建的数据平台、业务聚合平台等等,这种场景可能催生了微前端技术栈。
    到外企后团队较小,也没有专门的前端团队,业务也不会这么复杂,微前端没啥必要。
    GiantHard
        13
    GiantHard  
       77 天前
    有个问题,使用 hel-lodash 跟直接用 webpack externalize 的 lodash 相比,有啥好处吗?
    lookStupiToForce
        14
    lookStupiToForce  
       77 天前
    好像每一个前端(新?)技术的帖子下你们都能吵起来,后端看得瑟瑟发抖
    MMMMMMMMMMMMMMMM
        15
    MMMMMMMMMMMMMMMM  
       77 天前
    太长;不看
    fyooo
        16
    fyooo  
       77 天前
    @lvma0shu1gua1 好像是这样,原来在一个外企的时候,他们内部的系统都是很简单的前端架构,甚至没有用到 react 和 vue 。
    zed1018
        17
    zed1018  
       77 天前
    前端花活真多
    yl20181003
        18
    yl20181003  
       77 天前   ❤️ 1
    强行微前端不可取,但这个东西确确实实有它的应用场景的,前端也有巨石应用,也有新老项目兼容的问题,无脑喷的都是啥人啊
    rodrick
        19
    rodrick  
       77 天前
    大致看了一下 想法还是比较好的 远程模块这种我们这边也有线上组件组合页面的配置使用方式(虽然没有用联邦模块且是中心化统一管理模块) 但是有个问题不知道是否能解决(可能我没有看到) 拉取的远程库能有版本管理么 比如我项目内想锁定 1.0 版本 远程模块已经升级到 2.0 版本 我看了一下都是 preFetchLib("xxx" ) 这种情况能处理么
    RealJacob
        20
    RealJacob  
       77 天前
    @yaphets666
    个人感觉,部分 iframe 能做的,但要规避 iframe 的一些缺点的,会有一定的需求。想了两个场景,
    比如一些需要多业务方协作的「复杂」项目。例如一个复杂表单,同时需要填写财务报销的信息,和休假的信息,(举个例子,实际是否有这种场景另说),且需要做一些全局的弹窗样式,这样 iframe 不好处理的。这个场景可能涉及三方协调开发,1. 表单基座的研发 2. 财务系统的研发 3. hr 系统的研发。
    再一个,比如想做一个浮动的广告展位,可能有专门的业务方去开发这个广告,独立于基座主项目开发上线,没有固定的区域和大小去做 iframe 。
    nasa
        21
    nasa  
       77 天前
    一直在使用 https://single-spa.js.org/

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

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

    据我所知微软应该用了很久了,他们的 SAAS 提供内嵌 react 组件的功能
    yaphets666
        36
    yaphets666  
       77 天前
    @RealJacob 我雀食没搞过 20 个业务方这种需求
    RealJacob
        37
    RealJacob  
       77 天前
    @yaphets666 只是举个例子,可能略有夸张了。但我确实实际遇到过类似的情况,我就是那个基座。一个需要兼容老系统,新系统,n 多业务方的系统。
    你要说 iframe 能做吧,也能,但需要砍掉非常多需求。目前的情况个人感觉是一个微前端不错的实践,我觉得是有用的
    RealJacob
        38
    RealJacob  
       77 天前
    btw ,在我的场景里,20 个业务方还是往少了说,感觉算上写老系统的 rd 的话,历史上前前后后需要参与的 rd 应该是大于 100 人的,这里仅说 rd ,不算 pm 、qa 等。
    RealJacob
        39
    RealJacob  
       77 天前
    yaphets666
        40
    yaphets666  
       77 天前
    @RealJacob 这就是我说的嘛,整合老项目,这种需求微前端很好啊
    RealJacob
        41
    RealJacob  
       77 天前
    @yaphets666 这不是你说的情况,老项目其实只是其中很小一部分,小于 15%。需要做的主要是接新项目
    RealJacob
        42
    RealJacob  
       77 天前
    @yaphets666 我的重点在于,多方合作,逻辑复杂,我这种情况根本是不可能融合到一个系统中的,融合到一个系统只会越来越难维护。换一个负责人就再也不会知道前面的逻辑到底是什么情况了
    micean
        43
    micean  
       77 天前
    后端架构师入侵前端?
    ZRS
        44
    ZRS  
       77 天前 via iPhone
    修辞学大师
    Envov
        45
    Envov  
       76 天前
    @RealJacob 微前端我是认可的,我质疑的是微模块
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   实用小工具   ·   649 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 17:26 · PVG 01:26 · LAX 09:26 · JFK 12:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.