对于大多数前端来讲,无非就是写写简单的页面,我并非歧视前端,笔者也是前端,由于前端确确实实对于公司的总体业务的认知没有后端的了解的更加深入(毕竟人家是玩数据库的)。javascript
笔者在刚刚作公司内部系统的时候也只是作作简单的各个模块系统,如今大多数公司都是使用的微前端的系统架构,以达到各个业务依赖性没有那么大,一样也不会由于项目的逐渐扩大,致使项目愈来愈大,首先加载慢,再其次就是难以维护。css
可是全部项目都以微前端的形式分散开,就会遇到整合的问题,因而在咱们进行疯狂的讨论,由于使用的技术栈是Vue
这个因素也被考虑进去了,讨论出来初版最终解决方案。html
初期实现-iframe
其实对于大多数人来讲,一旦说到前端项目整合的话,第一个想到的就是iframe
,这种是最简单最的方法了,大多数公司都是使用的这这种方法对项目进行整合的。前端
废话咱们也就没多说,就开始开发了,遇到的第一个问题就是跨域,由于整合全部子项的每一个都有本身的域名,承载这些子项目的框架又有本身的域名。这里就使用了,document.domain
的解决了跨域问题。跨域的问题通常都会遇到,这也并非难解决的。vue
除了跨域问题,还有就是各个子项目的鉴权,各个子项目须要登陆以后的token
其实这个问题也不是特别困难,可是后端在作这个地方为了保证权限的安全性考虑,token
会随着一段时间进行变化,这样一来就不是简简单单的把token
传给子项目就好了,首先考虑的是,各个子项目携带者着token
向后端请求数据的时候,当token
发生变化的时候,须要通知登陆框架。java
在最初考虑这个问题的时候,考虑使用postMessage
进行通讯由于涉及的项目太多,并且使用postMessage
方法虽然轻便,可是以为这种方法有些臃肿,不太适用于咱们如今的总体架构方案。通过讨论以后,就放弃了这个方案。为何会放弃这个方案,由于当打开多个子页面的时候,其中一个子项目在请求数据过程当中token
发生变化了,其余子页面须要知道token
想要知道token
发生变化,就必须经过登陆框架通知,若是使用postMessage
的话就实在太不方便了。vue-cli
其实想要的无非是登陆框架的token
改变,子项目token
随着改变,这时机智的我想到了灰常优秀的Vue
,Vue
是使用的是Object.defineproperty
,经过该方法,各个子项目也好和登陆框架也好,只须要监控一个对象上某个自定义属性便可,这个使用我把矛头指向了window
,虽然这样不太好,可是针对于目前的状况window
是最好的选择。数据库
依赖实现结构图:express
解决了一些问题以后,也算是能够完成了初版虽然存在不少的问题,可是确实是能够用了。因而第一个版本就这样匆匆忙忙的上线了,用户反映怎么说呢,其实也没有那么好,毕竟是iframe
须要加载的会比较慢。还在想办法进一步优化一些。json
结构优化
时间天天都在流失,登陆平台依旧有不少的问题,对iframe
有所了解的同窗都应该知道,每次iframe
在打开的时候都须要从新拉取资源,这个是真的是太头疼了,然而这还不是最关键的问题,最关键的是什么,各个子项目每一个模块都在登陆平台里面,不少模块彻底在同一个项目里面,不少时候须要拉取相同的资源,这个实在是太难受了,做为一个前端来说,如此大量的重复资源加载,有点没法容忍。
有的时候各个子项目业务太大的时候,页面加载的实在是有点过于太慢了,在最初作项目时,那个时候单页面应用火热(如今也有大部分公司在使用),单页面应用就会带来这样的问题。
为了解决这个问题曾经考虑过使用路由懒加载,虽然能够实现一些资源的节约,可是,举个例子来说的话,若是当前模块只有一个只有表单,其余什么都没有,这个使用彻底不须要使用route
和stroe
,其余的在同一个项目里面的应用仍然用到了route
和stroe
,致使加载该模块的使用route
和store
同时也被拉取下来了,实在是让人头痛,自己我不须要这些东西,为何还要加载这些东西。我想哭~~~
带着这些疑问,开始寻求解决方案,通过一段时间的调研,发现多页面应用
彻底能够知足我如今的需求,经过多页面,只须要在对用的页面的实例中挂载对应所须要的资源就能够了。当读取到当前这个子项目中的某个模块的时候就能够作到这一点了。
这样作的好处在于当前子业务模块,须要用到route
就引入route
,用到stroe
就使用stroe
,打开页面也只会拉取相对应的资源。再也用担忧当前子项目拉取一些没有相关的资源了。
具体多页面配置请参考:Vue-cli3多页面配置
结构设想
虽然经过上面两部操做,已经对性能解决了很大一部分问题,可是,身为一个优秀的前端(咳咳咳,不要打断我。。。暂时不接受反驳,哈哈哈)来说得话,整个框架仍是存在一些问题。
route
和stroe
这些资源,为何子项目打开的时候,还要从新拉取一次呢?iframe
始终不是那么的优雅,会带来一些不可预知的问题,或者之后一些需求甚至会致使没法知足(虽然如今尚未遇到,可是仍是得为之后作打算)如下内容没有通过实践,还没法知道是否能够实现。
这个想法来自于SSR
,当调研Vue
的服务端预渲染的时候我发现,当客户端页面启动的时候是经过,读取客户端导出的一个json
文件,而且读取了里面的内容,找到对应的.js
文件,既然在服务端渲染的时候能够经过读取对应的js
文件作到页面的渲染,那么在前端渲染的时候是否是也能够来一波这样的骚操做呢?。这样一下灵感就来了,突然就有了一个大胆的想法。
关于这里还有一个小插曲想要说一下,我之前觉得ssr
是服务端解析了js
文件,可是被小伙伴给质疑了,其缘由是Node
根本就没得办法去解析js
文件。之前调研ssr
的时候用到了renderToString
的函数,可是,当时接收的是一个url
参数,也就是前端路由,createBundleRenderer
返回的对象中存在两个函数分别是renderToString
和renderToStream
,其中renderToString
函数接收的就是页面中所写的template
模板内容,最后把渲染好的页面返回给客户端。这是我本身后来理解的,再往下就要看源码,这里我没有详细看,毕竟与该文章内容不符,这里就不作多余赘述了,有兴趣的同窗能够看下。这里灰常感谢个人小伙伴指出了个人错误。
服务端渲染中节选的代码:
let render = vueRender.createBundleRenderer(serverBundle,{ template, clientManifest:clientBundle.data, renInNewContext:false }); // 重点就是这里 render.renderToString({ url:request.url }).then((html) => { respones.end(html); }).catch(error => console.log(error));
服务端渲染请参考:手把手教你搭建SSR(vue/vue-cli+express)
若是在Vue
打包的使用,能够把各个页面对应的css
文件js
统一写入到项目中的一个json
文件中,若是是这样的话,登陆框架能够经过域名获取到该模块对应的组件,而后经过动态路由route.addRoute
这个api
把读取到的组件注册到登陆页面,这样一来Vue
、store
、route
、组件库
这些东西就彻底可使用,登陆框架的了。岂不是一箭双雕的吗?这样的优化真的太大了。
上图中完成了操做以后,获取到对应的页面组件以后,经过路由动态注入到登陆框架中的,就好了。这些想法还在一步一步的调研过程当中。。。
总结
全部的项目不管大小,都须要演变,可是其中须要做为开发人员的咱们,进行不断的思考和优化,以达到一个比较好的状态,作前端也有一段时间了,我的以为,没有最好的选型,只有最适合选型,只有真正符合当前项目的需求的选型才是最正确的。
前端的路还有很长,还有太多太多的东西须要去考虑,前端所须要重视的是用户体验和数据交互,其实最最重要的还有就是性能。不能由于一个错误的想法,让用户以为当前的系统变得很慢。
感谢你们阅读这篇文章,文章中若是有什么问题,你们在下方留言我会及时作出改正。