美团点评酒旅移动端 Vue.js 最佳实践
Posted 穿背心儿的程序猿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了美团点评酒旅移动端 Vue.js 最佳实践相关的知识,希望对你有一定的参考价值。
作者 | 胡成全
责编 | 唐门教主
移动端html5因其开发效率高、多端适配能力强而为广大开发者所熟知。而企业级的团队开发对技术成熟度、学习成本、开发便捷性以及大规模应用的架构能力有严格的要求。合理的技术选型,一致的开发规范对前端技术团队尤为重要。
美团点评酒旅前端专注于手机和桌面浏览器,因此不必考虑和客户端共享代码。在对比流行的MVVM框架AngularJS、React和Vue.js后,我们认为,实现上轻量、学习曲线平缓、专注在HTML视图层的Vuejs,能够最大限度地契合酒旅的团队需要。
经过前期的快速发展,在完成业务目标的同时,各系统之间的技术选型差异逐渐放大。技术栈不统一带来的开发效率问题日渐突出,系统维护成本显著增加,基础技术建设收效甚微,难以开展。我们面临的问题主要有:
业务线技术栈不统一,AngularJS、Vue.js、jQuery和传统老项目并存,项目切换和维护成本较高;
基础技术建设无法开展,业务和技术组件无法复用,一个技术方案需要多个版本的实现;
团队规模扩大,新人培训和快速切入业务难度大,团队效率下降。
因此,我们需要解决的核心问题是:
统一技术选型,降低团队学习成本;
完善技术生态,技术方案提取和复用,提高开发效率。
多人协作的前端项目,技术选型需要满足并行开发,能做到较好的模块分解、组件复用、数据和状态管理清晰易于维护。同时兼具良好的开发体验,如开发调试、开发工具和项目脚手架。在这些方面,Vue.js的单文件组件开发方案,Vuex的数据和状态管理方案,能很好地契合预期。
经过反复尝试和探索,我们总结出了一整套行之有效的实践经验,包括对Vue.js的使用、业务生态建设、性能优化和工程化的一些建议。下面将分别进行介绍和说明。
Vue.js有多种开发和使用方式,为方便代码维护和作为技术栈统一的延伸,我们约定了一致的编码规范,对常见的使用方式做了一致性约束。
Vue.js使用自定义标签的方式为HTML扩充标签集合,自定义标签需要定义并注册到Vue运行环境。通常的开发方式下,我们简单通过Vue.component注册全局组件就能达到目的,一次注册,到处使用。但对于复杂的场景,其缺点直接导致了代码可维护性的降低,譬如:
全局组件命名问题,组件提供方需要避免组件名称重复;
组件中无法添加CSS,这使得组件的样式必须和组件本身分开管理维护。
为此,我们选择了使用Vue.js官方推荐的组件开发方式Single File Components构建复杂应用。在此开发方式下,组件的所有代码汇总到一个扩展名为.vue的文件中,实现组件间的低耦合。通过官方推荐的自动构架工具vue-loader完成代码的构建。更进一步,对于复用率高的组件,我们后期直接提取到团队自建的npm仓库,对其他业务线直接提供技术支持。
对简单应用,组件间的组织方式比较简单,通过消息通信机制实现彼此状态的更新和同步,应用数据和状态分散存储在各个组件中并没有太大问题。随着业务场景的复杂和功能迭代,状态间的消息变成一个不可维护的网状结构,可维护性急剧下降,直到不可维护。为此,我们对业务级别的应用,根据其复杂程度,确定是否选用Vuex统一维护数据和状态。Vuex的核心规则是通过Vuex.Store创建实例store,并将其挂载到父子组件中。Store由以下几部分组成:
State对象存储原始数据;
Getters函数定义State的获取方式,组件引入Getters获取数据并完成视图渲染;
Mutations定义State中数据的更新方式,并唯一持有对State的更新入口;
Actions作为Mutations的外层包装,对内持有对Mutations的访问权限,对外提供数据更新的入口。
实际开发中,我们在对Vuex的使用方法做了调整,以便于模块化开发,如:
将每个子组件的数据分开定义,每个模块的数据独自保有一个命名空间;
负责更新数据的Mutations指令,约定一致的命名规则,譬如以组件名称作为前缀,做到望文生义;
State、Mutations、Actions在同一个文件中定义,不做单独引入,确保一致的入口和引用方式;
子组件的数据定义Mixin到统一入口文件,并创建Store实例。
这样一来,我们彻底剥离了数据状态管理和核心业务逻辑部分的代码。在组件级别上以最小的侵入实现了数据挂载,组件模块化管理解耦成功。
我们已经实现了开发技术栈的统一,为了提高开发效率,避免重复造轮子,并且对轮子的质量提供统一的质量保证。我们建设了一个Vue.js组件库Vue Gallary,沉淀出业务中的一些交互解决方案和通用业务组件,确定准入规则后发布到自建的npm仓库。
在组件准入规则上,我们构建了组件开发脚手架,约定了组件的开发规范,一键生成项目代码主体结构,帮助开发者更好地开发基础组件。此外,对于所有组件,我们建设了一个组件库平台系统,可以查阅现有组件情况、Demo实例和组件信息、使用方式等。我们会在代码仓库层面统计组件被使用的频率,评估组件的使用情况和带来的开发效率提高。
我们HTML5应用面向多端,如美团App、点评App、大象,在不同的App上视觉规范不一致,如何做到同一套代码的多端视觉适配呢?为此,我们实现了一个多端的样式适配方案Hue。我们对业务的多端视觉规范做了统一收集和汇总,整理出了一套通用样式解决方案,开发者根据自己所处的环境,引用不同的样式文件实现换肤。听起来很简单,但在对子组件的样式适配上会显得比较复杂。通常,组件的样式都是定义在组件内部的,如何让组件也实现换肤,这才是重点。
我们的方式是:样式库是可编码的预处理文件,组件通过npm引入样式库并依赖其中的公共样式部分。在构建目标代码时选择要支持的终端平台,将样式文件提取到一个文件中,根据选择的终端构建出不同版本。这部分样式以页面为维度,一个页面构建出一个样式文件。
此外,我们还开发了Vue.js组件的性能统计工具,可以统计组件在各个生命周期的性能情况,确定性能瓶颈,帮助开发者提高组件性能。
如上所述,我们的代码要运行在不同终端上,终端提供了一些HTML5所不具备的Native API,但不同终端提供的API功能不尽相同,这给业务方带来了抹平终端差异的成本。为此,我们为了提高开发效率,实现了一个Super Bridge的解决方案,对开发者屏蔽了实现差异,其核心内容主要包含:
顶层业务接口封装,用户直接操作这部分接口;
检查当前终端环境,动态载入当前终端的特定JS Bridge实现;
对尚未开放的API,实现HTML5版本提供服务。
前端离线化:移动端对网络要求较高,页面加载问题比传统PC端更加突出。为增强用户体验,减少前端加载时间是一个必要的技术手段。目前我们已经实现了一套纯前端、增量式的代码离线化方案。该方案通过浏览器本地存储特性、增量式的代码构建策略,以及可配置的本地存储空间管理实现。目前已经在机票业务上得到实践和验证,加载效率提升了50%。
客户端离线化:对于Hybrid开发方式,我们借助客户端的能力,实现了一套客户端静态资源离线方案。该方案通过消息推送、URL拦截、资源预加载的方式,打破纯前端离线化的技术限制,实现更多的离线策略和配置。此方案已经在多个业务实践和验证,目前正在做方案的升级和改进,以期满足更多业务场景。
构建策略:我们采用了非关键代码的异步载入策略,将其分片构建到多个目标文件,以此提升用户可交互时间。
业务场景:性能优化是一个永恒的议题,常见的方法有迹可循。部分优化方案需要分析业务场景,或者走查代码逻辑才能得出结论。譬如我们主流程有四个页面,每个页面都会尝试写入Cookie,但分析业务之后发现绝大多数情况只需要在第一个页面写入即可。其他页面的策略可以调整为——如果获取不到再尝试写入。整个链路节约的时间就相当可观。
我们采用E6语法进行业务开发,一方面实现源代码级别的精炼,一方面与主流的技术趋势保持对齐。通过制定团队内的代码编码规范,梳理出ESLint代码检查规则,并在代码提交阶段做代码检查。
数据Mock:为完成前端代码;
包管理策略:npm策略升级为Yarn,之前我们有发生过依赖的包版本不一致导致的线上问题;
开发脚手架:我们自建了一套前端开发脚手架AWP,通过其初始化前端项目,完成代码构建,调试和发布。
Vue.js可供使用的框架特性和语法特点非常丰富,但在团队协作中,选择一致的功能集合,保持一致的使用规则非常重要。结合美团酒旅前端团队的使用情况,我们将团队的使用规则总结如下:
业务组件均以单文件的方式编写,禁止注册全局组件而通过Component方式引入子组件;页面尽可能分解为组件,并做好解耦;
数据管理优先使用Vuex,通用组件选择性使用props方式;store的定义可以以组件的维度做好分解,在入口处做好聚合;
尽量不使用消息分发和广播做通信依赖,避免“消息网”带来的维护灾难;
数据绑定优先使用mastache语法,尽量避免生僻指令;
避免使用内部钩子和方法,除非必要;禁止直接操作DOM;
考虑组件按需加载的特性做好分块和打包,加速页面载入。
当前,Vue.js已然成为前端最流行的框架之一,任何级别的改进,对广大的使用群体来说,收益都将是巨大的。本着造福广大用户的初衷,希望Vue.js本身能继续保持高质量的稳步迭代。
我们在使用个过程中曾遇到的最大问题,是从Vue.js 1升级到Vue.js 2引起的大量代码修改和调整。尽管我们对大版本升级带来的改动是有一定预期的,但作为一线用户,总希望有更好的兼容性,或进一步在升级指南上加强引导。
关于文档,中文官方文档更新落后于英文文档,团队中有同学因为中文文档引发过问题。希望Vue.js团队能在这方面做一些引导和提醒,譬如标注好更明确的版本信息,文档更新日期。
关于测试,官方文档的测试部分比较简陋,社区的很多示例项目甚至没有测试,希望官方能够做一些引导和测试准入机制。譬如推荐测试框架,完成一份标准的测试准入示例。
目前,美团点评酒旅前端团队已经实现技术栈的统一,并在此基础上完成了组件库、样式库、开发工具脚手架、静态资源离线化等生态建设,开发效率得到了极大的提高。未来,我们将继续在统一技术栈的背景下完善基础建设,服务好业务团队,包括正在进行的基于Vue.js的企业级框架的开发、基于Vue.js开发规范的微信小程序项目脚手架等。
本文为《程序员》原创文章,未经允许不得转载,更多精彩文章请订阅《程序员》
以上是关于美团点评酒旅移动端 Vue.js 最佳实践的主要内容,如果未能解决你的问题,请参考以下文章