当前位置: 首页 > Web前端 > HTML

Elux-从“微前端”到“微模块”

时间:2023-03-28 00:51:51 HTML

前言:“前端微模块”这个概念有点新。虽然之前也有人提到过这个名词(不过是百度),只是简单的等同于Dynamicloadingofmodules并没有赋予它更大的意义,似乎也没有看到具体的实现方案。小弟也突发奇想,摸着石头过河,想和大家探讨一下“前端微模块”会不会成为一片浩瀚的天空?微前端够用吗?从产品的角度来看,一个大型应用程序包含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,而且同一个功能可能会有不同的需求版本,这让“小李”无奈适配。“微前端”还不够灵活,粒度不够细。从开发的角度来看,对于一些常用的业务流程和功能,比如“发送短信验证码”、“忘记密码”,如果多个项目需要,如何跨项目共享和维护?是简单的复制粘贴吗?还是把所有的脑筋都放在基地里?“微前端”并没有解决项目间代码复用和维护的问题。将业务功能打成模块对于后端开发来说,按照业务功能来划分模块几乎是业界的共识,而在前端开发中,往往是按照UI界面来划分模块。这样的前端模块实际上只是Component组件,不具备独立性和完整性。如果我们把完整的业务功能(包括UI组件、样式、图片、交互流程、业务逻辑、API请求、数据管理等)打包成一个NPM包,利用NPM的版本和依赖管理机制来维护客户需求,是不是?美不美?试想,一个客户需要A、C1(某版本C功能)、E2(某版本E功能)、G功能,我们只需要安装对应版本的npm包即可:npminstallAC@1E@2G业务模块成为NPM包,版本号与需求关联。伟大的!我们将这些包含完整业务功能的模块称为前端微模块。可见,所谓微模块,其实就是包含业务功能的NPM模块。微模块的划分微模块是实现具体业务功能所需资源的集合:划分视角:业务功能(非UI界面)划分原则:高内聚,低耦合(边界清晰)请注意“高内聚”,低“耦合”是唯一的划分标准,不需要单一的职责,所以一个微模块可能包含多个功能点,多个UI组件,以及一组相关的视图。如果两个微模块紧密依赖,紧密交互,请不要拆分,这样会使问题复杂化,一个常见的思路是使用后端Restful的理念,将每个资源的维护(增删改查)封装到一个独立的微模块中。micromodulesandUIcomponentsMicromodules和UIcomponents都是一个npmpackage,看起来有点像,其实有本质区别:UIcomponentsareasinglepackage;微模块是资源的集合。UI组件为复用而生,可能在多个地方被实例化,通常不包含具体的业务逻辑;而微模块不追求通用性,包含特定的业务逻辑,通常只需要初始化一次。一个微模块可能包含多个UI组件、视图、模型等,也可能只是没有任何UI的逻辑。微模块的开发和维护微模块的开发和维护就是NPM包的开发和维护,不需要任何额外的学习成本。你需要做的就是维护它的依赖关系,对外封装API,保证独立性和易用性。微模块的部署微模块的使用和部署通常有两种方式:静态编译:微模块以npm包的形式安装到项目中,可以通过打包工具(如webpack)正常编译打包。这种方式的好处是代码产品经过打包工具去重和优化;缺点是当一个模块更新时,需要整体重新打包。动态注入:利用打包工具(如webpack5的ModuleFederation)的动态加载功能,将微模块部署为子应用(类似现在流行的微前端)。这种方式的好处是每个子应用都是独立部署和运行的。子应用中的微模块更新时,其他应用无需重新编译,刷新浏览器即可动态获取最新模块;缺点是没有打包工具的整体编译和优化,代码和资源容易出现重复加载或冲突。Elux对以上两种部署方式都有支持和示例。对于Elux中的微模块,我们来看看目前流行的前端工程目录。假设有独立的函数ModuleA和ModuleB:src├──assets├──consts│├──ModuleA││├──Const1.ts//A│├──ModuleB│├──Const2.ts中用到的一些常量//B中用到的一些常量├──utils├──components│├──ModuleA││├──Component1.ts//A用到的一些UI组件│├──ModuleB│├──Component2.ts//一些B├──containers├──pages│├──ModuleA││├──Page1.ts//A│├──ModuleB│├──Page2.ts//A中使用的部分页面├──ModuleB│├──Page2.ts//部分页面使用inB├──models│├──ModuleA││├──Store1.ts//A中使用的一些状态定义│├──ModuleB│├──Store2.ts//B中使用的一些状态定义│Its特点是以“文件功能”为一级分类,以“功能模块”为二级分类。现在如果我需要删除ModuleB或添加ModuleC,您将不得不执行多个目录操作。随着文件越来越多,相互引用越来越复杂,ModuleB的相关资源和依赖就像一团乱麻一样散落在各个文件和文件夹中,你会发现要将ModuleB..剥离干净是一项巨大的工作。应该如何改进?以“功能模块”为一级分类,以“文件功能”为二级分类。注意模块的外部封装,不要绕过封装引用模块内部资源。下面是Elux工程的常用结构:src├──modules│├──ModuleA││├──assets│││├──imgs//A等用到的一些图片││├──consts│││├──Const1.ts//A中使用的一些常量││├──utils││├──components│││├──Component1.ts//A中使用的一些UI组件│├──views│││├──View1.ts//AView中用到的一些业务││├──model.ts//A的数据模型││└──index.ts//A的外包装导出│││├──ModuleB│├──在Elux工程中可以看到ModuleC,所有与功能模块相关的文件都放在一个单独的文件夹中,通过索引文件导出到外部。这是在Elux中独立开发、安装和运行微模块的基础。微模块vs微前端微前端是一个广义的概念,微模块也是实现微前端的解决方案。与之前狭义定义的微前端相比,微模块更灵活,但更不孤立(仅依赖于模块和约定的命名空间)。如果你没有权利协调整个项目,或者项目本身是一个异构系统(每个子应用使用不同的技术栈),那么微前端仍然是首选方案。如果用两个词来概括它们的特点:微前端更注重:微模块的隔离更注重:广义和狭义的自治微模块,也许你会说,不要否认微模块好,但是我们的工程量没那么大,没必要拿去市场给客户定制,所以微模块对我来说没有意义?其实我们上面说的都是狭义的微模块,即应用严格由微模块组成,不存在其他全局资源和顶层组件。目的是保证微模块的完整性,允许它们自由组合。,独立部署。从广义上讲,微模块可能并不以独立开发和部署为目标。可以有公共资源和组件,不需要将业务模块发布为npm包,可以一个一个安装。我们只需要使用微模块耦合模式的解决方案来组织我们的代码。不管你是否真的需要独立开发和部署微模块,我们都可以将我们的应用以微模块的模式进行架构,让资源高内聚低耦合,让项目保持清晰的上下文结构,提升代码的可维护性和可靠性。可重用性,这就是广义上的微模块能给我们的启示。为了证明这个想法不只是纸上谈兵,大家可以看看我的开源项目:Elux——基于“微模块”和“模型驱动”的跨平台跨框架“同构方案”》,里面所有的工程模板都是基于“微模块”的思想,其中Micro:基于Webpack5的微前端+微模块方案这个模板就是上面所谓的“狭义的微模块”,即一个以自主开发部署为目标的“微模块”,其他项目只是“广义的微模块”。安装方法:npx@elux/cli-initelux-init@elux/cli-init@2.1.1新建工程:/Users/hiisea/work/elux/aaatotally[44P]templatesarepulledfrom...?请选择平台架构CSR:基于浏览器渲染的应用[16P]SSR:基于服务端渲染+浏览器渲染的同构应用[8P]?Micro:基于Webpack5的微前端+微模块方案[8P]Taro:Taro-基于跨平台的Application(各种小程序)[8P]RN:基于ReactNative的NativeAPP(开发中...)[4P]抛砖引玉,你可能不会真正使用它,但它可能会给你带来新的想法...