开源React Native组件库beeshell 2.0发布
总第357篇
2019年 第35篇
2018年,我们开源了React Native组件库——beeshell 1.0。时隔一年,我们对React Native组件库继续优化,实现beeshell 2.0升级,开源38个功能。希望更好的服务社区,同时也希望利用社区力量丰富React Native组件库。
引言
背景
UI 风格一致性。在同一个业务中,各个组件要有一致的 UI 风格,保证用户体验、塑造品牌形象。
通用性。可以支持不同的业务方,可以灵活定制不同的业务需求,最大化组件复用率,减少重复开发。
易用性。组件的功能、行为表现符合开发者的直观感受,易于学习和使用、减轻记忆负担;功能丰富,可以支持多种业务场景,支持特定业务场景的多种情况。 稳定性。RN 组件库需要同时支持 iOS、Android、Web 三个平台,组件要在三个平台可用、可靠、稳定。
简而言之,组件库的目标是通用、易用、稳定、灵活。
系统设计
我们的目标是提供一套通用、易用、稳定、灵活的组件。然而,对一个组件来说,如果通用性、灵活性强,则易用性、稳定性势必较差。如何合理的处理这个矛盾呢?
架构升级
图F
beeshell 2.0 与 1.0 的架构在整体上保持一致,共分成四层:业务层、组件库(体系)、RN 层、系统层。而 beeshell 2.0 的架构升级,则主要体现在第二层与第三层。
MTD 的关注点是通用性、灵活性,所以提供的是基础、通用的组件。组件的扩展能力极强,可以满足多个业务方的定制化需求。
Roo 是对 MTD 的继承与扩展,定制了外卖业务的 UI 风格与功能,通用性减弱,功能性和业务性增强,关注易用性、业务性、一致性。
beeshell(准确说是 2.0 版本)是对 Roo 的继承与扩展,与 Roo 相比,去除了过于业务化的组件与功能,纳入并整合社区的需求,关注通用性、易用性、稳定性。
组件库体系的三个版本,内部的架构设计一致,本文只详细介绍 beeshell 开源版本。
接口层。汇总所有组件,统一输出,使用全部引入的方式,方便组件使用。另外,为了避免引入过多无用组件,引起资源包过大,也支持组件的按需引入。
组件层。细分为原子、分子、扩展组件。
与 beeshell 1.0 相比,我们对组件在更细的粒度上进行拆分。同时,层次划分也更加精细、明确。如上图 F 所示:基础组件细分为分子、原子组件。这样,组件的继承、组合方式更加灵活,能够最大化代码复用。而且,原子、分子、扩展组件,各层次组件各司其职,“关注度分离”,兼顾通用性和易用性。工具层。与 beeshell 1.0 相比,工具更加完备。不但新增了树形结构处理器、校验器等;而且工具的独立性更强,与组件完全解耦,与组件配合实现功能。
这样,一方面,使得组件实现更加简洁,提升了组件的可维护性;另一方面,可以将工具提供给用户,方便用户开发,提升组件库的功能性、易用性。而且,工具与组件的解耦遵循“关注度分离”的原则。三端适配。RN 在整体上实现了跨平台,iOS、Android、Web 三端使用一套代码,但是在一些细节方面,例如:特殊 API 的支持、相对位置计算等,各个平台有较大差异。为了更好的支持三端,保证跨平台稳定性,还需要在这一层做很多适配工作。
第三层:RN 层
MRN 是基于开源的 RN 框架改造并完善而成的一套动态化方案。MRN 从三个方面弥补 RN 的不足:
动态化能力。RN 本身不支持热更新,MRN 借助公司内发布平台,实现包的上传发布、下载更新、下线回滚等操作。 双端(未来三端)复用问题。从设计原则上保证开发者对平台的差异无明显感知。 保障措施。在开发保障方面:提供脚手架工具、模版工程、开发文档等,方便开发者日常的 MRN 开发工作。提供多级分包机制,业务内部和业务之间能够灵活组织代码;在运行保障方面,提供运行环境隔离,使得不同业务之间页面运行无干扰。提供数据采集和指标大盘,及时发现运行中的问题,同时提供降级能力以应对紧急情况。
协作模式
图X
结构方面:MTD 包含 beeshell 1.0 的全部内容,并进行了组件数量的扩充、组件功能的增强;Roo 包含 MTD,进行了定制与业务扩展;beeshell 2.0 与 Roo 基本一致,去除业务部分,纳入社区需求。
首先,我们在 beeshell 1.0 的开发以及开源中,积累了丰富的经验。在建设 MTD 公司通用版组件库时,贡献了 50% 的组件;同时,贡献了许多设计模式与思路,大大加速了组件库的建设。
其次,在 MTD 建设完成后,为了更加方便、快速的接入外卖的相关业务,以 MTD 为基础,定制了外卖主题的组件库 Roo,提升了组件库的业务功能性和易用性。外卖相关的业务项目,在接入 Roo 后直接使用,无需再进行主题的定制与调整,在一定程度上节省开发成本。
第三,我们将共建的成果贡献出来,以 Roo 为基础,升级 beeshell 2.0 并开源。将部分过于业务化的组件移除,纳入了社区的相关需求,保证组件库的通用性、易用性与稳定性。
最后,对于公司内部,各个业务方可以以 MTD 为基础进行扩展,定制自己的业务主题组件库(Roo 就是第一个业务扩展);对于社区,各个开发者可以根据实际的业务需求,以 beeshell 为基础,定制扩展组件库。
综上所述,我们以 beeshell 开发团队为桥梁,建立了美团公司与开源社区之间进行技术交流的通道,美团公司、beeshell 团队以及社区,可以在技术上互帮互助,共同建设、进步。
方案实现
UI 风格一致性
Roo Theme 向上实现了 UI 规范具体内容,将设计规范统一收敛,向下输出主题变量、组件样式类、通用样式工具等,供各个组件库以及业务方使用。
样式一致性。通过继承、扩展 Roo Theme,定义全局性的主题变量,用于组件的样式部分定义。主题变量范围涉及品牌色、灰度、字体尺寸、间距以及组件级变量,为组件以及组件之间样式一致性,提供了全面的保障。同时,组件库提供了自定义主题变量的接口,可以重置相关变量的值,对 UI 风格进行一致性调整,实现一键换肤。另外,使用“内部样式 < 主题 < 扩展样式”的样式优先级覆盖策略,保证了样式部分的定制能力(在下文“定制化能力分级设计”章节中详细介绍)。
动效一致性。一方面,依赖主题变量中定义的动画开关变量(主要考虑到一些低端 Android 机器的性能问题),用户可以关闭某个组件的动画;另一方面,依赖组件库的良好分层设计,我们将动画类独立实现,这样可以使用策略模式,将动画方便的集成到任意组件中。
下文详细介绍样式一致性和动效一致性。
样式一致性
通常,一个产品的 UI 只会有一个品牌主色。然而,像 beeshell 这种品牌主色色值较浅的情况,一个品牌主色并不能够支撑所有的应用场景。此时,可以通过加深主色的方式,再增加几个色值,beeshell 的品牌主色还包括一个加深的色值 #ffa000,用于某些组件的激活状态,如下图所示:
对于品牌主色的个数,需要根据色值的情况而定,不必过于拘泥规则,只要能有一致性的用户体验即可。
图U
这四个色值,分别用于一般信息、成功、警告、失败这四种业务场景,以及从这四种业务场景所衍生出的场景。在一定程度上,保证色彩的一致性。
图B
这样的排版比例,可以使得界面的文字内容更加协调、流畅,进而提升了排版的一致性。
图L
beeshell 使用了默认的字体行高,在一定程度保证了可读性和排版的一致性。
图S
边线
动效一致性
引导用户在视图中的视觉焦点。
提示用户完成手势操作后会发生什么。
暗示元素间的等级和空间关系。
让用户忽视系统背后发生的事情(比如抓取内容、或加载下一个视图)。
使应用更有个性、更优雅、体验更加一致。
beeshell 组件库基于 Animated 进行了二次封装,提供 FadeAnimated 和 SlideAnimated 两个动画类,支持淡入淡出动画和滑动动画,可以使用策略模式集成到任何组件中。
Modal 组件使用 FadeAnimated 类实现动画,动效如下图所示:
Dropdown 组件使用 SlideAnimated 类实现动画,动效如下图所示:
定制化能力分级设计
如上图所示:第一个例子比较通用、规范。“区域文字内容”的文案与样式需要支持自定义;第二个例子,需要支持多行文字以及图标,即“区域内容”需要支持自定义;第三个例子,自定义的重点,由区域以及区域内部,转移到区域之间的布局,“区域布局”需要支持自定义。
第一级定制化:定制主题变量
第二级定制化:提供定制属性
代码实现为:
<Text style={this.props.labelTextStyle}>{this.props.labelText || '完成'}</Text>
LabelText 用于定制文案内容,将 LabelTextStyle 整体暴露出来,而不是只暴露颜色单个属性,这样有两点好处:
开发者都熟悉 Style 这个名称与用法,但并不知道 xxxColor 是什么,组件更加易用。
Style 不仅可以定制 Color,还支持 fontSize、fontWeight 等属性,定制能力更强。
以上两级主要是样式部分的定制,使用了样式优先级覆盖的策略,扩展样式(labelTextStyle)覆盖主题,主题覆盖内部样式。
到这里,区域以及区域内部的定制化需求,就都可以满足了。但是区域布局的定制化,因为布局情况太多,并不容易实现。如果再提供几个属性,用于定制布局方式、头部边框样式、底部按钮,按照这种方式,属性会无节制增加,势必造成组件难以维护,易用性也会大打折扣。那应该如何实现?我们设计了第四级。
第四级定制化:继承/组合基类
然后,组件库实现了 BottomModal 组件,继承 SlideModal,固定滑动的方向和开始位置,弹框内容横向拉伸至全屏、纵向自适应,功能增强而定制化能力减弱。实现效果如下:
第四级定制化,是使用了新的思路,不再盲目的增加一个组件的功能,来帮助开发者满足产品需求,而是提供了基础工具。基础工具实现了底层、复杂的部分,表现层的部分则让渡给开发者,用户自己实现,“授人以鱼不如授人以渔”。
功能丰富
组件丰富度
虽然,beeshell 的组件数量还比不上 Antd Mobile RN(用不了多久也会超过),但已经超过 NativeBase 和 React Native Element。beeshell在组件数量上有很大优势,可以支持更多的业务场景,且支持全部引入和按需引入,用户无需担心打包过多无用代码的问题。
功能丰富度
功能丰富度针对的是单个组件所支持的功能,旨在覆盖特定业务场景的多种情况。
图O
对于一个组件的功能丰富度,我们通过多方式收集、功能综合分析、UI 模型抽象、技术实现、验证反馈几个步骤来保证。
多方式收集。通过多种方式来收集组件功能,收集方式包括:组件既有功能、业务新需求、标杆项目特性。
功能综合分析。对收集的功能进行全面、综合分析与考虑,得出组件需要支持的功能特性。
UI 模型抽象。对组件功能进行抽象设计,根据 UI 模型,明确抽象设计的合理性和有效性。
技术实现。根据平台特性、技术选型来完成代码实现。
验证反馈。组件实现后,会应用到业务或者示例工程来验证,如果组件并不能满足需求,需要重复执行以上几步。
下文以 SlideModal 组件的实现,举例说明:
其次,综合分析得出,SlideModal 组件需要支持的功能有:弹出位置自定义、滑动方向自定义、全屏/半屏自定义。
由 UI 模型得出,SlideModal 组件通过 (offsetX, offsetY) 坐标值来定义弹出位置;为了支持全屏/半屏效果,将屏幕分割为 4 个区域,分别自定义触控效果(阻断点击或者击穿);弹框内容在一个区域展示,每个区域有 3 种滑动方向(图 N-2),共支持 12 种滑动动效。
对比业界开源 RN 组件库,针对滑动弹框场景,没有几个可以超过 SlideModal 的业务支持能力。
易用性提升
命名
组件名称。
组件描述。
引入方式,包括全部、按需两种引入方式。
示例演示,动图与静图。
示例代码,使用伪代码,言简意赅,能说明使用方式即可,同时,附有完整示例代码的链接。
API 说明,分成 Props 和 Methods 两部分。
Props 包含 Name | Type | Required | Default | Description。 Methods 格式借鉴 RN 官方文档格式。
示例
测试
不仅如此,beeshell 2.0 在测试领域继续探索,集成了“灰盒测试”(基于开源方案 Detox 实现)。
灰盒测试,是介于白盒测试与黑盒测试之间的一种测试,灰盒测试多用于集成测试阶段,不仅关注输出、输入的正确性,同时也关注程序内部的情况。灰盒测试不像白盒那样详细、完整,但又比黑盒测试更关注程序的内部逻辑,常常是通过一些表征性的现象、事件、标志来判断内部的运行状态。
通过黑盒测试、白盒测试、灰盒测试,三种测试方案,更加全面的保证组件库的代码质量,大大提高了代码可维护性。
开发调试
未来规划
第一阶段,beeshell 1.0 版本,开源 20+ 组件,主要提供基础功能。
第二阶段,对我们在开发 React Native 应用几年时间积累的组件进行整理,同时参考业界的标杆项目,开源 50+ 组件。
第三阶段,调研移动端 APP 常用的功能与场景,分析与整理,然后在 beeshell 中实现,开源 100+ 组件。
此次 beeshell 2.0 升级,共计开源 38 个功能,而且已经详细的规划了另外的 15+ 组件,也会在近期开源,目前处于第二阶段的收尾阶段。
开源相关
Github 地址:beeshell
核心贡献者
参考资料
团队介绍
在用户方向上,构建了全链路的高可用体系,客户端、Web前端和小程序等多终端的可用性在99%左右;跨多端高复用的局部动态化框架在首页、广告、营销等核心路径的落地,提升了30%的研发效率;
在商家方向上,从提高进程优先级、VoIP Push拉活、doze等方面进行保活定制,并提供了Shark、短链和Push等多条触达通道,订单到达率提升至98%以上; 在运营方向上,通过标准化研发流程、建设组件库和Node服务以及前端应用的管理与页面配置等提升10%的研发效率。
招聘信息
外卖事业部终端团队是由一群活力四射,对技术饱含热情,平均年龄不超过26岁的人共同组成。在这里,你可以看到大家对技术的追求,对产品的雕琢,对团队的认同,一切都是那么自然;在这里,你可以做一个纯粹的FE,写写JS,打磨一下CSS;也可以做一个精致的猪猪女孩(男孩),优雅的调试 Android 和 iOS 代码。当然,你绝对可以做一个霸道总裁,肆意的拥抱跨端方案,Hybrid,Flutter,React Native 等,都是你的新战场。我们正在持续努力成为一个面向未来编程的团队,而这里还缺一个你。欢迎志同道合的同学发送简历到:tech@meituan.com(邮件标题注明:外卖事业部终端团队)。
React Native工程中TSLint静态检查工具的探索之路