Web开发

首页 » 常识 » 问答 » 基于WebComponents跨框
TUhjnbcbe - 2020/12/3 15:30:00
过去我们在讨论前端组件化架构的时候,通常是指某个框架限制下的组件化架构,主流组件化框架有React、Angular和Vue。理想的组件库可以自然地用于所有的前端框架,而传统的组件库是技术栈强耦合的,在面临技术栈升级或变更的时候,往往需要进行大面积的代码调整和重构,同时需要维护多套组件库。这种环境强耦合的方式会带来重复开发、交互不一致、升级困难等问题。网易严选前端团队从年开始了对跨框架组件开发的实践,以未来组件化趋势WebComponents为桥梁,将组件核心代码与技术栈隔离,支持React和Angular的封装,力求“writeonce,runanywhere”。背景网易严选发展至今,前端技术栈经历了Jquery、NEJ、Angular以及目前的React,每一次的版本升级和技术栈变更都需要持续完善组件库。理想状况下,技术栈升级的过程应该是-,但是由于组件库数量庞大、逻辑复杂,应用项目众多,很难在短时间内完成系统升级。网易严选目前有+B端业务系统,每个系统少则几十个页面,多则数百个页面,且需求量日益增多,实际落地过程中很难挤出足够的排期来完成升级,这就意味着升级是逐步进行地、漫长地。而在这个漫长的过程中,我们需要同时维护多套技术栈下的组件库,必然会带来一些问题:

维护成本高首先,在技术栈发生变更时,需要花大量精力迁移新技术栈的组件库。其次,在快节奏的互联网环境下,业务调整非常快,业务组件的需求变更非常频繁,意味着后续需要不断地在新旧技术栈下开发和维护多个“外壳不同,逻辑相同”的组件,维护成本非常高。

视觉交互不一致新旧技术栈下的技术策略不同,导致采用的基础UI库可能也不同。以网易严选为例,年以前,技术栈是Angular,所维护的基础UI库是自研的Shark,而技术栈转换成React后,采用Antd作为基础UI库。由于Shark和Antd在设计上不完全一致,导致新旧系统整体的视觉和交互会有轻微的差异。

升级困难由于环境强耦合性,后续如果要进行React升级或者使用Vue等其他技术栈,必然又需要经历同样的阵痛,如此往复,耗费大量人力,组件库的稳定性较差,后续升级难度重重。

基于以上痛点,我们希望能探索一套环境无关、便于接入、完全自治的跨框架组件开发模式。

一、技术选型跨框架组件(CrossFrameworkComponent(CFC))是一种支持各种框架的基于单个通用模块的有效结构。

我们前面说到,不同框架、同一框架不同版本无法共存,导致组件无法跨框架复用,甚至只能固定在框架的某个版本,这与前端未来的模块化发展是相违背的。庆幸的是,W3C于年提出WebComponents的概念,并与年产出v1草案,使浏览器原生支持模块化。Google也一直致力于WebComponents的发展,率先在Chrome完成了浏览器的底层支持。

1WebComponents1.1概念

WebComponents的三驾马车,即Customelements、ShadowDOM和HTMLtemplates。

1)Customelements????允许用户自定义一组JSAPI,完成UI和逻辑行为,这与主流框架中的组件自定义元素的概念是一致的。

2)ShadowDOM????自定义元素将生成一棵与主文档隔离的“影子”DOM树,而ShadowDOM的作用就是将这棵树附加到宿主元素中,保证了元素功能的私有和独立性。

3)HTMLtemplates????提供了template和slot功能,用于自定义元素结构和模板复用。

1.2生态

7年以前,WebComponents的发展是较为缓慢的,毕竟标准的推进需要各大浏览器厂商的支持,过程漫长,各大公司都在观望。到了7年,陆续有公司开始使用WebComponents构建UI库。但是原生的开发方式非常繁琐,有不少团队开始研究WebComponents的开发框架和编译工具?,通过更灵活、便捷的方式开发编译出WebComponents。其中,Svelte团队的Svelte框架,Polymer团队的Lit-html、腾讯的Omi,都取得了不错的效果。

1.3优缺点分析

1)优点

框架0耦合

浏览器原生支持

主流框架支持

未来组件化趋势

2)缺点

兼容性目前原生浏览器中只有Chrome和Firfox提供了全面的支持,IE和Edge等并不友好。庆幸的是,官方polyfill可以提供IE11以及Edge和其他大部分浏览器的支持,这对B端产品来说,已经够了。

数据绑定

状态管理

开发成本  WebComponents目前并没有数据绑定和状态管理,导致我们无法像其他主流框架那样方便地更新视图、使用redux等进行数据状态管理。

至此,我们萌生了一个大胆的想法,是不是可以使用某个主流框架进行组件核心逻辑的开发,以WebComponents作为桥梁,进行其他框架的复用手段?2方案对比网易严选从年开始了对跨框架组件开发方案的调研,通过对比开发效率、基础UI库复用、性能、学习成本等角度对比了以下几种方案,最终结合网易严选现状,以React技术栈为基础开发,转换成WebComponents,最后再封装层进行技术栈耦合,达到“底层一套核心代码,上层支持多套框架”的目的。二、跨框架组件开发方案1架构设计

在CFC架构设计中,网易严选借鉴了许多外部的优秀方案与设计,经过长时间的探索、开发和实践,形成了有严选特色的跨框架组件开发架构体系。

????

整体架构如图,分成5层,从下到上依次是基础库、组件层、桥梁层、封装层、应用层。

基础库底层基础库包括了技术栈、基础UI库以及其他工具库,是上层建设的基石。

组件层组件层,采用React进行组件核心逻辑开发,这里需要可以复用底层基础UI库和其他业务组件库。

桥梁层通过第三方工具Direflow完成React组件到WebComponents的转换,从而实现内部完全自治,统一对外输出形态,上层可以接入任意支持WebComponents的框架中。为了资源复用,我们将源码以UMD的方式打包并上传至CDN,通过懒加载的方式与封装层进行联通。

封装层至此,应用层已经可以直接使用组件了,但是由于在React/Angular/Vue中使用WebComponents时需要处理事件、参数变更等,使用方式较为繁琐。为了减轻组件使用者的负担,我们在封装层进行了统一的源码加载、参数传递、事件处理等中间转换。最终,对外发布的npm包和现有多套组件的使用方式是一致的。

基础包收纳与框架无关,又需要在WebComponents和不同框架之间复用或者对外暴露的文件。

包服务管理用于管理包依赖和加载顺序。

2技术细节2.1Direflow

Direflow是一个将React框架转成WebComponents的第三方工具,目前github的star数在50左右。其背后的技术很简单,利用了WebComponents的生命钩子完成组件的挂载、更新和卸载。

2.2封装层

封装层起到了胶水作用,主要完成以下功能:

1)加载WebComponents及其依赖的源码

2)参数传递

参数初始化

参数变更检测

3)通信

回调函数,在封装层转化成框架的事件传递方式

全局通信,使用Event完成全局事件通知

)base包输出

由于封装层的代码比较固定,我们提供了脚本化配置,通过几行简单的配置,实现一键生成封装层。最后,尽管需要保持封装层和技术栈的统一,在该方案下的升级和重构成本是非常低的。

三、落地问题1转换能力

通过大量落地实践,我们对该方案在React和Angular框架封装后的能力进行分析,最后得出如下结果。可以看到,在参数变更、事件、路由等常规组件能力上,React和Angular都是无损的,而在slot模板能力上,无法在React组件中自定义Angular组件。

目前对于这种场景还无法解决,但是在大部分业务场景里,是可以通过合理的组件设计去规避使用slot,尽可能地用数据驱动视图。2基础包复用

我们在前面提到,Direflow只是一个转换工具,对外输出WebComponents,其底层本质上还是React。因此,在运行时会加载React库和UI库。在落地的时候发现,单个业务包的大小达到1.2M,无法忍受。所以我们加入了资源复用,将React相关套件、UI库以及Direflow剥离出去,通过包加载管理和浏览器缓存以达到复用目的。最后核心业务包部分控制在几十K。

然而,要做的事情远不止这些,我们通过管理命名空间、收敛基础库版本、管理包依赖以及CDN服务的方式缓解了包大小和包冲突的问题。

包冲突管理包命名空间,以隔离影响

版本收敛试想一下,如果我们的一个应用场景里用到的多个组件包底层的React都是来自于不同的版本,虽然不冲突了,但是复用率将大打折扣。另外,多个框架在一个环境会占用大量内存,影响页面性能。所以我们通过管理包服务以及代码检测的方式进行版本收敛,在底层React版本始终加载大版本下的最新小版本,相同环境内的React版本不应该超过2个。

包依赖通过包管理服务管理业务包依赖,在懒加载的时候进行按序加载,保证执行顺序,避免重复加载和冲突。

加快加载速度将所有资源上传到cdn,以加快加载速度。

3样式处理

ShadowDOM天然的隔离性,让css的处理变得稍微复杂。

ShadowDOM内通过style-it插入根节点前。

ShadowDOM外在ShadowDOM外进行DOM操作,eg,全局的toast、modal,已经脱离了ShadowDOM,就需要在全局额外动态加载对应的css,并且要保证对应命名空间的唯一性。

第三方UI样式对于第三方UI样式,比如我们现在用的antd,同样需要进行资源复用,动态加载。

四、开发姿势和使用姿势目前,网易严选已将开发模板集成到cli,通过以下5步,轻松完成一个业务组件的开发。而对于组件使用者的而言,由于封装层已经隔离了内部的复用,并没有额外增加使用者的成本,使用的时候直接以技术栈对应的开发方式即可。五、价值分析

效率提升互联网寒冬时代,各大公司都在强调降本增效,提高生产力才是硬道理。从网易严选目前落地的组件包的代码量上看,人力投入可缩小至60%。

环境隔离由于将框架和版本解耦,真正做到组件自治,未来升级技术栈的时候,也只需要新增对应的封装层即可,做到平滑升级。

交互视觉统一因为只维护了一份代码,组件在不同技术栈下的表现可以保证一致。

六、写在最后最后需要强调的是,跨框架组件开发模式终究是未来组件库的趋势,真正的组件库应该是完全自治、环境隔离、不受框架和版本限制的,网易严选的跨框架组件方案是结合严选场景的具有严选特色的方案。而WebComponents在未来会提供越来越多的特性,值得一试。至于底层是选择React-WebComponents、Angular-WebComponents,还是直接使用Svelte、Omi这样的框架,都需要各团队结合实际情况去调整方案。

综上,本文通过介绍网易严选跨框架组件开发模式的方案设计和落地细节,力求保证组件库的隔离性、一致性和稳定性,希望给大家提供一个新的思路。

??交流讨论欢迎
1
查看完整版本: 基于WebComponents跨框