其实微网站html5源码分享下载的问题并不复杂,但是又很多的朋友都不太了解web网站源码,因此呢,今天小编就来为大家分享微网站html5源码分享下载的一些知识,希望可以帮助到大家,下面我们一起来看看这个问题的分析吧!
我会按照以下几个方向对微前端进行知识梳理:
什么是微前端,微前端的方案有哪些,微前端方案的对比,微前端的适用场景,微前端的实现思路,微前端的底层源码分析,微前端技术的延伸–Vue如何使用React项目的组件和webcomponments,以及微前端的一些开源项目。
1.什么是微前端
微前端是一种将前端应用程序拆分成更小,更独立的部分,以便于团队协作和维护的架构模式,可以理解为项目更加细粒度。
微前端允许不同的团队独立开发和部署各自的功能模块,同时保持整个应用程序的一致性和协调性,可以理解为一个项目分为了多个模块,多个模块可以自己开发和部署,符合我们高内聚,低耦合的期望。
微前端的核心思想是将前端应用程序视为一个由多个独立的微应用组成的整体,每个微应用都可以独立开发,测试,部署和运行。
微前端可以帮助团队更好的管理复杂的前端应用程序,提高开发效率和代码质
2.场景引入
我列出一些场景出来,大家可以思考下如何实现以及对我们的增益。
Vue,React,jQuery这三个技术栈的项目,领导让你把这三个项目合为一个。你的Vue,React项目不用npminstall,不用下载node_modules,如何运行。你的项目可以调用其他项目的组件,不用copy代码,就是直接调用。多个项目之间可以进行状态交流(这个延伸下没准可以增加个单点登录的实现方案)。UI组件库的开发,每个组件的开发都不用考虑会影响到其他组件,而且可以实现可插拔以及增量构建。
其实还有很多好玩的场景,我就不一一列举了,上述这些都可以用微前端来实现。
3.方案梳理
微前端的实现方案有很多,我做一个比较全面的梳理,目前各类前端方案层出不穷,找到最适合自己团队业务的方案极为重要。
Single-SPA
用于构建微前端应用的JavaScript框架,它可以将多个独立的应用程序组合成一个整体应用程序。是一个将多个单页面应用聚合为一个整体应用的JavaScript微前端框架。在同一页面上使用多个前端框架,而不用刷新页面。不限技术栈。支持独立部署每一个单页面应用。新功能使用新框架,旧的单页应用不用重写可以共存。有效改善初始加载时间,延迟加载代码。文档地址:zh-hans.single-spa.js.org/docs/gettin…
qiankun
基于Single-SPA的微前端框架,它提供了更加完整的微前端解决方案,包括应用程序的注册,加载,通信等功能。基于single-spa封装,提供了更加开箱即用的API,不限技术栈。HTMLEntry接入方式,让你接入微应用像使用iframe一样简单。样式隔离,确保微应用之间样式互相不干扰。JS沙箱,确保微应用之间全局变量/事件不冲突。资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速微应用打开速度。umi插件,提供了@umijs/plugin-qiankun供umi应用一键切换成微前端架构系统。文档地址:qiankun.umijs.org/zh/cookbook
Piral
用于构建微前端应用的框架,支持多种前端框架和库,同时提供了一些额外的功能,如插件系统和扩展性。渐进迁移。共享库。共享现有布局和程序框架。文档地址:github.com/smapiot/pir…
Bit
用于构建和共享组件的平台,可以用于构建微前端应用,Bit提供了一些核心的AP和工具,例如组件注册,版本管理,依赖管理,测试和构建等,可以快速构建和部署微前端应用,这个建议和CloudAlfa搭配使用。I具有传统单体式前端的安全性和健壮性。介接入方式简单、可伸缩性强。通过简单的解耦代码库、自治团队、小型定义良好的API、独立的发布管道和持续增量升级,增强工作流程。文档地址:bit.dev/docs/quick-…
ModuleFederation
用于构建微前端应用的框架,基于webpack,提供了一些高级功能,例如动态加载和模块化,远程动态容器,可以实现项目间的组件共享,依赖共享,函数共享,状态共享,其核心思想是代码统一。是webpack给出的微前端方案。使JavaScript应用可以动态运行另一个JavaScript应用中的代码,同时可以共享依赖。依赖自动管理,可以共享Host中的依赖,版本不满足要求时自动fallback到Remote中依赖。共享模块粒度自由掌控,小到一个单独组件,大到一个完整应用。既实现了组件级别的复用,又实现了微服务的基本功能。共享模块非常灵活,模块中所有组件都可以通过异步加载调用。我做了一个ModuleFederation的知识梳理,比官方文档好理解一些:juejin.cn/post/719804…文档地址:webpack.js.org/concepts/mo…
PuzzleJS
用于构建微前端应用的框架,可以将一个大型的前端应用拆分成多个小型的子应用,并实现子应用之间的通信和协作。SEO友好,在服务端进行准备和渲染。当片段所需的api出现故障时,PuzzleJs可保证其他页面片段仍正常工作。文档地址:github.com/puzzle-js/p…
Micro-app
基于微前端架构的前端应用程序,采用了Single-SPA框架作为基础,同时也进行了一些定制化的开发,目前Micro-app已经在京东的多个业务场景中得到了应用美丽如京东商城,京东金融,京东物流等。使用简单,接入微前端成本低。零依赖。兼容所有框架(不需要提供脚手架工具)。提供了JS沙箱、样式隔离、元素隔离、预加载、资源地址补全、插件系统、数据通信等一系列完善的功能。文档地址:zeroing.jd.com/docs.html39;[qiankun]name、entry、containerarerequiredforeachmicroapplicationtoregister.&39;&39;string&39;http://localhost:3001/remoteEntry.js&39;./module&39;path&39;webpack&39;app1&39;remoteEntry.js&39;./module&39;./src/module&39;path&39;webpack&39;app2&39;remoteEntry.js&39;app1@http://localhost:3001/remoteEntry.js&39;path&39;webpack&39;app1&39;remoteEntry.js&39;./module&39;./src/module&39;^17.0.0&39;react-dom&39;^17.0.0&39;path&39;webpack&39;app2&39;remoteEntry.js&39;app1@http://localhost:3001/remoteEntry.js&39;^17.0.0&39;react-dom&39;^17.0.0&39;hello-feng-template&39;open&39;hello-feng&39;vue&39;vue-custom-element&39;./hello-feng.html&39;hello-feng-vue&39;react&39;react-dom&39;react-custom-elemets&39;./hello-feng.html&39;hello-feng-react&或者npmiqiankun-S\n复制代码
在主应用注册微应用main.js
放在main.js的尾部
import{registerMicroApps,start}from&39;;\n\nregisterMicroApps([\n{\nname:&39;,\nentry:&39;,\ncontainer:&container-vue&39;/micro-vue&39;/micro-vue&39;micro-clouds&39;//localhost:7000&39;/micro-clouds&39;39;,//子应用挂载的div\n//传递给子应用的参数\nprops:{\nrouterBase:&39;,\n}\n}\n]);\n//启动微应用\nstart();\n复制代码
当微应用信息注册完之后,一旦浏览器的url发生变化,便会自动触发qiankun的匹配逻辑,所有activeRule规则匹配上的微应用就会被插入到指定的container中,同时依次调用微应用暴露出的生命周期钩子。
如果微应用不是直接跟路由关联的时候,你也可以选择手动加载微应用的方式:
import{loadMicroApp}from&39;;\n\nloadMicroApp({\nname:&39;,\nentry:&39;,\nactiveRule:&39;,\ncontainer:&subapp2&39;/micro-clouds&39;./public-path&39;vue&39;@/App.vue&39;vue-router&39;@/router&39;@/store&34;34;):&app&34;&34;/micro-clouds&39;[vue]vueappbootstraped&39;/:micro(micro-vue|micro-clouds):endPath(.*)&39;MicroApp&39;微前端应用&34;qiankun&39;@/views/qiankun/MicroApp.vue&34;layout-containermicro-container&34;$store.state.app.isLoadingMicro&34;Loading…&34;subapp1&34;subapp2&39;vue&39;qiankun&39;vue-router&39;@/views/qiankun/micro-app&39;MicroApp&39;=======&34;scss&39;qiankun&39;@/store&39;@/assets/js/utils&39;micro-clouds&39;/micro-clouds&39;39;,//子应用挂载的div\nprops:{\nrouterBase:&39;,\nmainStore:store,\nuser:utils.getStorage(&39;)\n}\n}\n]\n\nexportconstregisterApps=()=>{\nregisterMicroApps(microApps,{\nbeforeLoad:(app)=>{\nstore.commit(&39;,true)\nconsole.log(&39;,app.name)\n},\nbeforeMount:[\n(app)=>{\nconsole.log(&39;,&39;,app.name)\n}\n],\nafterMount:[\n(app)=>{\nstore.commit(&39;,false)\nconsole.log(&39;,&39;,app.name)\n}\n],\nafterUnmount:[\n(app)=>{\nconsole.log(&39;,&39;,app.name)\n}\n]\n})\n\nstart({\nsandbox:{\n//默认开启预加载\nprefetch:&39;,\n//qiankun提供的样式隔离方法(严格模式)\nstrictStyleIsolation:true,\nexperimentalStyleIsolation:true\n}\n})\n}\n复制代码
微应用配置mian.js
import&39;;\nimport{createApp}from&39;\nimportElementPlusfrom&39;\nimportNProgressfrom&39;;\nimport*asELIconsfrom&39;\nimportzhCnfrom&39;\nimportdraggablefrom&39;\nimport&39;\nimport&39;//css初始化\nimport&39;//公共css\nimport&39;\nimportAppfrom&39;\nimport{createRouter,createWebHistory}from&39;;\nimportroutesfrom&39;\nimportstorefrom&39;\n\nletinstance=null\nasyncfunctionrender(props={}){\nconst{container,routerBase}=props;\n\ninstance=createApp(App);\nconstrouter=createRouter({\nhistory:createWebHistory(`${routerBase}`),\nroutes\n});\ninstance.use(router);\ninstance.use(ElementPlus,{\nlocale:zhCn\n});\ninstance.use(store);\ninstance.component(&39;,draggable)\n/*eslint-disable*/\nfor(const[key,component]ofObject.entries(ELIcons)){\ninstance.component(key,component);\n}\n\ninstance.mount(container?container.querySelector(&app&34;34;);\n\n//eslint-disable-next-lineno-underscore-dangle\nif(window.__POWERED_BY_QIANKUN__){\nrouter.afterEach((to)=>{\nconstmatched=to.matched.map((item)=>{\nreturn{\n…item,\npath:`${routerBase}${item.path}`,\nredirect:`${routerBase}${item.path}`,\n};\n})\nprops.mainStore.dispatch(&34;,[\n…matched\n]);\n});\n}\n\nrouter.beforeEach(async(to,from,next)=>{\nNProgress.start();\nif(store.getters[&34;]){\nnext();\n}elseif(store.state.app.whiteList.includes(to.path)){\n//白名单页面\nnext();\n}else{\nnext(&34;);//全部重定向到登录页\n}\n});\n\nrouter.afterEach((to)=>{\nconstkeepAliveComponentsName=store.getters[&34;]||[];\nconst{name}=to.matched[to.matched.length-1].components.default;\nif(to.meta&&to.meta.cache&&name&&!keepAliveComponentsName.includes(name)){\nstore.commit(&34;,name);\n}\nNProgress.done();\n});\n}\n\n//eslint-disable-next-lineno-underscore-dangle\nif(!window.__POWERED_BY_QIANKUN__){\nrender({container:&34;,routerBase:&34;});\n}\n\nexportasyncfunctionbootstrap(){\nconsole.log(&39;);\n}\n\nexportasyncfunctionmount(props){\n//标记当前启动形式为微服务启动\nstore.commit(&34;,true);\nawaitrender(props);\n}\n\nexportasyncfunctionunmount(){\ninstance.unmount();\n}\n复制代码
public-path.js
(function(){\nif(window.__POWERED_BY_QIANKUN__){\n__webpack_public_path__=window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;\n}\n}());\n复制代码
vue.config.js
constpath=require(&39;)\n\nmodule.exports={\npublicPath:process.env.NODE_ENV===&39;?&39;:&39;,\nconfigureWebpack:{\noutput:{\nlibrary:&39;,\nlibraryTarget:&39;,\njsonpFunction:&39;\n},\n},\ndevServer:{\nport:4003,\ndisableHostCheck:true,\nheaders:{\n&39;:&39;//主应用获取子应用时跨域响应头\n},\nproxy:{\n&39;:{\ntarget:process.env.VUE_APP_TEST,\nchangeOrigin:true,\npathRewrite:{\n&39;:&39;\n}\n}\n}\n}\n}\n\n复制代码
到这为止,一个完整的微前端架构就搭建好了,下面来介绍各个细节的交互是怎么处理的。
2.父子应用耦合以及单独使用
简单讲就是为了满足更多更灵活的使用要求,咱们设计要能满足主应用与微应用耦合在一起使用,也可以子应用单独使用,不仅满足了用户的需求,还可以方便开发人员调试。(联调子应用时子应用一定是能独立启动的,并且有自己的登录、菜单功能,说白了就是一个完整的系统)
为了区分微前端运行还是单独运行,我们需要在子应用中插入微前端标识。
34;&34;/micro-clouds&这是子应用中微前端的钩子函数,如果是通过微前端启动,就通过这里来启动项目\n\nexportasyncfunctionmount(props){\n//标记当前启动形式为微服务启动\nstore.commit(&34;,true);\n//props是主应用传过来的参数\nawaitrender(props);\n}\n复制代码
区分好了之后,就需要将子应用中的菜单、头部状态栏隐藏,只留下内容区,连内容区周围的间隙都要去掉,因为主应用内容区也有间隙,避免样式冲突。
3.父子应用通信
原则上应该尽可能得降低父子应用之间的耦合,以免子应用单独使用时无法正常运行,也会增加维护成本。但是像登录信息的传递是有必要的,父应用登录了将登录信息传到子应用,避免子应用检测到无登录状态跳转到登录页面。
39;micro-clouds&39;/micro-clouds&39;39;,//子应用挂载的div\nprops:{\nrouterBase:&39;,\n//父应用的store传递给子应用\nmainStore:store,\n//父应用传递给子应用的登录信息\nuser:utils.getStorage(&39;)\n}\n}\n]\n复制代码
34;user&34;app/microChange&主应用vuex\nconstactions={\n//处理父应用的to.match\ngetBreadcrumb({commit},matched){\nconstlevelList=matched.filter((item)=>item.meta&&item.meta.title&&item.meta.breadcrumb!==false);\ncommit(&39;,JSON.parse(JSON.stringify(levelList)));\n},\n//处理微应用的to.match\ngetMicroBreadcrumb({commit},matchedList){\nconstmicroLevel=matchedList.filter((ele)=>ele.meta&&ele.meta.title&&ele.meta.breadcrumb!==false);\n/*\n*为了解决这个告警采用JSON.parse(JSON.stringify(microLevel))vue3.0需要注意的地方\n*runtime-core.esm-bundler.js:198[Vuewarn]:Avoidapplogicthatreliesonenumeratingkeysonacomponentinstance.\n*Thekeyswillbeemptyinproductionmodetoavoidperformanceoverhead.\n*/\ncommit(&39;,JSON.parse(JSON.stringify(microLevel)));\n}\n}\n复制代码
39;/micro&39;app/setMicroBreadcrumb&39;app/getBreadcrumb&子应用上报to.match给父应用\n好好回想一下,在父应用中传递给子应用的props中就有一个`mainStore`,这个就是父应用的store,可以直接在子应用中使用`props.mainStore.dispatch(&34;,[…matched]);`\n\nfunctionrender(props={}){\n…\nif(window.__POWERED_BY_QIANKUN__){\nrouter.afterEach((to)=>{\n//你可能发现这里为啥要改造`path、redirect`,路径前面拼接了一个`routerBase`\n//是因为在父应用中,如果子应用路由不带子应用的前缀标识路由是没法跳转进子应用页面的!!!\nconstmatched=to.matched.map((item)=>{\nreturn{\n…item,\npath:`${routerBase}${item.path}`,\nredirect:`${routerBase}${item.path}`,\n};\n})\nprops.mainStore.dispatch(&34;,[\n…matched\n]);\n});\n}\n…\n}\n复制代码
到这里基本上配置完成了,后面是一些遇到的样式bug,一定要实践,光看可能效果不大
5.父子应用中样式冲突的问题
当在父应用打开子应用时出现样式问题,正常在vue+element-plus的项目中,是这么引组件的样式
通过审查元素发现这个弹窗的dom节点的class样式少了一些属性,也就是光有class少了样式值,所以导致样式问题。目测是import引入样式的没法作用到子应用节点,改成在public/index.html通过link的方式引用
成功解决样式问题,需要注意的是当遇到样式问题时可以从引入方式、append-to-body属性(element-plus组件)着手排查。
配置完整个微前端架构,看似百八十行代码,其实遇到的问题还是蛮多的,跟撸个demo完全是两回事,网上可查的资料又少,官方文档只是介绍了那几个api的使用,干完这票确实提升不少,值得去尝试,我认为这是构架师必备技能。
6.qiankun加载子应用的协议会转成http的问题
前面由于都是在本地以及测试环境验证过,因为都是http协议所以没有暴露出这个问题。当到沙盒以及生产环境时,子应用页面加载不出来,我也没有改动代码,测试和生产是同一份代码,一直报这个错误
也就是主应用是https协议,子应用是http协议,导致了这个问题。现在问题清楚了,又有另外一个疑问,我的主应用指向子应用的路由是https啊,为什么被改成了http,这个问题我不太清楚是不是qiankun这家伙干的,官方也没说。
解决办法:
public/index.html头部加上这个
<metahttp-equiv=&34;content=&34;>\n复制代码
如果是统一加上这个,测试环境和本地环境又不行了,得区分开发,怎么办?
我们都知道,打包后生成的index.html是由html-webpack-plugin插件生成的,沿着这条线索找,插件文档果然有meta这个配置项github.com/jantimon/ht…
那么在vue-cli生成的项目中没有单独使用html-webpack-plugin,而是在vue.config.js里的pages入口这里配置,具体代码:
pages:{\nindex:{\nentry:&39;,\ntemplate:&39;,\nfilename:&39;,\ntitle:&39;,\nmeta:process.env.NODE_ENV===&39;||process.env.NODE_ENV===&39;\n?{}\n:{\n&39;:{&39;:&39;,content:&39;}\n}\n}\n},\n复制代码
完美解决!
项目部署
部署方式很多种,我这里只介绍我在项目中的实践。
主应用:main.xxx.com/home子应用A:clouds.xxx.com/projectA/ho…子应用B:clouds.xxx.com/projectB/ho…子应用C:clouds.xxx.com/projectC/ho…
现在的部署都流行CICD,docker+k8s,所以我采用的是每个项目都单独部署一个docker,最后通过域名+项目前缀进入项目,nginx配置如下:
入口文件\ntry_files$uri$uri//index.html;\n}\n复制代码
39;GET&39;DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization&39;GET&39;DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';\n\nroot/usr/share/nginx/html;\ntry_files$uri$uri//index.html;\n}\n复制代码
微网站html5源码分享下载的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于web网站源码、微网站html5源码分享下载的信息别忘了在本站进行查找哦。
