写点什么

爱奇艺知识 WEB 前端组件化实践

  • 2021 年 2 月 03 日
  • 本文字数:4531 字

    阅读完需:约 15 分钟

爱奇艺知识WEB前端组件化实践

组件化作为一种开发模式,其在代码复用,提高开发效率上的效果被广泛认可。组件化思想适用于移动端、Web 前端、PC 端、TV 端等多种类型的客户端和前端开发


本文主要讲述爱奇艺知识 WEB 前端团队如何结合自身的业务特点,探索和实践了一套高效的前端组件化方案。


组件化:前端解耦和提效利器

前端业务发展过程中,代码体积会越来越大,业务的逻辑复杂程度也会随着迭代越来越高。


组件化的意义在于提效,交付的产物是可用的、直观的、可组合的业务形态。


目前行业内前端组件化按面向使用人群大致可分为 3 类:


面向运营人员:运营人员主要进行页面的创建、设计,组件类似乐高积木一样,拼凑起来,针对特殊的组件,可交给开发人员定制实现,实现一些偏静态或者偏固定功能(如抽奖、问答、支付等)的页面,各个大厂一般都有自己 Low Code 平台下类似的产品。

面向设计人员:设计人员主要参与页面设计,并直接将设计稿转换成前端代码,省去前端的开发过程,比如阿里的 imgcook,也可针对一些复杂逻辑,可交给开发人员进行二次开发。

面向开发人员:这也是最传统的开发模式,主要针对的是动态的页面,需要后端接口配合的场景,各个页面的组件通用,所以抽离出来公共组件供各个页面调用。

爱奇艺知识的组件化设计属于第三种,也即是面向开发人员而设计的。在开发层面,通过组件的复用,能够减少冗余代码、实现功能和业务逻辑的解耦,并且通过组件的拓展提高可拓展性、可维护性


业务场景:项目多且独立、又要保持产品一致性

具体到组件的拆分,目前在业内并没有统一的标准,需要结合具体的业务场景,因为不同场景下组件拆分的力度、程度可能都有所不同。



爱奇艺知识 WEB 前端项目构成

从爱奇艺知识 WEB 前端项目构成可以看到,知识 Web 前端的项目很多,我们把项目按类型分开,每个分类下的项目都是独立的项目,完成其相关的业务功能,各项目是独立开发、独立部署的,并且项目间没有直接的业务关联。项目虽然多,但项目中都有业务相关的课程、讲师、店铺等实体,而这些实体的 UI 样式在各个项目中要基本保持一致,另外一些通用的 UI 元素,比如弹框、loading 等也要保证风格一致,因此为了产品体验一致性,同时提升开发效率,提高代码复用性,Web 前端需要进行组件抽离


在这里需要简单说明一下,我们 Web 端组件化思路和知识移动端团队在组件化的思路是不太一样的,移动端更多的是从业务和功能的纵向进行组件划分,也可以称之为模块化,每一个组件或模块既包括 UI 又包括业务逻辑,比如播放器组件播控播放控制和 UI 样式,分享组件包括分享功能和弹窗,支付组件包括支付流程和收银台支付结果页;而 Web 前端的组件化更偏重 UI 层面,逻辑更多的是放在页面中,这也符合 Web 开发的特点,UI 元素复用性更高


感兴趣的同学可以了解一下移动端组件化的设计思路,传送门在这里:爱奇艺知识移动端组件化探索和实践


根据上述背景,知识 Web 前端进行了相应的组件化建设,目标如下:

1. 代码复用,提升开发效率

根据业务特点,横向和纵向划分组件,以组件为单位承接业务需求。虽然以 UI 组件为主,但对于相对独立的功能,也进行了纵向的组件抽取。

2. 组件独立开发维护,与各项目解耦

组件单独开发、调试、发布,供业务方调用,业务方只需专注业务本身。

3. 更方便的组件调用,更合理的路由跳转

组件调用需明确输入、输出参数,并对参数进行校验并给出合理错误提示;当各项目引用业务组件 涉及到跳转时,组件库自动决定是项目内(前端路由)跳转还是项目外(location.href)跳转。

4. 组件文档化,支持在线调试,降低组件使用门槛

组件库需要有完善的使用说明文档,支持在线调试,使业务方更加容易、便捷的使用。


整体设计

任何工具的设计都需要从实际的业务场景出发,回到我们的场景下,需要考虑如何管理项目间所依赖的公共组件资源变得非常重要,组件的设计既要符合业务方使用的便利性,同时也要满足组件自身开发的可维护性、可扩展性


我们认为,组件化的关键在于组件的分层以及拆分,明确组件的层级以及对层级的定义对于组件化系统至关重要。下面是基于我们自身的业务,我们将组件进行如下分层(图示):



为了更好的理解,我们将层级之间的关系进行如下展示(图示):



由于 Card 组件由多个 Item 组件组成,所以 Card 组件与 Item 组件的关系如下:



card 组件

基于以上设计,我们简单总结一下,组件按类别可分为:基础组件、业务组件。

其中基础组件可分为:基础 UI 组件、基础工具组件;业务组件可分为:item 组件、Card 组件、区块组件、功能组件、页面组件。

基础组件

  • 基础工具库:这是一组 JS 库,无 UI 界面,包含项目所使用的基础功能,如:网络请求、页面埋点、异常上报、与 Native 交互的 CallNative,以及一些常用 utility 工具等等。

  • 基础 UI 组件:包含了:文本、图片、按钮、布局、loading 加载、toast 提示等常用的 UI 组件。

业务组件

  • Item 组件:业务组件的最小单元,比如:列表中的一项,宫格中的一项,金刚位中的一项、轮播图中的某张图片等等。业务方可引入所需的 item 组件或组合 item 组件来完成页面的展示。

  • Card 组件:这是一套服务于 Card 化所对应的一套组件,这里简单介绍一下 Card 化:后端返回的是一套基于 Card 的数据结构,每个 card 数据与前端某一个 UI 组件一一对应,通过对数据的配置来实现对前端展现的控制。Item 组件也可以属于 Card 的一部分,由 Card 组件组合多个 Item 组件来进行界面的展示。

  • 区块组件:是为了完成某一个区块的 UI 展示,而抽离出来的组件,供业务方使用,比如:评论组件、评价组件等。

  • 功能组件:是为了完成某一项具体的业务功能而抽离出的组件,比如:播放器组件、发布器组件、分享组件等。

  • 页面组件:也叫路由组件,这是基于微前端所抽离的组件,我们的某个页面也可以当做组件,从而被其他项目所使用。

技术实现

由于基础组件、区块组件、功能组件已经是非常通用的设计,这里我们重点介绍一下业务组件中的 Card 组件、Item 组件。需要注意的是,不管是基础组件还是业务组件,我们在设计之初都需要让其符合以下设计原则。

设计原则

我们的组件设计原则需满足如下要求:

  • 需要统一技术栈,保证组件在同一技术生态。

  • 单一职责,一个组件只专注做一件事,且把这件事做好。

  • 追求无副作用,输入一但确定,输出就是固定的。

  • 可配置,一个组件要明确它的输入和输出分别是什么,同时入口处检查参数的有效性。

  • 粒度适中,划分粒度的大小需要根据实际情况权衡,太小会提升维护成本,太大又不够灵活和高复用性。每一个组件都应该有其独特的划分目的的,有的是为了实现复用,有的是为了封装复杂度 实现业务清晰的目的。

  • 适当的包体大小,便于页面快速加载。

  • 完善的使用说明文档。

数据协议

在项目初期,我们的 H5 移动端首页:https://zhishi.m.iqiyi.com 是基于后端的 Card 化数据,由后端数据选择前端的 Card 组件、Item 组件来进行页面的展示,在这种场景下,我们的 Card 组件、Item 组件首先被设计出来,与此同时我们设计了一套前端数据协议(可以理解为数据格式定义),后端 Card 数据经过前端协议后,转换成前端的 Card 数据结构,在此数据结构的基础上进而抽离出 Card 组件、Item 组件。


后来发现我们大量的页面并非基于 Card 化数据,而是基于不同的 API 、不同的数据结构,如何让这些页面也复用我们的 Card 组件、Item 组件呢?为此我们需要不同的转换器,将后端的接口数据根据前端数据协议转换为 前端的数据格式(如下图),这样无论后端接口数据如何改变,我们只需更改转换器的逻辑,而无需更改前端组件代码,进而复用我们的 Card 组件、Item 组件。


UI 实现

在具体的 UI 实现方面,我们拿下图中我们的业务 UI 组件库内常用的两个 Item 举例:课程列表 Item、课程宫格 Item 。


不难发现 Item 组件主要是由 图片、文本组成的,而图片、文本恰好又属于我们的基础 UI 组件库范畴。

  • 图片组件,是在保留原生`img`的特性前提下,支持懒加载,自定义占位、加载失败占位、图片获取策略(webp or jpg);


  • 文本组件,支持 单行、多行截断。

所以我们在编写 Item 组件的时候只需组合图片、文本组件即可,这样后期随着我们组件数量增长,当我们开发其他 Item 组件的时候会变得非常轻松,效率也得到极大提升。


还有一点需要注意的是:可能我们的组件需要同时满足在移动端手机、平板、 PC 端的正常展现,这样就会涉及到布局以及屏幕适配的问题,同时也涉及到设备旋转带来的屏幕尺寸动态变化的问题。所以在组件在设计的时候 宽、高不能定死,而是引用方设定的,同时我们需要在组件内兼容不同屏幕的适配样式,也可以分别导出不同屏幕的适配样式文件供引用方使用。

构建工具

由于基础工具库 是一组 JS 库,所以我们使用 rollup 构建,它是一个高效的 library 模块打包器,可以使我们的组件更加轻量、简洁,同时生成 es, umd 格式文件供前端调用。

UI 组件库,我们使用 VUE 作为前端技术栈,使用 Webpack 进行构建,业务组件项目支持导出多个组件入口,支持业务组件按需加载(如下所示)

import { item40000, item40001, item40010, item40011} from '@iqiyi-kpp/ui-biz-vue'
复制代码

组件支持按需加载就意味着,各组件入口需要单独打包,这会涉及到各入口的公共资源重复引用的问题。

我们可以使用 @babel/runtime,@babel/plugin-transform-runtime,设置 core-js 为 false,做大限度减小 babel 转换的包体。


使用 babel 命令打包 JS 文件(不使用 webpack),减小 JS 包体。


使用 webpack externals 将第三方依赖,以及每个组件的公共引用提出来,通过 require 的方式去引用,而不是重复打包到每个组件内。

技术文档

我们的组件库开发完成,并不意味着组件化这件事就算做完了,一个良好的组件库往往需要有一个良好的文档说明,这样会降低团队成员的沟通成本,所以基于 storybook 我们搭建了 UI 组件的文档站点,比如下图的基础 UI 组件库文档,可动态展示最新的组件版本,同时支持 UI 组件在线调试,更能直观的表达组件样式与交互,增强了组件的易用性。



总结

前端组件库一般是放到公司的私有仓库上,通过 npm 进行维护的,使用方需要 引用并打包到自己的项目内才能使用。随着 webpack5 module federation 的流行,也可以将组件当作微模块单独发布,各使用方可通过动态 load module 的方式进行引用


由此也可以看到前端组件化的优势:可以很大程度上降低系统各个功能的耦合性,这对前端工程化及降低代码的维护成本来说,是有很大的好处的。


爱奇艺知识 WEB 前端组件库经过不断的完善和迭代,基本实现了组件化的全部目标,组件通过独立开发、测试、发布,使得各业务项目只需关注本身业务,组件得到充分复用,目前组件化已成功运用到各个业务项目中。


组件化并非一蹴而就,而是一个持续的过程,比如:随着业务组件会变得很多,业务组件需要支持业务方按需加载,同时需要考虑组件的包体大小,不能因组件包体过大导致页面加载过慢;业务组件应该通过类似 Jenkins 工具统一发布,发布前应进行自动化测试,以完成很好的测试覆盖等等。


当然在实际开发工作中会有许多不理想的情况,比如一个小项目没有那么多重复的代码,比如设计团队不认可组件化等等,所以组件化需要考虑具体的业务场景,在这个前提下设计出符合我们自身的组件化系统才有必要。


本文转载自:爱奇艺技术产品团队(ID:iQIYI-TP)

原文链接:爱奇艺知识WEB前端组件化实践

2021 年 2 月 03 日 07:003903

评论

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

零基础学Tableau系列 | 01—Tableau简介、条形图与直方图

不温卜火

数据可视化 数据清洗 4月日更

I'm Back

小天同学

思考 个人感悟 4月日更

1.4 Go语言从入门到精通:Go代理goproxy

xcbeyond

Go 语言 4月日更 goproxy

智能取色-为多元化的产品场景选择完美的色彩组合

百度贴吧技术团队

智能取色 个性化 视觉策略 沉浸感

2021年金三银四全新版互联网大厂面试题,分类80份PDF,累计4700页

Java 编程 程序员 架构 面试

源中瑞智慧平安社区--为平安生活助力

13530558032

WebRtc学习之旅 —— 初认识

小驰笔记

新动能 · 新机遇:SaaS软件提供商 Zoho 25 周年战略再升级

科创人

莫高窟永不褪色的微笑,照耀在华为未曾止步的数据保护征程

脑极体

Rust:范型使用trait限定的一点总结

Microwood

rust Trait 范型 范型约束Output Add

可能是最糟糕的愚人节玩笑:科技史上的美式疯狂

脑极体

Golang 泛型浅析

D

开源 云原生 编译器 语言 Go 语言

朱嘉明:《量子时代和数字经济2.0 》推荐序

CECBC

数字经济

区块链的创新技术给奢侈品行业带来了新的机会

CECBC

奢侈品

勇做全球区块链“分布式存储”领航

CECBC

分布式

Redis为什么变慢了?一文讲透如何排查Redis性能问题 | 万字长文

Java redis 程序员 架构 计算机

2021阿里面试通关手册必备:5000字面经解析(技术/攻克)

比伯

Java 架构 面试 程序人生 计算机

百家号在线视频编辑器的技术演进

百度Geek说

大前端

访问控制相关概念及常见模型

龙归科技

身份和访问管理

WebRtc学习之旅 —— Android端应用开发

小驰笔记

gorm源码阅读之schema

werben

Go 语言 gorm

架构培训作业

肖春

架构师训练营

历史命令被黑客删除?教你实时备份

运维研习社

Linux 4月日更 服务器安全

拥抱云原生,基于eBPF技术实现Serverless节点访问K8S Service

UCloud技术

容器 云原生 k8s serverles

从0开始的支付业务架构演进之路

誰敢得罪我

根据码龄来爬取CSDN博客粉丝

空城机

Python 爬虫 python 爬虫 4月日更 粉丝数据

美团点评高级1234面:算法+HashMap+Zookeeper+线程+Redis+kafka

钟奕礼

Java 编程 程序员 架构 面试

专科出身,2年进入苏宁,5年跳槽阿里,论我是怎么快速晋升的?

钟奕礼

Java 编程 程序员 架构 面试

区块链电子合同--赋能企业数字化转型

13530558032

聪明人的训练(一)

Changing Lin

4月日更

爱奇艺知识WEB前端组件化实践_前端_爱奇艺技术产品团队_InfoQ精选文章