当前位置: 首页 > Web前端 > vue.js

基于VueSSR的微架构在FOLLOWME5.0实践

时间:2023-03-31 18:49:44 vue.js

2020年5月22日,FOLLOWME5.0第一版终于上线了。这也是公司内部基于Genesis推出的第二个项目。首页是一个老项目,经历了最原始的一种VueSSR。后来年初迁移到Nuxt.js,现在迁移到Genesis。可谓一波三折。第一次实践2019年上半年,我们在与APP的混合开发项目中第一次实践了模块化。它有独立的API、路由、状态和页面,按需初始化,但并不完美,它是一个基于路由的微模块,状态也是按需注入全局状态。无路由微模块管理2019年8月,开始接触web首页的开发。Vuex的状态管理,所有的状态都被注入到全局状态中,并且交集在一起。随着业务的迭代,不再明确哪些是需要的,哪些是可以删掉的。随着业务规模的扩大,维护难度越来越大。为了保证非侵入性,在Tms.js的基础上抽象出一个支持微模块的状态库。这时候我们的微模块就有了独立的API、状态和页面。我们的5.0左侧导航被提取到一个独立运行的微模块中。一个微模块由多个组件组成,它有自己的内部状态管理。2019年底,大跃进得知我们要升级到5.0版本,网站也将进行大改版。基于现有的微模块开发理念,我们希望更进一步,解决一些以往项目架构的弊端。在5.0之前,我们有一个公共导航栏,CSR和SSR项目都需要它。每次更换导航栏,都需要重新打包发布十几个项目,极大地消耗了我们的身心。体力,我希望一个页面可以从不同的SSR服务聚合起来,以API的形式提供给另一个服务。在这个大胆的想法诞生后,我们深入研究了Nuxt.js,希望它能满足我们的需求。经过一番研究,确定不能满足我的需求后,我们最终选择了做轮子。Genesis参考了一些社区SSR框架的实现,基本都是封装好的框架,灵活性不高。我们希望它是一个简单的SSR库,作为工具函数使用,从而支持多实例运行。这里的概念下,它不像Nuxt.jsnuxt.config.js那样直接读取一个配置开始运行,而是为你集成了各种功能。它只是一个基本的渲染工具函数import{SSR}from'@fmfe/genesis-core';constssr=新SSR();常量渲染器=ssr.createRenderer();renderer.render({url:'/'});当然在实际业务中,我们还需要创建一个HTTP服务,将我们的内容返回给用户。如果要实现微服务,并且能够被不同的服务调用,首先需要服务本身具备将渲染结果输出为JSON的能力,然后第三方服务读取渲染结果输出为HTMLrenderer.render({url:'/',mode:'ssr-json'});我们巧妙的使用了Vue的Renderer选项模板,传入一个函数,执行后返回一个JSON渲染结果=strHtml.replace(/^(<[A-z]([A-z]|[0-9])+)/,`$1${this._createRootNodeAttr(ctx)}`);constvueCtx:any=ctx;constresource=vueCtx.getPreloadFiles().map((item):Genesis.RenderContextResource=>{return{file:`${this.ssr.publicPath}${item.file}`,extension:item.extension};});const{数据}=ctx;if(html===''){data.html+=`

`;}else{data.html+=html;}data.script+=vueCtx.renderScripts();数据样式+=vueCtx.renderStyles();data.resource=[...data.resource,...resource];(ctxasany)._subs.forEach((fn:Function)=>fn(ctx));(ctxasany)._subs=[];返回ctx.data;};远程组件考虑到并不是所有的项目都需要远程调用,所以远程调用组件由一个独立的包提供,并得到SSRJSON的渲染结果,最后由远程组件负责我们嵌入到页面中服务。fetch是一个异步回调函数,可以使用axios库向remote-view组件发送请求返回SSR渲染的结果。renderer.render({url:'/',mode:'ssr-json'}).then((r)=>{//写接口提供r.data给remote-view组件访问});5.0服务拆分根据UI的渲染效果,我们将左侧导航和内容区拆分为不同的服务,内容区因为不同的开发团队和业务拆分为不同的服务。在第一个版本中,我们拆分了左侧导航的node-ssr-general服务,首页和通知的node-ssr-home服务,信号的node-ssr-signal服务。每个服务都是独立部署,独立开发,由不同的人维护,最终才由node-ssr-general服务聚合。未来,我们的产品会进一步迭代,越来越多的服务会融入到这个大应用中。内网域名初始SSR服务尝试使用RPC和HTTP获取接口数据进行渲染。后来经过权衡,在5.0中,我们统一采用在服务端配置HOST的方式,配置一个内网域名,通过HTTP请求提供给SSR服务,获取数据服务的加载策略,这样首屏就可以更快的呈现给用户,所以服务器端远程组件使用SSR渲染,而客户端路由切换时使用CSR渲染,所以切换到信号栏中,加载过程中会出现一些明显的白屏过程。未来可以通过ServiceWorker预加载所有服务的静态资源和CSR渲染时的HTML,减少加载服务内容时出现白屏的概率。关于微前端,理论上Genesis也可以同时支持React。输出同样标准的JSON渲染结果,同样标准的应用创建和销毁逻辑。只是我们团队目前主要还是以Vue为主,所以这方面还是需要团队有时间去支持。发射信号模块FOLLOWME5.0新版本攻略体验GenesisGithubGenesis文档vuedemoSSRdemo基于Genesis+TS+Vuex微架构demoMicrofrontendµ-frontendµ-serviceexamplesbasedonVueSSRforGenesisframework文章源地址