谈谈大家对微前端的看法 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
JefZ
V2EX    程序员

谈谈大家对微前端的看法

  •  
  •   JefZ 2024-09-10 14:34:14 +08:00 3596 次点击
    这是一个创建于 399 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一个项目,有首页,搜索页,购买流程,账号页面,售后流程。 总代码 40 万行。除掉单测,快照,大概 20 万行。几十个前端开发协同工作。 React 项目,有完善的懒加载机制,服务端渲染。Router + Redux 。 由于公司收购,新公司的架构变更,这个项目要迁移到新的仓库,新的云供应商,新的项目外部依赖。 有人提议使用微服务来重新按 domain (首页,搜索这些)对这个项目使用微前端的概念来重构基础框架。 虽然是不同的 domain ,但是它们有相同的基础组件依赖,有公共逻辑依赖,状态在 Redux 。传统,规规矩矩。

    下面是我个人在团队内提出的看法:

    • 项目虽然有不同的 domain ,但是有公共逻辑和组件,使用微服务会导致公共逻辑重复。因为微服务的概念和模块联邦不一样,微服务是一个自洽的服务,它可以独立运行,所以它必须有完整的逻辑和依赖。这意味着,拆分出的微服务需要重复很多逻辑,会带来很大的维护负担。
    • 我们不像门户网站,不同的 tab 对应不同的功能,可以根据 tab 拆分服务。比如,机票 tab 是机票团队的页面。酒店 tab 是酒店页面。它们完全是不同的服务。几乎没有公共业务逻辑(日志这些不算)。我们的服务没有 tabs 的概念。
    • 主应用和子应用,子应用和子应用之间的状态传递会导致逻辑和 debug 的复杂度指数级上升。加大了开发的心智负担。很多团队不止工作于一个 domain ,而是交叉的。
      • 这里我们考虑多一点。我们使用 styled-component ,所以 CSS 的隔离是一定要的。否则 id 会重复。
      • 既然拆分了,那就意味着我们需要独立部署每个微前端,每个微前端就需要照顾自己的服务端逻辑,比如预热,比如服务端数据请求。我们现在的拆包已经可以达到“浏览器只需要请求需要的 bundles”的目的了。所以独立部署带来的好处不大。
      • Redux 的状态共享,我们需要额外的机制来实现微前端的状态共享。
    • 严格考虑是否提升了用户体验和浏览器端性能。没有,反而降低了性能。增加了重复的逻辑和代码量,增加了资源消耗,复杂度增加。
    • 微前端本身是为了屏蔽不同技术栈,在同一页面展示和共享状态的,我们的服务本来就是一个整体服务。所有的公共逻辑都是一样的。
    • 虽然微前端可以让我们渐进式的迁移,但是后期整合带来的效率低,和复杂度的问题也是需要严格审视的。

    学识尚浅,有核心的东西没有考虑到吗?我不知道该用什么来作为辅助验证我说法的东西。

    23 条回复    2024-09-12 18:09:39 +08:00
    guiyumin
        1
    guiyumin  
       2024-09-10 14:35:20 +08:00
    module federation
    stew5566
        2
    stew5566  
       2024-09-10 14:51:17 +08:00
    菜鸡求解,好奇这种情况下,会使用 mitt 这样的事件对象做一个大的管线吗
    shunia
        3
    shunia  
       2024-09-10 14:52:48 +08:00
    直接把微前端框架调研一遍就知道了吧?在 issue 列表里面找几个万年不改的关键性问题拿出来给大家展示展示,要是有人拍板说都能接受。那就啥也别说了,改呗。

    状态共享,内存/性能管理,加载优化是三个比较大的问题,据我调研的结果来看,没有哪个微前端是真正提供了解决方案的,本身它们也并不承担这部分责任。

    状态共享相对简单一点,写代码就能解决的事情不是事情。

    内存/性能管理在于要根据不同的微前端框架进行调整,还会增加所有人写代码的心智负担。你测试写的很好的情况下,对测试也会带来更多成本,单测之外肯定要为性能而考虑做页面的压力测试。

    加载优化我也没想到好办法。对于首页来说加载问题是必须要解决的,首页的子页面越多,加载的文件量和渲染性能都有可能线性增长。尤其如果同时启动多个框架进行初始化或者渲染,想想都会头大。不过你只有 React ,会好解决一点。但是这个也会影响首页的指标啊,这责任谁承担呢?
    laommmm
        4
    laommmm  
       2024-09-10 14:53:57 +08:00
    微前端一开始就设计架构来做还行,统一规范。
    后面集成的,最后只会变成非常庞大的工程,揉在一起。
    并且基座会有非常多的问题等着解决,甚至有很多问题无法解决。
    shadowyue
        5
    shadowyue  
       2024-09-10 14:57:18 +08:00
    不管前端后端,一个项目最初的技术架构选型基本上决定了它的上限。
    可见的未来也不会改,很难改的动。
    JefZ
        6
    JefZ  
    OP
       2024-09-10 14:58:01 +08:00
    @guiyumin
    老哥提到模块联邦。
    模块联邦对于我们有个贼麻烦的点

    * 我们的项目的基础组件是一个单独的仓库,本质上,当基础组件库升级,希望所有依赖它的仓库都升级,虽然我们可以使用 bot 实现,你懂的,就是增加复杂度。
    * 本质上 domain 之间还是有依赖的,使用模块联邦给本地开发和部署也可能会带来一些心智负担。

    该怎么决策呢,综合微前端和模块联邦的好处,我们似乎一个都没用到[doge]

    GPT 对于这种决策问题也没办法。
    shakukansp
        7
    shakukansp  
       2024-09-10 15:12:08 +08:00
    vue
    模块联邦和 qiankun 都用过
    建议还是模块联邦……
    微前端一个是 vue 的 keep-alive 要弄的和单体应用效果一样没弄成功过,也可能实是我那项目有魔改的 vue-router 的原因

    模块联邦相对的问题少点
    rockey1997
        8
    rockey1997  
       2024-09-10 15:18:50 +08:00
    你这种很适合用 monorepo
    zy0829
        9
    zy0829  
       2024-09-10 15:19:14 +08:00
    @JefZ 那你们为啥不试试 monorepo + micro web?的方式
    yimov2
        10
    yimov2  
       2024-09-10 15:21:43 +08:00   1
    在团队内折腾过,实践下来发现:

    之前考虑的各个子应用独立开发优势完全没有展现。因为在实际业务中,一个需求经常会出现跨子应用开发,多个子应用经常共用一些状态、数据、依赖。

    反而页面性能、数据传输、依赖共享、心智负担都会成为隐性的技术债。

    在最开始得到的一点点小好处,最终都会成为架构上的大麻烦。
    lee88688
        11
    lee88688  
       2024-09-10 15:34:08 +08:00
    @JefZ 使用 mono repo 的方式组织呢,这样模块联邦用起来会好一些。我们这边就是 mono repo 都在一个仓库(不过我们没有用模块联邦),团队按照模块开发自己部分,外部依赖升级统一在最外层统一完成,对于主依赖模块内部不允有不同的版本。
    beq
        12
    beq  
       2024-09-10 15:34:46 +08:00
    我一直用的 qiankun ,做的后台系统
    讲讲微前端在我司的应用场景吧,先说说公司基建,我们前端有自己的工程化平台,每一个项目都能申请一个 appid ,或者多个项目分配一个 appid ,appid 的作用是分配一个二级域名,类似 xx.baidu.com/你的库名
    二级域名又是区分 pre prd 等环境的,关于发布,上线,灰度都能在平台上操作,所以维护,迁移方面都不用关心,只需要修改下数据库内存储的子应用映射路径就可。
    由于业务持续发展,产品迭代,不断细化,会有越来越多的内容更新,单个项目过于臃肿,于是根据功能将其划分多个子系统,基座应用主要用于承载,子系统脱离基座也能独立运行( qiankun 自带)。
    后台系统大部分是配置相关的,模块之间依赖很小,即使有数据依赖,接口层面也能解决。
    ...
    总之,微前端 是 iframe 的替代方案,是巨石应用的拆分方案之一,关于通信方面,微服务通过 rpc 通信,前端也可以通过 tsrpc 类似通信调用,通过 store/redux 这种方案,反而增加了心智负担,后续维护的人怎么知道 xxx 方法是 a, b,c 还是基座呢?如果你能携一些来源信息也可以,这就涉及通信方式的设计了
    hispy
        13
    hispy  
       2024-09-10 15:48:23 +08:00
    没看懂拆分的必要性。是因为项目体积太大,成员太多?
    mygao666
        14
    mygao666  
       2024-09-10 15:52:49 +08:00
    首先技术没有银弹
    你们统一技术栈,没必要上微前端
    Monorepo + pnpm ,感觉就可以了
    almon123
        15
    almon123  
       2024-09-10 15:57:33 +08:00
    微前端目前我用下来最大的优势就是:基本不用操心兄弟部门写的代码,连框架用啥都随他们(只要是主流框架),他们的模块线上挂了完全不影响我们其他模块运行。实现到这种效果要求你的基座应用必须精雕细刻,文档也得详细。
    微前端最适合的场景就是几个完全不搭边的团队,但开发出的产品需要放在一个系统里。
    19cm
        16
    19cm  
       2024-09-10 21:05:40 +08:00
    能不碰就不碰
    19cm
        17
    19cm  
       2024-09-10 21:06:47 +08:00
    我们项目为了刷新网页数据缓存,用无界,是缓存了,但随即一堆各种问题
    foolishcrab
        18
    foolishcrab  
       2024-09-11 01:40:08 +08:00 via iPhone
    微前端这种东西只能做无奈之选,根本不适合你们这种精益求精的重构。
    aikilan
        19
    aikilan  
       2024-09-11 11:32:04 +08:00
    t/935103#reply26
    一年前对微前端的疑问
    jones2000
        20
    jones2000  
       2024-09-11 14:36:35 +08:00
    不同的 domain ,微服务,先要考虑的是后台有一个聚合网关, 可以把接口 1+接口 2 聚合成一个新的接口 3 , 返回需要的数据。 然后根据前端显示定义好后台数据接口, 涉及到多个接口的,使用聚合网关,变成一个新的接口。总之前端要什么数据,后台就给什么数据,请求 1 次获取到。来回 3 ,4 次才能获取的完成数据的,然后后台重新开发。
    状态共享直接用 share worker
    JefZ
        21
    JefZ  
    OP
       2024-09-12 14:34:33 +08:00
    感谢大家提供参考

    @shunia @tianzi123 @yimov2 @shadowyue @laommmm @shunia

    > 增加后期心智负担

    这是最恐怖的。我们现在的模式挺好的,新的框架基于 Next ,相当于提供了初始化项目的范式,正正常常,没有垂涎的优势,复杂度守恒,除了可以统一框架,不一定能带来什么优化,边际成本变多。


    @beq

    > 于是根据功能将其划分多个子系统,

    哥你这个拆的太彻底了,这变成了彻底的前端微服务,每个子系统独立的很,我们应该没法和你们一样拆的这么彻底。

    @rockey1997 @zy0829 @lee88688 @mygao666

    > monorepo

    好主意。深化一下我们现在的项目结构。

    * 统一技术栈,项目按照 DDD 的思想,每个有边界的业务有自己的 domain ,几个 domian 结合起来就是 monorepo 中的一个 package 。现在我们不同的 domain 之间就互相干扰,每个团队这里引用一下那里导出一下,拆分成 package 也应该不会好转
    * 独立,独立构建,独立配置,因为原来就是统一的栈,所以独立后,无非是复制一份基础的配置和构建过程。
    * 项目的公共依赖,几乎每个 domain 都使用到了,没有一个 domain 有的依赖别的 domain 没有的场景。所以不存在依赖管理的问题。
    * CICD 么,bundles 包都被上传到了 CDN ,要服务器没有用。只有主应用因为要 SEO 和服务器端逻辑才需要服务器。大部分 domain 就安静的待着,没有服务端逻辑,静态文件服务都不需要。

    这种情况下,monorepo 的优势在哪里呢?因为没有做过,所以无法理解真实的项目问题和好处。

    @jones2000

    > 聚合网关

    我们有 BFF 。BFF 也要迁移。这就是另外的问题了。涉及到 BFF 和后端的访问延迟,访问权限。

    ----

    补充背景:
    这个主题主要是关注技术,但是我想增加一些额外的东西来说明我们除了技术上的选择,还有非技术的压力。
    新的公司架构有一套自己的,封装了 Next 的框架,围绕着这个框架有很多额外的依赖(比如翻译,配置)。高层决策希望统一技术栈。我们自己也挺想用新的体系,问题在于不想为了统一而统一,因为我们属于成熟项目,大家不都说理想的技术决策是基于理性表达代码嘛。
    JefZ
        22
    JefZ  
    OP
       2024-09-12 14:38:57 +08:00
    果然对于旁人的痛苦是缺乏想象力的,
    写代码的人才会真正在乎改动带来的困难,后期开发的复杂度,心智负担重,debug 变得更难,性能不好了。
    mygao666
        23
    mygao666  
       2024-09-12 18:09:39 +08:00
    @JefZ #22 哥们,写个代码这么痛? 有代码洁癖么?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5595 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 149ms UTC 01:25 PVG 09:25 LAX 18:25 JFK 21:25
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86