

微模块-前端业务模块化探索,拆解巨石应用的又一利器 - hiisea
source link: https://www.cnblogs.com/hiisea/p/16624472.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

大家好,我是Eluxjs的作者,Eluxjs是一套基于“微模块”和“模型驱动”的跨平台、跨框架『同构方案』,欢迎了解...
文前声明,以下推断和结论纯属个人探索,鉴于本人知识水平所限,谬误在所难免,恳请各位大佬不吝赐教...
什么是前端“微模块”?
Elux中的『微模块』是指在Web前端工程中,将代码和相关资源按照不同的业务功能
进行归类和模块化。
根据业务功能
进行模块化一直以来都是后端的普遍做法,而Web前端则通常都是按照UI界面的视图区块View
来进行模块化,这样的模块实际上只是Component组件
,不具备独立自治的能力。究其原因我想是因为在早期Web1.0的时代,前端的职能就是仅仅作为后端API数据的一个Render渲染器,所以前后端的视野和格局出现了分化,也导致很多人说前端根本无架构之说。
然而web生态发展到今天,浏览器越来越强大,赋能越来越多,甚至不亚于一个小型操作系统,这时候的Web前端早已不是当初简单的数据渲染器,状态管理、会话维持、数据持久化、文件缓存、通信协议...随着PWA、小程序、快应用的推广,WebAPP不再是瘦客户端,渐渐成长为大胖小子。
此时的我们应当跳出“渲染器”的井口,而从一个完整的软件工程来思考我们的前端架构,Web前端不只是一层View、一个GUI,我们需要回归到与后端一致的以业务领域
为驱动的模块化视角。
为什么前端需要“微模块”?
-
从开发角度来说:我们需要
高内聚、低耦合
的松散结构体,而不是牵一发而动全身的巨石应用,这不管是对于开发、维护、还是后期渐进式重构,都至关重要。前端Leader:经过一年多的迭代和人员变动,我们代码已经混乱不堪了,开发越来越吃力,必须要重构,否则玩不下去了! 产品经理:嗯,我理解,这里面也有很多是我们需求变更频繁引起的,我支持你们重构! 前端Leader:感谢大佬理解,那新需求先停下来,等我们重构好了再迭代吧? 产品经理:你们重构要多久? 前端Leader:产品这么复杂了,估计至少要3个月左右吧。 产品经理被吓出一身冷汗:大佬,你要3天还可以考虑,停下来3个月估计公司都要关门了... 前端Leader:可是产品这么复杂,几天时间完成重构是天方夜谭。 产品经理想了想:这样把,我每个迭代少安排几个需求,这样你们每个月就可以留几天时间重构了。 前端Leader:这可不是1+1=2的问题,而是0与1的问题,大佬你不了解! 产品经理:谁说我不了解,你们就不能渐进式重构吗? 前端Leader:...
此时如果我们的前端工程是基于“微模块”,一来可以轻松的找到“局部重构”的
边界
,二来也可以通过维持“微模块”的对外接口来无极替换。 -
从产品角度来说:软件架构永远是服务于业务需求的。我们希望我们的产品能像搭积木一样
按需组合
,可以快速包装出各种灵活多样的套餐,以满足客户越来越精细化的定制需求。某个大型应用包含A,B,C,D,E,F,G等若干功能,原来一直是整体打包出售... 随着用户需求的多样化,有的用户仅需要部分功能,于是聪明的前端架构师“小李”利用时下流行的微前端技术, 将应用拆分成了的 3 个子应用: - 【基础应用】包含功能:A - 【子应用A】包含功能:B,C,D - 【子应用B】包含功能:E,F,G 这样等于有 3 个套餐可以供客户选择: - 套餐A:基础应用 + 子应用A - 套餐B:基础应用 + 子应用B - 套餐C:基础应用 + 子应用A + 子应用B 然而用户的需求越来越精细化,有的需要ABCD,有的需要ACEG,有的需要ABDF... 而且同一个功能可能还存在需求版本的不同,这让“小李”无可适从。
现在我们利用“微模块”来帮助小李解决问题:
- 将各种独立的业务功能封装成不同的微模块:A,B,C,D,E,F,G
- 将各种微模块按需求迭代版本,发布成NPM包
- 某客户需要 A,C1(
C功能的某个版本
),E2(E功能的某个版本
),G 功能,我们单独为该客户创建一个聚合工程分支,安装相应版本的微模块:npm install A C@1 E@2 G
我们知道世界上有一款建站神器
wordpress
,曾经号称世界上50%的网站都是由它创建的,我认为它的成功秘诀就是社区模版机制和功能插件化,你要什么功能都总能找到“前端+后端”一起打包安装的插件,这也类似于“微模块”的概念。
- 从工程的角度来说:“微模块”是跨工程、跨项目共享
通用业务代码
的理想决方案,对于跨端、跨平台复用业务逻辑
尤其有用。
前端“微模块”的划分原则与边界
- 拥有
高内聚、低耦合
的工程结构。 - 拥有
独立自治
的子域逻辑。
从图中可以看到,每个微模块负责定义和维护自己领域内的事务,并且麻雀虽小,五脏俱全
,拥有独立的路由解析、状态管理、数据模型、控制器、视图、组件、资源、业务实体、API管理等等...总之,所有与自己领域相关的资源都被内聚到了一起。
以下是某巨石应用的SRC目录,其特点是以“文件职能”作为一级分类、“功能模块”作为次级分类:
├─ src
│ ├─ api # API接口管理
│ ├─ assets # 静态资源文件
│ ├─ components # 全局组件
│ ├─ config # 全局配置项
│ ├─ enums # 项目枚举
│ ├─ hooks # 常用 Hooks
│ ├─ language # 语言国际化
│ ├─ layout # 框架布局
│ ├─ routers # 路由管理
│ ├─ store # store
│ ├─ styles # 全局样式
│ ├─ typings # 全局 ts 声明
│ ├─ utils # 工具库
│ ├─ views # 项目所有页面
│ ├─ App.vue # 入口页面
│ └─ main.ts # 入口文件
以下是Elux中基于微模块的SRC目录,其改进是将“功能模块”作为一级分类,“文件职能”作为次级分类:
src
├── modules
│ ├── ModuleA
│ │ ├── entities
│ │ ├── assets
│ │ ├── api
│ │ ├── utils
│ │ ├── language
│ │ ├── components
│ │ ├── views
│ │ ├── model.ts
│ │ └── index.ts
│ │
│ ├── ModuleB
│ ├── ModuleC
微模块的台前与幕后
前端开发最终呈现的是UI界面,但这只是表象,支撑UI界面渲染和交互的是背后一系列state、model、controller等幕后英雄,它们根据自己所属不同领域被封装在各个微模块
中,UI既然与它们唇齿相依,必然也将跟随它们内聚在一起。
View和Component
本质上说View就是一个Component,但我们从架构的思维来区分它们:
- View:业务视图,它用来表现业务规则与逻辑,通常能够较为独立和完整的解决某一领域问题。
- Component:UI组件,它用来表现渲染规则与交互逻辑,通常不与具体业务直接相关,可复用在各种不同业务场景中。
所以在“微模块”的架构中,丰富多彩的UI界面由一个个单一职责的View聚合
而成,每个View同样依据自身所解决的领域问题而被分散
在各个微模块中,这里面有几个注意点:
- 领域性:View被归属到不同
微模块
的原则是其解决的问题领域,而不是视觉上的几何空间。View可以在视觉上被拆装、聚合、嵌套,这并不影响它们所属微模块。 - 完整性:一个View通常能解决一个较为独立和完整的问题,View与View之间是较为松散的关系,如果2个View之间联系紧密,那就不应当拆分它们。
不以视觉延伸和几何空间作为View的微模块归属原则:如下图所示,假设有一个View用来展示用户资料
,我们将其放在UserModule这个微模块中,称其为UserModule.DetailView
,但你发现其中又包含一个该用户发表文章的列表
,你当然可以把这个列表单独提取出来作为一个新的View。从视觉上来看,它似乎和用户资料是连在一起的,似乎可以和UserModule.DetailView
放在同一个微模块中;但我们从它解决的问题来看,它属于文章领域,而与用户领域关系并不大,所以我们最好将其放在ArticleModule中,称其为ArticleModule.ListView
前端“微模块”的实现方案
- 定义和创建微模块,可借助于Eluxjs框架,当然你发现了其它框架也可以。
- 管理微模块,可借助于NPM仓库。
- 使用微模块,可借助于打包工具:
- 静态编译:微模块作为一个NPM包被安装到工程中,通过打包工具(如webpack)正常编译打包即可。这种方式的优点是代码产物得到打包工具的各种去重和优化;缺点是当某个模块更新时,需要整体重新打包。
- 动态注入:利用
Module Federation
,将微模块作为子应用独立部署,与时下流行的微前端类似。这种方式的优点是某子应用中的微模块更新时,依赖该微模块的其它应用无需重新编译,刷新浏览器即可动态获取最新模块;缺点是没有打包工具的整体编译与优化,代码和资源容易重复加载或冲突。
微模块 vs 微前端
从本意上来说,微模块只是一种工程结构和模块化方案,而微前端
只是它的一种应用场景之一。微模块架构不仅可以用来构建复杂的单体应用,也可以结合Module Federation
实现多子应用独立部署的“微前端”。
如果单独就微模块 + ModuleFederation
方式实现的微前端,与传统意义上的qiankun、icestark
等微前端方案相比,微模块方式胜在粒度更细、更灵活、更轻巧,而传统方式则胜在隔离性更好。
想到一个非常形象的比喻:
IFrame vs 微前端 vs 微模块
可类比于 进程 vs 线程 vs 协程
从左至右:越来越轻量化,隔离性逐渐变弱,灵活性逐渐增加。所以鱼与熊掌不可兼得,具体哪种方案最适合还得看不同的产品需求。
微模块之间的通信
- 微模块之间按照某些规则和约定共享同一个Runtime,强制隔离性较弱,所以它们之间的通信是轻量级的,可以相互引用与调用。
- 建议观察者模式,或者使用事件总线模式来保持微模块之间的松散关系,这是另一个故事,可参考Eluxjs中的
ActionBus
。 - 微模块
高内聚、低耦合
的划分原则,也意味着微模块之间不会出现特别复杂的互动与交流(互动密切的微模块应当合并)。
落地与实战
光练不说傻把式,光说不练假把式
,这里先把思路概念要说的说完,下面就要开始出实例了。先喝口水,请听下回分解...🤩🤩急性子也可以直接去Eluxjs官网,看看Demo,不吝赐教...
Recommend
-
106
广电总局再次给行业打了一针“镇定剂”,这一次扼腕叹息的是游戏领域。昨日下午,中国音数协游戏工委于官方网站发布了一则有关《绝地求生:大逃杀》(以下简称《绝地求生》)的消息,消息称:由于近段时间《绝地求生》在国内火热、不少游戏开发者都有开发意向。因此...
-
41
-
40
据台湾媒体报道,巨石强森(DwayneJohnson)和女友LaurenHashian结婚了!两人从2007年开始交往,虽然都没有正式结婚,但相继迎接两位宝贝女儿Jasmine和Tiana。他如今在美国时间8月18日,在社交网站宣布喜讯,两人在夏威夷终于结婚了!
-
31
据新浪娱乐报道,近日巨石强森在ins发文透露由于自己着急出门上班,情急之下徒手把液压铁门拆了下来。事后,他还拍下了现场照片与视频。据了解,当天巨石强森家的门由于暴风雨引起断电打不开,维修人员也要45分钟才能到,一想到团队还在等着自己开工,他就徒手把门...
-
7
据外媒报道,上周,一支数羊探险队在美国犹他州沙漠深处发现了一块神秘的巨石,他们警告全世界的人都不要靠近它。据当地新闻媒体KSLTV报道,犹他州公共安全部门的直升机机组人员发现了一个10到12英尺高的钢铁物体,他们称其为“monolith(巨石)”。
-
11
-
9
巨石到底是何方神圣?
-
23
对巨石应用说不:转转商业微前端qiankun历史项目迁移升级实践大转转FE关注微信公众号:大转转FE。 一个有趣的前端...
-
6
前端模块化开发实验(一)——模块概念以及webpack基础配置现在web 应用前后端分离,前端独立成一个专业,并且还工程化了,这个事实对于 经历过早期Web1.0和2.0的开发者而言,刚接触时应该是比较新奇的。 应用软件网络化,web services 成为不可阻挡的...
-
7
基于模块联邦与大仓模式的商家巨石应用拆分实践 作者:天意 2023-08-16 19:14:02 开发 微前端是目前解决应用拆分的主要解决方案,但是...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK