写点什么

已配置 4000+ 页面,携程前端组件化探索之“乐高”运营系统

  • 2019-10-22
  • 本文字数:5311 字

    阅读完需:约 17 分钟

已配置4000+页面,携程前端组件化探索之“乐高”运营系统

一、前言

市场部活动组主要负责各种运营活动的相关开发,分为常规运营活动和定制运营活动。常规运营活动因为组件(模块)具有复用性,并且配置化需求非常多,因此我们建设了一个可视化页面搭建平台——乐高(legao)活动平台。乐高平台将活动页面拆分为各种组件模块,运营人员通过自主的配置就能快速上线各种运营页面


组件承载页面交互和业务。最近的携程 20 周年系列营销活动涉及营销页面近百张,如果都是人工开发,要花费大量人力,几乎不可能完成。


里面包含了各种业务定制组件(能量入口,大牌订阅模块,定制逻辑导航等),各种“乐高”组件(大促,产品,抽奖,多 banner,机票 es 等等),各种新开发“乐高”组件(秒杀,售卖,对接基础瀑布流 sdk 等),各种新定制 snippets 组件等,正是因为能分别开发这些能配置在“乐高”上的组件,才能在有限的开发资源下保证这么多的页面和配置需求能快速保质的上线,更重要的是能够持续配置运营。


因而建设平台的重点之一就是建设组件,在这个过程中,我们针对“乐高”的组件(模块)做了一些探索。


首先是如何丰富组件库。组件库的不断丰富(尤其是包含业务逻辑的组件模块)是为了满足运营方更多且更加灵活的配置需求。我们除了开发产品推出的组件外,从开发的角度推出了更多增强页面配置功能的组件,另外通过协同 BU 开发同学定制业务组件,也期望能够建设一种面向更多运营人员的“业务模块”中台性质的平台,从而使得更多组件能够配合使用。


其次是如何充分利用平台的组件。“乐高”组件的重心业务模块都有完整的业务流程做支撑,如大转盘抽奖,组件 UI 和业务逻辑这些有较大的复用价值。于是我们希望组件开发完不仅仅只能留在乐高系统使用,还能给其他框架无关的非“乐高”页面使用,不仅是我们自己的定制运营活动,还有其他 BU 的活动页面,从而节省公司更多的开发成本。


本文将会从前端角度就“乐高”组件归纳方式,组件技术栈,以及组件复用等分享一些经验。

二、“乐高”介绍

携程“乐高(legao)”系统是市场部活动组开发的运营平台,致力于提供成熟、可靠、快捷的运营系统,期望能够满足各种常规的,自动化的,快速的运营需求。



目前市场部常规运营活动能够通过组件组合的方式快速配置生成 H5 页面,平台支持多种方式的领券活动,抽奖活动,产品展示等以及多个裂变类活动(投票,拼团等)的运营配置。


到目前为止已经有超过 4000+的页面在乐高上配置,组件(模块)库也增加到了 100+(BU 定制模块 30+),极大的缓解了公司的运营需求压力。



乐高前端结构图(目前):



乐高组件配置部分负责配置组件原子属性,以及运营基于各个组件配置的所有渲染属性值。渲染引擎部分则负责渲染。


渲染引擎目前是基于 JAVA 模板的空壳站点,通过唯一标识-页面英文名识别页面,获取页面所需的所有配置属性,并通过 JAVA 在服务端直出页面以及所有配置信息(基于公司内部框架 NFES 改造后将走 node 直出)。


从前端来看,乐高是组件化(模块化)构建页面的实践,也有一些组件“中台”的性质:


1)乐高平台自身收集各种可配置组件或者模块,是组件的集合。


2)乐高组件能够和其他定制活动项目的组件(模块)互用。


例如:为了“聚优惠”活动开发的瀑布流式产品聚合,在这个活动中定制了 2 列的布局,属于瀑布流式,在改成配置化(组件化)之后能聚合更多的产品类型,能配置更多的布局(如,一行一列,图文混排,图片上三列下两列等),这就成了乐高的一个通用的产品聚合组件。类似的还有签到组件,售卖组件等等。


3)协同其他 BU 开发的各种定制模块,使得组件(模块)共用。



乐高平台的用户增多,有一些部门(BU)需要根据自己的业务定制一些业务模块,例如机票的爆款模块,国际专车的产品模块等等,这样一些业务组件不具有通用性,但是为了满足各个 BU 的需求,又需要去定制开发,于是我们开放了乐高组件的开发和配置,提供了乐高组件的开发文档,打包工具和框架说明,鼓励 BU 开发人员自主开发定制组件,当然更鼓励开发同学更多的开发通用组件。


BU 同学专注于组件自身的逻辑,完成需求,还能节省开发时间,做到开发一次,多次使用。这样就能慢慢形成大家一同开发和维护组件,大家一起用的情景。

三、乐高组件(模块)的划分思路

建设乐高平台无疑也是一个摸索的过程,乐高的组件是在实际活动项目中一个一个总结抽象出来的,都具有实际运营配置意义(价值)。


乐高现在有较多的组件了,但是初始阶段组件库是 0,肯定是以组件的扩展,尽量满足运营同学的各种配置需求为目的,因此对于组件的扩展比较重视,组件的开发不仅依靠产品经理的规划,还有很大一部分是基于开发自己对于组件的理解,主动开发。目前组件的类型总体为如下几个类型:

3.1 业务组件

这一大类是我们根据业务需求定制的业务组件,这一类是乐高的核心组件,主要支撑各种运营活动。在特殊活动中,我们也会采用乐高现有组件搭配定制活动业务组件的形式,不仅丰富活动的形式,还能节省大量开发时间。


特点:UI 可配置,业务逻辑完整。在乐高都要有完整的后台流程,数据结构。


3.2 通用 web 组件

除了这些包含业务流程的模块,配置页面肯定少不了交互类静态组件,这一部分开发同学会结合实际,在开发其他定制需求的时候充分考虑组件化需求,尽量把定制需求都归纳为可配置化,可复用的组件,在这个过程中扩展了可配置的静态 web 组件库,如视频组件,轮播组件,多 banner 组件等等。根据实际需求抽象和设计组件,丰富页面交互和展示。


特点:负责交互和展示,属于静态组件。


3.3 活动级模块

运营类还有一些较大的活动如助力拼团,投票活动等也会根据实际情况基于乐高组件化,使得这种组件的一些主要模块成为组件,最终能通过运营自主的配置生成一整个活动流程的各种页面。


特点:组件附带其他业务流程页面,能够直接配置出整个活动,同时也能结合其他模块一起拼装页面。


3.4 其他(特殊类)

  • 定位组件拆分


有时候模块并不是独立业务组件的简单配置堆叠,在实际配置中需要有数据通信,交互关联,逻辑自定义等情况。


例如有个特定的业务模块儿包含一个定位所需定位组件,那么定位组件关联的组件可能不止一个业务组件,比如为 A,B,C 组件。



那么如果将定位组件随便耦合在 A,B,C 组件中显然是不行的,而且点击一次定位组件从而触发多个关联的组件的响应在这种情况下显然不容易实现,这样就可以考虑适当拆分组件,并通过发布订阅的方式,让关联的组件订阅定位组件的改变,从而满足配置需求。



  • tab 模块切换


用来控制其他组件(所有类型)是否渲染的”tab 模块切换“组件。配置这种组件 可以控制页面中一批组件的渲染,主要实现方式是通过闭包将组件的渲染动作(渲染函数和组件所需的配置数据)保存起来,并以发布订阅的方式达到控制的目的。


  • 携程 app 环境内嵌外链


外链广告投放在携程 app 环境内,不需要去开发携程 app 的分享或者 title 的 bridge 设置代码,因为乐高跟 app 基础对接过相关参数,通过这个组件就能自动引入 bridgejs 和具体设置代码,从而可以自动设置 app 环境下的 webview 分享功能和导航头文案颜色等,甚至是其他更多 bridge 功能。这样可以避免用 iframe 引入带来的诸多问题。


  • 自定义代码引入组件


通过这个组件能通过 ajax 引入基础 html 页面模块,达到页面部分模块快速定制化交互的需求。后来我们基于这个功能,扩展了可复用的 snippet 组件。

四、组件(模块)的技术栈类型

组件设计归纳是一个重要的步骤,但是开发组件才是中心任务。


乐高初期基于公司框架 Lizard 搭建,而后扩展引入 html 代码片段组件,后面又扩展引入 vue 组件,再后来又推出了能将组件对外“输出”的 sdk,目前正在基于公司 NFES(React)改造,每个步骤都有其实际意义和现实考量。



现在线上的乐高能够渲染的组件类型有三种:


4.1 基于 Lizard 的 AMD 模块

乐高平台最开始是在公司的 Lizard 框架的基础上搭建的,底层是基于 Backbone 框架(MVC)。乐高定义了一个 ModuleBase 类为组件基类,基于模板方法模式,负责分发组件配置数据,安置生命周期钩子等。子组件继承 ModuleBase 基类,各自实现逻辑,互不影响,高内聚低耦合。


子组件是一个个独立的 js 包,部署在 CDN 网络,通过 requirejs 动态引入,满足设计原则:OCP(对扩展开放,对修改关闭)



基于 Lizard 开发的组件:


4.2 基于 VUE 的 UMD 模块

VUE 框架的轻量,简单,以及 MVVM 带来的数据驱动和 virtual DOM 带来的性能提升,促使我们更多的开始开发 VUE 活动页面。开发这些定制活动页面的时候也积累了一些可以复用的业务组件和 web 组件,我们就在考虑可不可以把这些基于 VUE 的组件引入到“乐高”中呢?


vue-cli 3.0 的快速构建原型开发给了我们方法。


vue build 提供了将组件构建成为一个库或一个 Web Components 组件的能力。具体来说,就是将某个单独的 vue 文件打包成 umd 格式的类库。如下图所示:



乐高将这些组件配置引入,并给这些组件配置所需表单属性,它们就成了乐高组件的一员。渲染组件时用 vue.runtime.js 运行时的 render 方法进行渲染。


这样我们就能结合 VUE 和 Lizard,让乐高系统充分接纳 VUE 组件。



乐高上有很多基于 VUE 开发的组件,明显交互效果更好,开发效率更高,组件复用率也更高。


4.3 基于静态 html 的代码片段

部分模块儿定制性强,需求紧急,暂时没有组件,又不需要开发公共组件,针对这种情况,我们开放了基于轻量 html,css,js 的代码片段的组件加载模块儿,新增了代码片段组件,这种类型的组件开发迅速,可以专门处理定制性强需求紧急的模块。


该加载模块通过 ajax,将 html+JS+css 实现的定制组件加载进来,结合乐高平台的原子属性就能组成“snippets 组件”。 乐高在渲染这种组件时会通过立即执行函数将同一个页面上同一种 snippets 组件的作用域变量分发,使得各个组件拥有自己的配置数据,这种方式也能做到一次开发,多次配置使用。



线上已经有的 snippets 如:


五、SDK(legao.seed.js)

那么,这些组件或者模块如何能够更多的复用,更大的发挥它的作用?


比如:开发好的这些组件,除了用在乐高系统,能否也用在其他地方呢?


思考场景:如下一个“大转盘”组件



如果从头开始开发,则需要:产品–>UED–>前端–>后端–>配置平台,显然需要大量人力。通过 iframe 引入的方式在跳转返回,登录态,以及用户体验上都是极差的。


乐高上已经有很多业务+UI 可复用的组件(如刚才这个大转盘),“乐高”大转盘有一整套基于大转盘抽奖的流程,数据结构,能不能直接复用这些呢,或者说能够在任何一个页面中嵌入乐高的更多其他组件呢?这样就有了 Legao 的渲染 sdk:legao.seed.js。


开发这个 sdk,也是想进一步发掘乐高“业务”中台的一个优势。



legao.seed.js 引入也很简单。



这样的话,基于 vue 开发的组件不仅能在乐高平台中由运营同学自由配置,也能在我们开发其他活动页面的时候由开发同学根据所需模块引入,而且,运营还是能自由配置组件所有属性,无疑节省了很多的人力,提升活动开发的效率。


理想情况下,如果这种可复用的组件增多,那么开发其他活动或者项目的时候,节省的成本也会更大。

六、动态表单

乐高平台的另一个特点在配置平台上的体现就是动态表单。为了配合组件能够快速的上线,并且能够灵活的修改,组件在配置平台上都依赖“动态表单”系统自动生成子属性列表。


我们知道一般的组件配置表单需要开发人员去定制开发,针对每一个组件的配置属性做重复性的表单开发。如果没有这个表单,则运营人员面对的就是一堆的 JSON 字符串。如:



如果需要配置这个图里面的 json,肯定是非常不方便的,除了每一个表单都需要定制开发外还有有什么办法解决呢? 我们进行了动态表单的改造。期望能够自动生成一个统一而定制的动态表单。


每个组件都被拆分成了众多原子属性的集合,借助我们的组件治理模块,能够快速配置出动态表单,主要实现原子属性渲染类型,表单校验(正则,非空等),原子属性提示的配置等。



这样运营在配置组件属性值的时候能够更清晰,更方便。最重要的是能够随时修改要配置的属性,无需再开发。


如:“交通类产品配置组件”的动态表单配置:



最后呈现的就是可视化的配置界面:



此外动态表单也能用在 offline 其他动态字段的地方,减少开发成本,配置更方便快捷。

七、最后

乐高平台从 0 开始搭建,对组件的探索也历经了几个阶段,有些目标却是一直没有改变的,这就是使组件丰富化,可复用化。更长远的目标就是借助这样一个平台,能够形成组件化开发的良性循环模式,理想是无论常规类活动页面的开发还是定制类活动页面的开发都能够基于一套统一的组件,达到开发的组件能够继续复用,继续优化的目的,通过这些建设我们市场部的组件或者业务“中台”。


另外我们也在做基于公司的 NFES 框架(React 技术栈)做组件的改造,在首屏性能上,组件拆分,组件复用,国际化,SEO 等方面做提升。


作者介绍


孙罡,携程市场部活动平台前端工程师,主要负责市场“乐高”平台搭建,组件开发,以及各种定制活动的开发工作。


本文转载自公众号携程技术中心(ID:ctriptech)


原文链接


https://mp.weixin.qq.com/s?__biz=MjM5MDI3MjA5MQ==&mid=2697268973&idx=2&sn=7bdca0ffdea87338d5d8ac64c1ad7002&chksm=8376f1d9b40178cfb07f5a50bbd09c16850b619b5f3cc1afe2ccf2109505cb424212dbebf353&scene=27#wechat_redirect


2019-10-22 08:005950

评论

发布
暂无评论
发现更多内容

BitKeep逆势崛起:千万用户的信任,终点还未到来

西柚子

ImageBind 横跨六种数据模式,用向量统一 AI 语言

Zilliz

Zilliz AIGC 向量数据库 Towhee imagebind

涅槃重生,BitKeep如何闯出千万用户新起点

股市老人

文心一言 VS chatgpt (16)-- 算法导论4.1 1~2题

福大大架构师每日一题

ChatGPT 文心一言

Go语言中如何通过接口来实现单一职责原则

Jack

如何优化Golang中重复的错误处理

乌龟哥哥

三周年连更

dart-sass与node-sass的区别以及使用dart-sass可能会出现的问题

不叫猫先生

CSS SASS 三周年连更

2023开源之夏|来自MatrixOne社区的邀请函

MatrixOrigin

MatrixOrigin MatrixOne 开源之夏

ES数据没了?谁动了我的数据?

极限实验室

elasticsearch 数据误删 数据丢失

PoseiSwap:合规、隐私与支持更广泛的资产

BlockChain先知

从 ChatGPT 大热看未来的云计算的发展趋势 | 社区征文

宇宙之一粟

ChatGPT 三周年征文

比起失业我更害怕自己“一无是处”|社区征文

轻口味

个人成长 移动端 三周年征文

奇葩的 Git 签名错误

HoneyMoose

C++编译器和链接器的完全指南

小万哥

c++ 程序员 面试 后端 开发

2023-05-12:存在一个由 n 个节点组成的无向连通图,图中的节点按从 0 到 n - 1 编号, 给你一个数组 graph 表示这个图, 其中,graph[i] 是一个列表,由所有与节点 i

福大大架构师每日一题

Go 算法 rust

Django笔记二十六之数据库函数之数学公式函数

Hunter熊

Python 数据库 django 公式函数

BitKeep逆势崛起:千万用户的信任,终点还未到来

鳄鱼视界

利用 Amazon API Gateway 和 Amazon Lambda 处理 Cloudfront 的内容请求

亚马逊云科技 (Amazon Web Services)

MySQL 安装配置

梦笔生花

MySQL shell脚本 三周年连更

BitKeep逆势崛起:千万用户的信任,终点还未到来

小哈区块

ihateniggers:针对Python开发者的Windows远控木马分析

墨菲安全

墨菲安全 软件供应链安全 投毒分析

涅槃重生,BitKeep如何闯出千万用户新起点

BlockChain先知

MatrixOne Layout 设计解读

MatrixOrigin

分布式数据库 MatrixOrigin MatrixOne

专家共话:存力一体成“东数西算”全场景利器

脑极体

算力

新技术层出不穷,程序员到底该走哪条路|社区征文

阿泽🧸

职业规划 三周年征文

Java补充之MySQL入门必备知识

timerring

Java

一文讲明白路由器的基本概念、工作原理、主要部件以及应用场景

wljslmz

路由器 三周年连更

Kubernetes CNI之Flannel网络模型分析

王玉川

Kubernetes 云原生 flannel VXLAN cni

知乎文章被百度收录有何意义?如何让知乎文章被百度收录?

石头IT视角

失业浪潮之下,不如一蓑烟雨任平生 | 社区征文

宇宙之一粟

已配置4000+页面,携程前端组件化探索之“乐高”运营系统_语言 & 开发_孙罡_InfoQ精选文章