首页 体育 教育 财经 社会 娱乐 军事 国内 科技 互联网 房产 国际 女人 汽车 游戏

Bifrost微前端框架及其在美团闪购中的实践

2020-01-13

Bifrost本意彩虹桥,北欧神话中是连通六合的一条通道。而在漫威电影《雷神》中,Bifrost是神域——阿斯加德的出进口,神域的人经过它自在络绎于“九界”之间。借用“彩虹桥”的涵义,咱们期望Bifrost能够成为前端不同SPA系统之间的桥梁,使得不同的单页运用能够用这种办法完结功用的自在聚合/拆分。

立项之初,闪购赋能企管渠道仅仅是面向单个商家的CRM办理系统,选用惯例的Vue单页运用办法来完结。跟着项意图推动,它的定位逐步发作了改变,从一个单一事务的载体逐步变成了面向多种场景的商家办理渠道。另一方面,由于系统由多个前端团队一起开发保护,越来越多的问题随之显现:

因而,咱们期望构建一个更高维度的解耦计划,使咱们能够在开发阶段把互不干涉的模块拆成一个个相似后端微服务架构那样的子系统,各自迭代,在工作时集成为一个能够掩盖上述各种运用场景的完好系统。

首要,咱们收拾了中心诉求,按优先级排序如下:

依据以上这些诉求,咱们调研了现在市面上常用的微前端计划,最常见的计划有:

除此之外,还有美团集团内部的微前端实践——美团HR系统和业界比较闻名的微前端结构——SingleSPA。

这些计划的好坏收拾如下:

从用户体会视点动身,Nginx和Iframe首要被否决;HR系统的计划需求对现有的项目进行改造,把不同团队现在开发的项目整合到同一个单页运用中,在项目快速迭代的进程中,本钱过高,所以也被否掉。SingleSPA看起来完美,但它没有照顾到实践出产环境中的开发、布置的差异性,并不是Product-Ready。归纳多种要素考虑,咱们终究决议选用自研的办法来完结微前端化Bifrost。

Bifrost结构在规划的时分参阅了SingleSPA的思路,将系统了分为主系统和子系统。

主系统是用来操控子系统的调度中心,责任包含:

子系统只担任事务逻辑的完结。假如进一步细分的话,子系统能够分为事务子系统、完结公共菜单子系统、导航布局子系统,其间布局子系统会先于事务子系统加载。

Bifrost选用路由音讯分发的办法来操控子系统的加载和跳转。主系统保护了一条路由音讯总线,当路由发作改变时,子系统会将路由事情推送给路由总线,然后由路由总线决议加载/跳转的方针子系统。假如路由不需求切换子系统,则交由当时子系统进行处理。

假如子系统发作切换,主系统会在DOM中增加对应子系统的挂载节点,并异步加载系统的静态资源。由于子系统都是完好的Vue实例,当子系统的代码加载并履行之后,子系统就会主动在其对应的挂载节点上烘托相应的内容。

整个系统的生命周期如下图所示:

依据Bifrost完结的项目架构如下图所示:

这儿,咱们首要重视主系统、事务子系统和布局子系统的完结。

主系统的逻辑比较简略,首要是实例化Bifrost中界说的Platform目标,并注册各个子系统。子系统的注册信息包含:

一个简略的主系统完结如下:

import { Platform } from '@sfe/bifrost'
new Platform {
 // render layout
 appRegister: [
 { appName: 'app1', configPath: '/path/to/app1/config.js' }
}).start

在规划计划时,咱们始终保持一个理念,便是确保对事务代码的零侵入,因而事务系统改造的工作量很小。代码层面,只需求把本来子系统的初始化流程放到AppContainer目标的Mounted回调函数里即可:

import { AppContainer } from '@sfe/bifrost'
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use
const router = new VueRouter
new AppContainer {
 return new Vue.$mount
}).start

别的,还需求修正子系统的构建流程,构建完结之后生成一个包含子系统进口资源信息的配置文件。一个典型的配置文件如下:

 = callback)

此处咱们完结了@sfe/bifrost-config-plugin插件,在Webpack构建脚本中引进该插件就能够主动生成项目对应的配置文件。配置文件是一个当即履行函数,主系统能够经过JSONP的办法读取配置文件中的内容。

在实践出产环境中,咱们能够将子系统发布到恣意CDN,只需能够确保配置文件的URL始终不变,那么无需依靠任何服务,主系统就能够感知到子系统的发布。

布局子系统是用来完结菜单和导航栏的Vue工程,本质上和一般的事务子系统没有差异。只需求注意,布局子系统运用的是LayoutContainer而非AppContainer进行包装。

import { LayoutContainer } from '@sfe/bifrost'
import Vue from 'vue'
import App from './app'
new LayoutContainer {
 Vue.config.productionTip = false
 const app = new Vue = 
}).start

布局子系统作为主系统的一部分,既能够放在主系统中去完结,也能够像其他子系统相同经过异步的办法去加载。在咱们的项目中,结合了上面两种办法,每次发布时,会一同发布布局的静态资源和NPM包。主系统经过NPM包的办法引进布局子系统,将它打包到项目中,防止线上工作时,额定加载布局子系统的资源,减小项目体积,加速烘托速度。

本地开发时,咱们则会经过Bifrost界说的MockPlatform异步加载布局子系统的静态资源,确保线上/线下工作作用的一起性,便当本地联调。

代码层面的改动尽管不多,但要在实践的出产环境中落地,还需求处理一系列陈词滥调的问题,包含:

依据闪购事务实践,咱们总结了一套适用于Bifrost的处理计划。

选用微前端的办法意味着子系统的彻底阻隔,这给咱们的开发带来了一系列困扰:

为了处理这些问题,Bifrost界说了MockPlatform。MockPlatform的思路很简略:已然主系统能够动态加载线上的子系统,那么咱们只需求在开发时,模仿主系统的工作办法,去加载其他子系统的线上资源,之后就能够像调用后端API相同同各个子系统进行联调了。这也就解说了为什么布局子系统在输出NPM包的一同还保护了一份静态资源。

MockPlatform的API同Platform目标的API是一起的,开发时,咱们只需求依照主系统的办法引证布局或事务子系统的配置文件URL即可:

// ...others...
new AppContainer.start

凭借MockPlatform,咱们项目在开发阶段的感触和开发一般的单页运用没有任何差异,假如某个咱们依靠的子系统更新了功用,只需求让对应的RD发布一下,就能够在本地看到它的最新作用。

除了本地联调,大局通讯也是微前端项目中绕不开的一个论题。由于咱们一切项目选用的都是Vue技能栈,所以会挑选依据Vuex来完结大局通讯。Bifrost的主系统会保护一个大局的Vuex Store,用于保存大局状况。

当子系统期望监听大局状况时,子系统并不是直接订阅大局Store,而是凭借Bifrost供给的syncGlobalStore函数来订阅大局Store。调用该函数后,任何大局状况的改变都会被同步到本地Store的Global命名空间下。之后,就能够像一般的单页运用那样,调用Vuex的mapState办法完结和大局状况的双向绑定。

import { AppContainer, syncGlobalStore } from '@sfe/bifrost'
import Vue from 'vue'
import Vuex from 'vuex'
// ...others...
Vue.use
const store = new Vuex.Store
new AppContainer {
 // 同步大局store状况
 syncGlobalStore
 // ...others...
 return new Vue.$mount
}).start

假如子系统本身的状况需求同享,Bifrost还会供给installGlobalModule函数。该函数会将当时子系统需求同享的状况挂载到大局Store下,其他子系统能够经过前面说到的办法来同步这些状况。尽管Bifrost供给了子系统通讯的才能,但在实践拆分子系统时,应该尽量防止这种状况发作。假如两个子系统之间需求频频通讯,那就应该考虑把他们划分到同一个子系统。

由于各个子系统都需求集成到企管渠道,为了确保体会的一起性,咱们都是依据相同的组件库进行开发。简直一切项目都会依靠lodash、Moment等根底库,因而假如不对公共依靠进行办理,项目会加载许多冗余代码。

针对这个问题,咱们选用的是Webpack External办法来处理。构建时,各个子系统会将公共依靠扫除,主系统会打包一份包含一切这些公共依靠的DLL文件。子系统在工作时,直接从大局引证对应的依靠。假如子系统期望运用某些库的特定版别,也能够挑选不扫除这些依靠项。这在子系统期望晋级某些依靠库的时分显得极为有用:经过子系统的部分晋级,能够约束依靠库晋级的影响规模,防止形成大局影响。

DLL文件会包含大部分公共依靠,但有一个破例——咱们不会将Vue打到DLL文件中。由于在实践开发中,许多库都喜爱向Vue的原型链上挂载办法和特点。假如不同团队开发时挂载的内容刚好用到同一个字段,就会带来不行预知的影响。

除了底层的依靠,咱们还需求考虑对公共的事务模块和东西函数进行复用。在企管渠道,咱们为公共事务组件库和公共函数库创立独立的Git工程,然后将一切的子系统和公共模块经过Git Submodule的办法引进到主系统的工程中。主系统选用Lerna的办法安排代码,各个子系统在开发时,能够经过软链直接引证到本地公共模块的代码,完结公共模块的复用。当公共模块发作更新,直接调用Lerna Publish就能够一同更新一切子系统package.json中依靠版别。

前面说到,主系统选用的是JSONP办法加载子系统的配置文件,整个发布进程都只需求发布静态资源,因而,Talos供给的前端静态资源发布的才能就能够满意咱们的需求。每次发布时,只需求构建有更新的项目,并将打包后的静态资源上传到CDN即可。

选用微前端架构还有一个额定的优点:在Nginx和实践的事务层之间,多了一层主系统,咱们能够像客户端相同,动态决议需求加载的子系统版别。依据此,咱们完结了子系统的版别操控和定向灰度功用。发布时,咱们经过参数确认本次发布是否是灰度版别。在发布成功后,会记载本次发布的灰度信息、版别和配置文件URL等信息。

主系统每次启动时,首要会调用接口确认当时用户所在的链路,再依据链路信息加载相应的子系统。咱们记载了每次发布的资源URL,所以也支撑子系统的版别切换。只需求在版别服务中修正各条链路上需求激活的子系统版别,就能够轻松完结子系统版别切换。

这儿咱们首要评论Bifrost结构的埋点计划。在Bifrost项目中,能够凭借主系统供给的一系列钩子函数完结针对子系统的埋点,包含:onAppLoading、onAppLoaded、onAppRouting、onError。每逢子系统发作切换都会调用onAppRouting函数,因而咱们能够在这儿记载子系统加载的次数。onAppLoading和onAppLoaded则会在子系统初度加载时调用,经过核算Loading和Loaded成功率的比值,咱们能够得到子系统加载的成功率。子系统加载失利时,会调用onError函数,协助排查子系统加载失利的原因。

今年年初,咱们对企管渠道进行了微前端改造,现在系统已经在线上平稳工作半年时刻,支撑上百个零售产品牌,上千家门店事务的工作。

选用微前端架构,给咱们项目带来的优点是清楚明了的:

当然,同一切的架构计划相同,微前端这种形式也存在一些折衷和退让。在取得低耦合和灵活性的一同,也引进了额定的杂乱度。在微前端项目中,咱们需求考虑多个工程的标准和代码质量的一致,需求引进更多的主动化东西来办理项意图发布布置流程,还需求处理多个前端工程工作在同一个域名下引起的Cookie掩盖等问题。

因而,在选用微前端架构之前,主张咱们要慎重的评价自己的项目是否真的合适选用微前端的办法,防止盲目引进微前端导致项目难以保护,因小失大。

咱们以为,假如项目中存在以下两个场景,比较合适选用微前端架构:

其他大部分项目都能够经过调整代码结构,构建单页运用,乃至选用最传统的多页运用等办法来进行优化、调整,历来到达下降耦合的意图。微前端并不是“银弹”。

从上一年12月立项至今,Bifrost阅历了近一年的迭代,发布了2个大版别和38个小版别。诞生之初,Bifrost仅仅是针对企管渠道这个特定事务场景的微前端计划。现在,已进化为面向Vue技能栈的通用微前端结构。期间,咱们环绕Bifrost,逐步完善了整个微前端技能系统的建造,完结了Bifrost主/子系统的脚手架工程和命令行东西、子系统的办理渠道、灰度发布功用等一系列渠道和东西,完结了Bifrost微前端生态的雏形。

当然,Bifrost仍然还有许多能够提高的当地。未来,咱们将会从以下几个方面进一步完善Bifrost:

跟着前端工程的日益杂乱,咱们对可扩展的前端架构的诉求也变得愈加激烈。微前端作为一种前端解藕的计划,天然愈加频频地被咱们所提及和运用。另一方面,尽管网上已经有了许多关于微前端的评论,但仍然缺少真实落地到出产环境的事例。因而,咱们期望经过对闪购团队近半年在微前端计划上的实践同享,协助咱们对微前端从概念到运用有一个愈加明晰的知道,也等待与咱们一同沟通,碰撞出更多的火花。

雨甫,美团闪购前端研制工程师。

美团闪购是美团点评旗下的零售到家事务,闪购专心于为顾客供给丰厚、快捷的零售品类挑选和及时配送服务,为零售商家供给线上、线下的全体处理计划,助力商家提高运营功率。

用户经过手机下单即可快速买到周边各类商家供给的丰厚产品,包括食材生鲜、超市便当、鲜花绿植、母婴用品和健康护理等很多品类。美团闪购与美团外卖同享配送网络,均匀30分钟配送上门,24小时无间断配送,打造全品类一站式零售到家渠道。

美团闪购前端团队诚招高档前端开发、前端开发专家。欢迎各位大佬的参加,一起打造极致的LBS电商体会。感兴趣同学可投递简历至:tech@meituan.com

热门文章

随机推荐

推荐文章