聊一聊微前端框架的选型和实现 | 业务平台

一、项目背景

目前,我们开发维护的项目主要有 6 个,但是分别对应 PC 和 H5 两个端:

82f134503de181d35243a94a0e31f8cb.png

如上图所示,我们 6个项目最开始是一个一个进行开发维护的,但是到后期,这几个项目之间有的部分会有业务逻辑不同,UI 基本相似的情况出现。而这几个项目前端维护人员较少, 这个时候就要考虑开发效率问题,我们希望相同部分共用,而不是每次都去项目里面进行复 制粘贴,重写逻辑。我们引入微前端,将相似的部分抽离出来,创建一个仓库,实现下图效果

613b2745f8deab74a1ca8ae9b0016b59.png 

但是上图也会造成一个问题,就是我们每抽离一个模块,需要单独申请一个仓库去进行维护, 这样子维护起来也很麻烦,我们在这个基础上进行改进,引入 MonoRepo+qiankun,最终实 现下图效果。所有模块放在一个仓库中,每次出现新的模块,我们在这一个仓库下面去创建 项目,只维护一个仓库,但是可以在不同项目之间进行切换。

8a64c70e1643e44ae815df4bf477caf7.png

二、微前端方案+技术选型

微前端架构旨在解决单体应用在一个相对长的时间跨度下,由于参与的人员、团队 的增多、变迁,从一个普通应用演变成一个巨石应用后,随之而来的应用维护难,成本越来越大的问题。

三、目前阶段流行的微前端方案

1、single-spa

在官网中被自称是一个元框架,可以实现在一个页面将多个不同的框架整合。很多微前端方案基于此进行二次开发或者是灵感来源,支持 esm。基本原理是:把 render 函数和 mounted 函数等钩子暴露出来,在远端引入后,在合适的时机执行,把组件挂载到 DOM 上。

缺点:如果不是用成型的框架,如 qiankun,从 0 开始搭建,比较繁琐。

优点:技术栈无关,对代码侵入性不强

2、qiankun

基于single-spa 的微前端解决方案,生产可用,阿里出品。

目前在交易平台项目中订单模块投入使用。 具体代码可以参考购小店的订单模块和购小店的使用方式。

3、MicroApp

一种用于构建微前端应用的极简方案,支持 esm(需要关闭沙箱)京东出品。

优点:qiankun 更多的是用路由的方式引入,microApp 更多是组件方式, 官方文档比较全面:开发文档,比 qiankun 强多了。

4、emp

基于 Webpack5 Module Federation 搭建的微前端解决方案,使用起来更优雅,使用远端的组件就好像本地组件一样,但是必须得是 webpack5。

官方对于跨框架调用不是很推荐,但是提供了Vue3 调用Vue2 组件; Vue&React 互相调用。

5、Garfish

包含构建微前端系统时所需要的基本能力,任意前端框架均可使用。接入简单,可轻松将多个前端应用组合成内聚的单个产品。沙箱隔离机制更完善。

6、Npm

npm 的方式相对来说,更加传统一些,如果用 npm 来做微前端的话:可能需要把原来业务,可复用模块抽离出来,在原来项目重新引入。专门维护一个公共模块的库,编译时候引入,导致最终的文件变大。

7、iframe

限制太大。除了特殊场合,不太推荐使用。

8、MonoRepo

严格来说,MonoRepo不算是微前端的解决方案,类似npm方式,但是也可以达到很方便的共享代码的效果。多个相似项目的代码在一个仓库里,把共用的业务逻辑或者组件抽离到单独 的项目中去维护。

四、技术选型

  • 因为所有的 C 端代码都是用的spack,所以排除了微前端中的 webpack模式

  • 不想对项目改动太大,所以也排除了npm模式和 iframe 模式。

  • 想要各个项目共享组件,所以采用monoRepo+qiankun,把多个项目在一个仓库中维护

五、项目实践关键点

1、在项目根目录下面创建 packages 文件夹,用来存放我们各种包,然后在根目录新建 pnpm 的工作区文件 pnpm-workspace.yaml,输入下面代码就可以将包进行关联

9c46211392e28f3a3791af8583359adf.png

2、路由页面

必须保证微应用加载时主应用这个路由页面也加载了。

主应用注册这个路由时给 path 加一个 *,注意:如果这个路由有其他子路由,需要另外 注册一个路由,仍然使用这个组件即可。这里我们根据不同的项目,activeRule 通过主项目传值的方式告诉子项目。

ebcd7978d871b131cabf933017c09542.png

78cede0b59dcc1ce737275772639289d.png

微应用的 activeRule 需要包含主应用的这个路由 path。 

6271809dc9b1c71b4b75a0d891240a78.png

3、安装 qiankun,在主应用注册微应用

94bd16b1bacc9a91290e465efdc4d221.png

4、在微应用导出相应生命周期钩子并配置微应用打包工具

f52dfea2251bbf6df77b22b196ee9215.png

 至此,MonoRepo+qiankun 项目搭建完成,可以在子项目中进行各自逻辑开发。

六、遇到问题

1、子项目如何知道应该走对应模块的逻辑 

将模块属性进行抽象,根据不同模块创建不同实例对象,在子项目mount 阶段根据主项目传的平台标识进行实例创建。 

f93015eee9385a285480b9972b98dbdf.png

2、子应用跟主应用不在同一个域名下跨域问题 因为不同子应用,申请的不同域名,单独打包部署,qiankun框架实际上是引入子应用打包生成的js文件,会出现跨域问题。开发环境要在子项目里面设置允许跨域。生产环境我们在nginx对应子项目的域名下面设置允许跨域。

3、登录cookie

我们项目里面没有将域名统一,拉取微应用 entry 的请求都是跨域的,所以通过自定义 fetch 的方式,开启 fetch的 cors 模式.

7472da1b831b44cd11a2ef225857c71d.png

4、CSS隔离

样式的隔离有很多种处理方式,如:BEM、CSS Module、css 前缀、动态加载/卸载样式表、Web Components 自带隔离机制等。

5、JS沙箱

如何确保子应用之间的全局变量不会互相干扰,实现js的隔离。普遍的做法是给全局变量添加前缀,这种方式类似css的BEM,通过约定的方式来避免冲突。这种方式简单,但不是很靠谱。qiankun 内部的实现方式是通过Proxy 来实现的沙箱模式,即在应用的 bootstrap 及 mount 两个生命周期开始之前分别给全局状态打下快照,然后当应用切出/卸载时,将状态回滚至 bootstrap 开始之前的阶段,确保应用对全局状态的污染全部清零  

6、数据通信

可以使用官方的initGlobalState方法

6434efad82f2d3f69de31c49f26fb289.png

我们这个项目应用之间不涉及数据共享,所以没有顶级  store 的概念。模块之间的简单通信可以通过 eventEmitter来实现。

c701afd7be06efb384aec5941be310e8.png

7、子应用缓存问题

子应用文件更新之后,访问的还是之前版本的内容,没有及时更新。 服务器需要给微应用的 index.html 配置一个响应头:Cache-Control no-cache,意思就是每次请求都检查是否更新。在nginx上配置:location = /index.html {   add_header Cache-Control no-cache; }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/93230.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

攻防世界-Web_php_unserialize

原题 解题思路 注释说了flag存在f14g.php中,但是在wakeup函数中,会把传入的文件名变成index.php。看wp知道,如果被反序列话的字符串其中对应的对象的属性个数发生变化时,会导致反序列化失败而同时使得__wakeup 失效(CV…

4.14 HTTPS 中 TLS 和 TCP 能同时握手吗?

目录 实现HTTPS中TLS和TCP同时握手的前提: 什么是TCP Fast Open? TLS v1.3 TCP Fast Open TLSv1.3 HTTPS都是基于TCP传输协议实现的,得先建立完可靠得TCP连接才能做TLS握手的事情。 实现HTTPS中TLS和TCP同时握手的前提: 1、…

【CP2K学习】-在Ubuntu上安装CP2K的全过程(包括gcc,gfortran,MKL等配置)

在Ubuntu中安装CP2K CP2K的安装检查系统是否安装gcc,gfortranMKL数学库的安装CP2K安装包下载CP2K的编译CP2K的测试ssmp版本测试popt版本测试 CP2K是第一性原理计算程序中发展迅速的程序之一,因其开源性、速度性等优点,是广大计算化学研究者的选择。 本文…

Git企业开发控制理论和实操-从入门到深入(三)|分支管理

前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…

原生web实现不固定列数的表格、随机列、document、querySelector、forEach、hasOwnProperty、call、includes

文章目录 效果图公共样式第一种解决方案(不推荐)第二种解决方案(强烈推荐) 效果图 公共样式 .d_f {display: flex; }.flex_1 {flex: 1; }.jc_sb {justify-content: space-between; }.ai_c {align-items: center; }.bc_ccc {background-color: #cccccc; }/* ------------paddin…

Ribbon:listOfServers ,${variableName:defaultValue}

解释: 配置了address的地址,请求会走address,也就是http://127.0.0.1:8081,通常用户与别的后端服务进行联调设置为其本地服务的ip。 如果address的地址被注释掉,如下面所示,类似这样的占位符${variableName:defaultVa…

Kafka学习笔记

目录 常见术语如何解决数据重复和数据乱序幂等性幂等性的缺陷事务事务原子性事务原理流程图 如何解决数据积压解决方法 Kafka的高水位(HW)和Leader Epoch副本同步机制解析Leader Epoch是如何解决消息丢失和消息不一致的问题的 常见术语 Kafka的三层消息…

Web安全测试(三):SQL注入漏洞

一、前言 结合内部资料,与安全渗透部门同事合力整理的安全测试相关资料教程,全方位涵盖电商、支付、金融、网络、数据库等领域的安全测试,覆盖Web、APP、中间件、内外网、Linux、Windows多个平台。学完后一定能成为安全大佬! 全部…

简述docker映射(Mapping)和挂载(Mounting)

映射的概念: 将容器内的端口映射到主机的端口上,这样就可以通过主机的网络接口与容器内部进行通信。主机上对应端口的请求会被转发到容器内部,从而实现对容器内部程序的通信访问(注意!这里提到的容器内部的端口并不一定…

arcgis的MapServer服务查询出来的结果geometry坐标点带*的问题

不知道小伙伴使用arcgis server服务做查询的时候,有没有遇到下面的问题 原因是查询结果中出现*字符 这个问题一直困扰了我很久:因为从数据库查询的坐标点是没有问题的。 一开始有同事遇到过,说重新插入下就好了,有时候确实能解决…

Qt 获取文件图标、类型 QFileIconProvider

Qt中获取系统图标、类型是通过QFileIconProvider来实现的,具体如下: 一、Qt获取系统文件图标1、获取文件夹图标QFileIconProvider icon_provider;QIcon icon icon_provider.icon(QFileIconProvider::Folder);2、获取指定文件图标QFileInfo file_info(n…

最详细jdk安装以及配置环境(保姆级教程)

一.进入oracle官网,下载jdk oracle官网:Oracle | Cloud Applications and Cloud Platform ps:不同的浏览器,可能进入oracle官网,会只显示部分内容,所以建议使用google Chrome浏览器 在下载之前,首先需要去…

UML四大关系

文章目录 引言UML的定义和作用UML四大关系的重要性和应用场景关联关系继承关系聚合关系组合关系 UML四大关系的进一步讨论UML四大关系的实际应用软件开发中的应用其他领域的应用 总结 引言 在软件开发中,统一建模语言(Unified Modeling Language&#x…

7 集群基本测试

1. 上传小文件到集群 在hadoop路径下执行命令创建一个文件夹用于存放即将上传的文件: [atguiguhadoop102 ~]$ hadoop fs -mkdir /input上传: [atguiguhadoop102 hadoop-3.1.3]$ hadoop fs -put wcinput/work.txt /input2.上传大文件 [atguiguhadoop1…

Mybatis-Plus快速入门

目录 一、基础工程 1、创建一个数据库:mp 2、添加数据 3、创建初始工程 4、添加依赖 二、Mybatis Mybatis-Plus 1、创建子工程:mybatis-plus-simple 2、在子工程下添加配置 2.1Mybatis实现查询User 2.1.1、编写User实体对象 2.1.2、编写UserMa…

pdf.js构建时,报Cannot read property ‘createChildCompiler‘ of undefined #177的解决方法

在本地和CI工具进行构建时,报如下错误。 Cannot read property createChildCompiler of undefined #177解决方法: 找到vue.config.js,在 module.exports {parallel: false, //新增的一行chainWebpack(config) {....config.module.rule(&…

微信小程序 基于Android的美容理发师预约管理系统

,本系统主要根据管理员、用户及理发师的实际需要,方便用户利用互联网实现对商品信息进行立即订购,同时让管理者可以通过这个系统对用户实际需求以及各信息进行管理。设计该系统主要目的是为了方便用户、理发师可以有一个非常好的平台体验&…

Qt/C++编写视频监控系统80-远程回放视频流

一、前言 远程回放NVR或者服务器上的视频文件,一般有三种方式,第一种是调用厂家的SDK,这个功能最全,但是缺点明显就是每个厂家的设备都有自己的SDK,只兼容自家的设备,如果你的软件需要接入多个厂家的&…

利用LLM模型微调的短课程;钉钉宣布开放智能化底座能力

🦉 AI新闻 🚀 钉钉宣布开放智能化底座能力AI PaaS,推动企业数智化转型发展 摘要:钉钉在生态大会上宣布开放智能化底座能力AI PaaS,与生态伙伴探寻企业服务的新发展道路。AI PaaS结合5G、云计算和人工智能技术的普及和…

前端如何走通后端接口

0 写在前面 现在基本都是前后端分离的项目了,那么前端小伙伴如何获取后端小伙伴接口呢? 1 条件 同一WiFi下,让后端小伙伴分享出自己的ip地址: 步骤1:winr调出运行界面 步骤2:cmd调出命令行窗口 步骤3:…