首页 » 网站建设公司 » seo落地页ifame框架笼罩_iframe接班人微前端框架qiankun在中后台系统实践

seo落地页ifame框架笼罩_iframe接班人微前端框架qiankun在中后台系统实践

访客 2024-10-18 0

扫一扫用手机浏览

文章目录 [+]

inner系统基座

业务现状问题

掩护迭代,随韶光延续是不可避免的

seo落地页ifame框架笼罩_iframe接班人微前端框架qiankun在中后台系统实践 seo落地页ifame框架笼罩_iframe接班人微前端框架qiankun在中后台系统实践 网站建设公司

至今,inner/outer 均有以下特点:

seo落地页ifame框架笼罩_iframe接班人微前端框架qiankun在中后台系统实践 seo落地页ifame框架笼罩_iframe接班人微前端框架qiankun在中后台系统实践 网站建设公司
(图片来自网络侵删)
页面构造繁杂 分类较多,菜单页面多;布局五花八门,分歧一技能栈分歧一 历史缘故原由,存在 jquery、静态模板、react 等技能栈权限分歧一 不同用户,权限不一样,利用的功能模块不同项目管理分歧一 部分功能模块是由业务方掩护;同一功能模块面向不同用户角色,也须要在不同系统中利用

初次打仗上述问题时,闪现在脑海里的是:用 iframe 呀。
确实,刚开始也是这样做的。

问题暴露,在掩护迭代中是个契机

系统在一个永劫光跨度的运行下,随着掩护职员的变迁、利用人群的增多,更多的问题也纷至沓来:

样式分歧一

由于没有统一规范,每个功能模块在不同的开拓者键盘下设想的构造不同,输出的风格也分歧一,使全体系统看起来略显凌乱。

浏览器提高/退却撤退

首先,iframe 页面没有自己的历史记录,利用的是基座(父页面)的浏览历史。
以是,当iframe 页在内部进行跳转时,浏览器地址栏无变革,基座中加载的 src 资源也无变革,当浏览器刷新时,无法勾留在iframe内部跳转后的页面上,须要用户重新走一遍操作,体验上会大打折扣。

弹窗遮罩层覆盖可视范围

iframe 页产生的弹窗,一样平常只能遮罩 iframe 区域。

页面间通报

与基座非同源下,iframe 无法直接获取基座 url 的参数,通报须要周转一下,如利用postmessage来实现;而动态创建的 iframe 页,或许还须要借助本地存储等。

页面缓存

iframe 资源变更上线后,打开系统会创造 iframe 页依旧是老资源。
须要用韶光戳方案或逼迫刷新。

加载非常处理

与基座非同源下,onerror 事宜无法利用。
利用 try catch 办理此问题,考试测验获取 contentDocument 时将抛出非常

以上问题,从业务代价看,对用户的利用体验会有丢失;从工程代价看,希望能通过技能提升业务体验的同时,也提高系统的掩护性。

改进实践 - 微前端

实践新技能,在问题暴露时是方向

大多数工程师,包括我,一边儿嘴里说着:学不动啦!
一边儿想考试测验一些新办法来优化系统。

结合问题分类,有思考一些考试测验方向,如:

中后台 UI 规范:历经迭代,百花齐放,然而更须要的是找到得当我司的风格,保持同等性。

其余,大互联网时期,从工程角度看,社区对类似系统的探索有很多,除了 iframe 外,也有不少相对成熟的替代方案:

1. single-spa

2. qiankun

提起这两个,就要提一下微前端理念,目前社区有很多关于微前端架构的先容,这里大略提一下:

Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. — Micro Frontends

大致是说,微前端有以下特点:

技能栈无关:基座不限定子运用的技能栈完备独立:子运用独立支配掩护,接入时基座同步更新;又可独立运行

基于此,不难想到:iframe 也是符合微前端理念的。
那其他方案又是如何做的呢?

single-spa

社区里 single-spa 先容也不少。
根据 demo 比葫芦画瓢,可以知道它的架构分布:

single-spa架构

启动做事的配置紧张是在single-spa-config 文件中,包含项目名称、 项目地址、路由配置等:

//single-spa-config.jsimport{registerApplication,start}from'single-spa';//子运用唯一IDconstmicroAppName='react';//子运用入口constloadingFunction=()=>import('./react/app.js');//url前缀校验constactivityFunction=location=>location.pathname.startsWith('/react');//注册registerApplication(microAppName,loadingFunction,activityFunction);//singleSpa启动start();

single-spa 让基座和子运用共用一个 document,那就须要对子运用进行改造:把子项目的容器和天生的 js 插入到基座项目中。

不须要 HTML 入口文件js 入口文件导出的模块,必须包括 bootstrap、mount 和 unmount 三个方法

<divid='micro-react'></div><scriptsrc=/js/chunk-vendors.js></script><scriptsrc=/js/app.js></script>

不过这种办法须要对现有项目的打包办法和配置项进行改造,本钱很大。
以是,对付已有的工程项目,我选择了放弃利用。

qiankun

qiankun 也是社区提到比较多的一个开源框架,是基于single-spa 实现了开箱即用。
可以采取html entry 办法接入子运用,且子运用只需暴露一些生命周期,改动较少。
【少】这个点,真是让我跃跃欲试。

目前我司业务场景是单实例模式(一个运行时只有一个子运用被激活),我们可以根据一张图来看看单实例下以html entry办法 qiankun 实现流程:

qiankun事理

如上图所示,一个子运用的全过程有:

初始化配置,匹配出子运用初始化子运用,加载对应的 html 资源,以及创建 JS 沙箱环境挂载子运用,实行生命周期钩子函数卸载子运用,当切换路由时,实行各卸载钩子函数,以及卸载 JS 沙箱环境,打消容器节点

详细实现细节,大家可以参考qiankun源码。

实践基座

从规范化开拓角度,我司的中后台系统是基于 umi 开拓(详细可参考我们之前的文章 umi 中后台项目实践)。
在构建主运用利用了配套的 qiankun 插件:@umijs/plugin-qiankun。

1. 初始化配置项,注册子运用

插件安装之后,我们可以在入口文件里配置:

此处紧张以运行时为例

//app.jsexportconstqiankun=Promise.resolve().then(()=>({//运行时注册子运用信息apps:[{//结算单管理name:'settlement',//唯一id,与子运用的library保持同等entry:'//xxx',//htmlentryhistory:'hash',//子运用的history配置,默认为当前主运用history配置container:'#root-content',//子运用存放节点mountElementId:'root-content'//子运用存放节点},{//公告name:'news',//唯一id,与子运用的library保持同等entry:'//xxx',//htmlentryhistory:'hash',//子运用的history配置,默认为当前主运用history配置container:'#root-content',//子运用存放节点mountElementId:'root-content'//子运用存放节点}],jsSandbox:{strictStyleIsolation:true},//是否启用js沙箱,默认为falseprefetch:true,//是否启用prefetch特性,默认为truelifeCycles:{//seehttps://github.com/umijs/qiankun#registermicroappsbeforeLoad:(props)=>{returnPromise.resolve(props).then(()=>loading())},afterMount:(props)=>{console.log('afterMount',props)},afterUnmount:(props)=>{console.log('afterUnmount',props)}}}))

2. 装载子运用,在路由配置中利用microApp来获取相应的子运用名称:

//router.config.jsexportdefault[{path:'/',component:'../layouts/BasicLayout',routes:[...{path:'/settlement/list',name:'结算单管理',icon:'RedEnvelopeOutlined',microApp:'settlement',//子运用唯一id},{path:'/settlement/detail/:id',name:'结算单管理',icon:'RedEnvelopeOutlined',microApp:'settlement',//子运用唯一idhideInMenu:true,},......{component:'./404',},],},{component:'./404',},]

以上便是基座的改动点,看起来代码侵入性很少。

子运用

在子运用中,须要做如下的配置

1. 入口文件设置 baseName,及暴露钩子函数

//设置主运用下的子运用路由命名空间constBASE_NAME=window.__POWERED_BY_QIANKUN__?"/settlement":"";//独立运行时,直接挂载运用if(!window.__POWERED_BY_QIANKUN__){effectRender();}//在子运用初始化的时候调用一次exportasyncfunctionbootstrap(){console.log("ReactMicroAppbootstraped");}exportasyncfunctionmount(props){console.log("ReactMicroAppmount",props);effectRender(props);}//卸载子运用的运用实例exportasyncfunctionunmount(props){const{container}=props||{};ReactDOM.unmountComponentAtNode(document.getElementById('root-content'));}

2. webpack 配置中,须要设置输出为 umd 格式:

//设置别名merge:{plugins:[newwebpack.ProvidePlugin({React:'react',PropTypes:'prop-types'})],output:{library:`[name]`,//子运用的包名,这里与主运用中注册子运用名称同等libraryTarget:"umd",//所有的模块定义下都可运行的办法jsonpFunction:`webpackJsonp_ReactMicroApp`,//按需加载}}//自定义webpack配置

OK,配置完成!

理论上,启动项目,支配等都该当没有问题了。
咦,打开地址,页面一贯在 loading,掌握台一堆报错,看起来要踩一踩坑了。

踩坑

1. 版本同等性

如果主运用和子运用都是基于 umi 框架,在利用 @umijs/umi-plugin-qiankun 插件时,要利用同一个版本,否则子运用报错。

2. 跨域

qiankun 是通过 fetch 去获取子运用资源的,以是必须支持跨域

constmountDOM=appWrapperGetter();const{fetch}=frameworkConfiguration;constreferenceNode=mountDOM.contains(refChild)?refChild:null;if(src){execScripts(null,[src],proxy,{fetch,strictGlobal:!singular,beforeExec:()=>{Object.defineProperty(document,'currentScript',{get():any{returnelement;},configurable:true,})};})}

比如:基座地址为 b.zhuanzhuan.com, 子运用为 d.zhuanzhuan.com 。
当基座去加载子运用时,会涌现跨域缺点。

曾经有采取通过 Node 做事做一层中转,跳过跨域问题:

....maxDays:3,//保留最大天数日志文件}//代理config.httpProxy={'/cors':{target:'https://d.zhuanzhuan.com',pathRewrite:{'^/cors':''}}};returnconfig

但考虑运用的访问量,以及线上线下环境掩护本钱,以为必要性不是很大,终极选择通过 nginx 办理跨域。

3. 子运用内部跳转

子运用内部跳转,须要在基座路由上提前注册好,否则在跳转后,页面识别不到。

{path:'/settlement/detail/:id',name:'结算单管理',icon:'RedEnvelopeOutlined',microApp:'settlement',hideInMenu:true,},

4. css 污染

qiankun 只能办理子运用之间的样式相互污染,不能办理子运用样式污染基座的样式。
比如:当切换到某个子运用时,左侧菜单栏溘然往右移了。

系统右移

查看掌握台,不难创造,子运用的相同模块覆盖了基座:

样式覆盖

这个问题,可以通过改变基座的前缀来办理,搞一个postcss 插件给不同的组件添加不同的前缀。

这里补充一个 css 隔离常用的办法如:css前缀、CSS Module、动态加载/卸载样式表。

qiankun 中 css沙箱机制 采取的是 动态加载/卸载样式表。

重写 HTMLHeadElement.prototype.appendChild 事宜

//Justoverwriteitwhileithavenotbeenoverwriteif(HTMLHeadElement.prototype.appendChild===rawHeadAppendChild&&HTMLBodyElement.prototype.appendChild===rawBodyAppendChild&&HTMLHeadElement.prototype.insertBefore===rawHeadInsertBefore){HTMLHeadElement.prototype.appendChild=getOverwrittenAppendChildOrInsertBefore({rawDOMAppendOrInsertBefore:rawHeadAppendChild,appName,appWrapperGetter,proxy,singular,dynamicStyleSheetElements,scopedCSS,excludeAssetFilter,})astypeofrawHeadAppendChild;....当子运用加载时,在 head 插入 style/link ; 当卸载时,直接移除。

//Justoverwriteitwhileithavenotbeenoverwriteif(HTMLHeadElement.prototype.removeChild===rawHeadRemoveChild&&HTMLBodyElement.prototype.removeChild===rawBodyRemoveChild){HTMLHeadElement.prototype.removeChild=getNewRemoveChild({appWrapperGetter,headOrBodyRemoveChild:rawHeadRemoveChild,});HTMLBodyElement.prototype.removeChild=getNewRemoveChild({appWrapperGetter,headOrBodyRemoveChild:rawBodyRemoveChild,});}

看起来很完美,但有时候会涌现,基座样式丢失的问题。
这个跟子运用卸载的机遇有关系:当切换子运用时,当前子运用沙箱环境还未被卸载,但基座 css 已被插入,当卸载时会连带基座 css 一起被打消。

5. 缺点捕获,降级处理

若子运用加载失落败,须要给相应的提示或动态插入iframe页:

//iframe.jsexportdefault({sourceUrl})=><iframesrc={sourceUrl}title="xxxx"width="100%"height="100%"border="0"frameBorder="0"/>import{render}from'react-dom';//全局未捕获非常处理器addGlobalUncaughtErrorHandler((event)=>{console.error(event);const{message,location:{hash}}=event;//加载失落败时提示if(message&&message.includes("diedinstatusLOADING_SOURCE_CODE")){Modal.Confirm({content:"子运用加载失落败,请检讨运用是否可运行"onOk:()=>import('./Inframe.js')});}});

6. 路由

子运用中存在按需加载的路由,在加载时页面样式丢失,这是官方库产生的问题,issue 里已有大佬提 PR 啦,可参考 https://github.com/umijs/qiankun/issues/857

以上,便是不完备踩坑。

后续

持续性思考会带来的技能红利

这次接入 qiankun,也只是处于表面运用。
后续我们更要思考接入它之后更深的工程代价,如:

- 自动接入 qiankun

结合我司已有的脚手架和 umi 模板,额外添加一个命令,自动注册子运用,做到自动化。

- 子运用间组件共享

基座和子运用大概率都用到了 react/dva 等,是否可以在基座加载完之后,子运用直接复用?当然,浅近思考该当少不了 webpack 的 externals。

标签:

相关文章

探索C语言在测试四中的重要性与应用

随着计算机技术的不断发展,C语言作为一种基础而强大的编程语言,在各个领域都得到了广泛应用。在测试四这个过程中,C语言的重要性不言而...

网站建设公司 2024-12-29 阅读0 评论0

探索C语言中的灯循环,点亮编程智慧之光

灯循环,是C语言编程中一个常见的循环结构。它通过重复执行一系列操作,实现对多个灯的控制。灯循环在嵌入式系统、游戏编程等领域有着广泛...

网站建设公司 2024-12-29 阅读0 评论0

探索ENDP语言,未来编程的璀璨星辰

随着科技的发展,编程语言不断更新迭代,其中,ENDP语言作为一种新兴的编程语言,逐渐引起了业界的广泛关注。本文将从ENDP语言的起...

网站建设公司 2024-12-29 阅读0 评论0

探索iirc语言的魅力与应用

随着互联网技术的飞速发展,编程语言层出不穷,其中iirc语言以其独特的魅力和强大的功能备受关注。本文将从iirc语言的起源、特点、...

网站建设公司 2024-12-29 阅读0 评论0

探索NTCC语言的魅力与价值

随着信息技术的飞速发展,编程语言层出不穷,其中NTCC语言因其独特的优势而备受关注。本文将从NTCC语言的定义、特点、应用等方面进...

网站建设公司 2024-12-29 阅读0 评论0

探索R语言中的度分布,提示网络结构的奥秘

度分布是网络分析中一个重要的指标,它描述了网络中节点度的大小分布情况。在网络科学、社会学、生物学等领域,度分布被广泛应用于研究网络...

网站建设公司 2024-12-29 阅读0 评论0