乐趣区

关于前端:企业级前端组件建设

组件化,又或者组件抽离的目标是为了性能共享不便保护,其可能带来的益处是少写代码,对立治理、对立保护。一套根底组件代码千锤百炼精而又精,从而起到疾速撑持业务迭代,晋升开发效率的目标。

前言

去年咱们平台为客户提供了一套企业级前端组件计划,收集了一下客户的需要,同时也做了一部分调研工作,因为咱们是为金融机构服务的,所以也发现了同业中广发所做的 GFDesign 也是这样的思路,大家能够看广发挪动端对立组件库 GFDesign 来了这篇文章,同时像蚂蚁的 Ant Design、字节的 Arco Design 和 Semi Design 以及腾讯的 TDesign,都是相似的企业级设计零碎以及组件库。那么提到了组件库不得不说一下组件化。

组件化是一种十分优雅的提效率、保品质的解决方案,能够帮忙研发人员实现性能复用,升高代码反复率,进步研发效率。帮忙设计师疾速构建 UI 设计稿,保障格调的一致性,为用户带来视觉和交互的一致性,例如色彩、字体、大小等。所以组件化不仅仅是前端代码的组件化,同时也蕴含了 UI 设计稿的组件化,帮忙产品经理或者 UI 设计师疾速绘制原型图以及 UI 设计图。

前端组件建设作为前端基础设施建设中的一环,它在很大水平上间接决定了前端工程代码的复用率。组件建设的目标就是复用性、灵活性,从而提供开发效率和品质。组件建设能无效解决许多代码层面的问题,帮忙开发人员晋升研发品质和效率。

组件标准

设计语言标准

设计语言标准次要用于明确组件的表达方式、偏好或格调,例如色彩、布局、字体等。明确设计语言标准有两大益处:对内而言,对立设计规范会在最大水平上防止业务中呈现各种个性化的设计,保障界面风格的一致性,使页面颠三倒四;对外而言,明确设计语言能够帮忙企业建设对立的品牌符号、品牌特色,有助于加深产品在用户心中的印象,对立的色彩和交互模式能加强用户对产品的相熟感和信任感,好的设计语言能够在体验上为产品加分。设计语言次要包含 7 局部。

第一,设计价值观。设计准则是领导设计师进行设计的准则,它确定了一个设计语言的基调。例如,国内比拟驰名的设计语言 Ant Design,它的外围设计价值观就是天然、确定性、意义感、成长性。

第二,色调体系。设计语言须要在一开始就定义好整个零碎的色调体系,色调体系一旦建设,前面所有的设计都将围绕这一体系开展,包含品牌色、辅助色、字体黑白灰色彩、不可用色彩、超链接色彩、胜利或失败色彩等。从设计角度来看,设计师们会保护一套主色盘和辅助色盘用于后续的设计工作;从研发角度来看,开发人员在实现组件时也会用变量存储要害色调数值,便于对立保护和替换主题色。

第三,图形。图形是设计语言中不可短少的一部分,它可能将某个概念转换成清晰易读的图形,从而升高用户的了解老本,晋升界面的好看度。例如,图标、背景图、插画等,它们都属于图形的一部分。

第四,布局。布局是页面设计中至关重要的环节,它间接确定了页面中内容的区域划分,一个正当的布局计划可能让页面的内容展现得更为敌对。例如,设计语言 Ant Design 采纳的就是 24 栅格体系,在不同像素的显示设施下出现的模式不同。

第五,字体。字体是体系化界面设计中最根本的形成之一,字体零碎包含字体品种、字间距、行间距、字重、字体色彩等内容。一个科学合理的字体零碎可能大大晋升用户的浏览体验及效率。

第六,暗影。暗影来源于现实生活,由两个不同阶层的立体产生,且强度由两者之间的间隔决定。物体的高度间接影响物体的暗影,物体离高空越远,暗影越大,含糊值越高。通过正当利用暗影,能够使得界面具备层次感,从而将用户注意力无效聚焦在须要突出展现的中央。

第七,图文关系。图文关系用于定义图片和文字之间的协同关系,保障两者之间不呈现抵触。例如,当文字呈现在图片上时,应该如何该搭配图文的色调,文字应该展现在什么地位。

业界比拟有名的设计语言有谷歌的 Material Design、微软的 Metro,以及蚂蚁金服的 Ant Design 等,其实不同的企业都有本人设计规范。从零到一搭建一套设计语言是一件繁缛、艰难且老本极高的工作,所以咱们个别抉择一套成熟的设计语言作为基准语言,在它的根底上进行个性化革新。比方咱们能够基于 Ant Design 设计规范批改全局的色调、字体等,革新成咱们本人企业的设计格调。

研发设计规范

依照组件的性能颗粒度对组件进行划分,能够失去原子组件和分子组件,其实这里的原子组件和分子组件是 Design System(设计零碎)中的实践,相干内容能够参考 https://www.uisdc.com/atomic-design-theory。明确组件的颗粒度能够帮忙开发人员防止反复开发组件,最大水平实现组件的性能复用,不仅便于保护,而且可能进步研发效率。不可再拆分或者没有必要再拆分的组件被称为原子组件。如果组件至多蕴含一个原子组件,同时增加了性能代码片段进行性能扩大,就被称为分子组件。举个例子,以后有一个下拉框组件,可能依据传入的配置信息提供下拉选项,返回抉择的对应信息。如果零碎中频繁用到某个配置信息的下拉框组件,就能够基于下拉框组件进行封装,将须要内部传入的配置项间接内置,这样就能失去一个新的分子组件。

明确组件颗粒度后就须要制订原子组件的研发设计规范,能够分为以下 5 局部。

第一,KISS(Keep It Simple And Stupid)准则。它的核心理念是让代码尽可能简略,并且放弃代码的可读性。开发人员判断组件是否合乎 KISS 准则的要害并不是代码量,而是代码的可读性。如果代码可读性很好,使用者能在短时间内看懂,就阐明该组件合乎 KISS 准则。在大多数状况下,开发人员能够通过恪守代码标准、对函数进行清晰易懂的命名,以及增加说明性正文等办法来进步代码可读性。

第二,YAGNI(You Ain’t Gonna Need It)准则。它的核心理念是不要适度设计。例如,开发人员不要设计以后用不到的性能;不要编写以后用不到的代码。代码能够依据业务状况预留扩大点,然而不须要提前实现这些性能。

第三,DRY(Don’t Repeat Yourself)准则。它的核心理念是进步组件的复用性。同样性能的代码逻辑,只应该被实现一次。开发人员应该将公共局部形象进去作为工具函数,从而进步代码的复用性和可维护性。例如,在大多数状况下,分子组件中的原子组件能够作为公共局部进行形象,从而无效进步组件复用性。

第四,LOD(Law Of Demeter)准则。它的核心理念是升高组件之间的耦合性,尽量做到能不依赖就不依赖。如果须要依赖,那么也应该尽可能依赖形象局部,放弃依赖关系上的松耦合。如果可能放弃松耦合,当依赖局部产生变更时就可能将影响降至最低。即使是不兼容式改变,开发人员也能以最低老本迁徙。

第五,SRP(Single Responsibility Principle)准则。它的核心理念是一个组件应该只关注一个性能点。如果违反了该准则,就会导致组件外部呈现大量的逻辑分支,从而使得逻辑凌乱,组件难以拓展和保护。

以上设计准则并不需要在同一时间内全副恪守,开发人员应该灵活运用以上设计准则。例如,在理论业务开发中,如果不能确定某一个性能将被复用,却为了这个临时用不到的复用需要投入大量的工夫、精力,从而导致开发成本上升,就不是很好的做法。同时,这也违反 YAGNI 准则。因而,在第一次编写代码时,开发人员不须要投入太多精力去思考复用性。如果遇到复用场景,就应该遵循 DRY 准则,对代码进行重构,从而使其可能被复用。

组件化的指标

  • 代码复用,晋升开发效率 依据业务特点,横向和纵向划分组件,以组件为单位承接业务需要。尽管以 UI 组件为主,但对于绝对独立的性能,也进行了纵向的组件抽取。
  • 组件独立开发保护,与各我的项目解耦 组件独自开发、调试、公布,供业务方调用,业务方只需专一业务自身。
    更不便的组件调用,更正当的路由跳转 组件调用需明确输出、输入参数,并对参数进行校验并给出正当谬误提醒。
  • 组件文档化,升高组件应用门槛 组件库须要有欠缺的应用阐明文档,使业务方更加容易、便捷的应用。

    组件的分类

    在前端开发中,咱们常常把组件按类别分为:根底组件和业务组件。

根底组件

根底组件是咱们最底层的根底视图组件,它是上层建筑的基石,像咱们罕用的 Element UI、Ant Design、View Design、Vant 等根底组件库。其中根底组件可分为:根底 UI 组件、根底工具组件。

  • 根底 UI 组件:蕴含了:文本、图片、按钮、布局、loading 加载、toast 提醒等罕用的 UI 组件。
  • 根底工具库:这是一组 JS 库,无 UI 界面,蕴含我的项目所应用的根底性能,如:网络申请、页面埋点、异样上报、与 Native 交互的 CallNative,以及一些罕用 utility 工具等等。

    业务组件

    业务场景:我的项目多且独立、又要放弃产品一致性。

不同模块或者子系统之间很多业务往往是相通的或者类似的,如果这个时候咱们每个页面对于实现相似的业务场景都去反复去写一遍业务代码,那齐全是没必要的。咱们能够把性能或者需要相似的有机体封装成一个业务组件,并对外裸露接口来实现灵便的可定制性,这样就封装成业务组件。比方商品模块,ui 和交互都一样, 就抽取进去, 商品信息作为属性传递进来, 依据需要去展现商品信息, 外部交互本人解决, 有的交互须要告诉父组件时通过事件向外传递。

组件设计准则

  • 须要对立技术栈,保障组件在同一技术生态。
  • 繁多职责,一个组件只专一做一件事,且把这件事做好。
  • 谋求无副作用,输出一但确定,输入就是固定的。
  • 可配置,一个组件要明确它的输出和输入别离是什么,同时入口处查看参数的有效性。
  • 粒度适中,划分粒度的大小须要依据理论状况衡量,太小会晋升保护老本,太大又不够灵便和高复用性。每一个组件都应该有其独特的划分目标的,有的是为了实现复用,有的是为了封装复杂度,实现业务清晰的目标。
  • 适当的包体大小,便于页面疾速加载。
  • 欠缺的应用阐明文档。

    组件的划分

    在我的项目中咱们常常会面临组件的提取,那么咱们如何晓得该提取哪些组件,在这里有两个倡议,第一个是你我的项目中复用水平比拟高,即不同页面或同一页面应用绝对频繁的能够作为组件提取。第二个是我的项目中应用绝对较少,然而复杂度和难度较大,业务属性很高,只有相似业务才会用到的组件。这就须要划分人员有足够的我的项目和业务教训去做组件的拆分。

对于组件咱们去划分根底组件以及业务组件,因为业务组件具备业务属性,属于特定场景,所以咱们这里基于根底组件去做一些类型的划分,当咱们分别哪些是根底组件的时候能够依据对应类型去做判断。这里以 Ant Design 为例:

  • 通用型组件: 比方 Button, Icon 等
  • 布局型组件: 比方 Grid, Layout 布局等
  • 导航型组件: 比方面包屑 Breadcrumb, 下拉菜单 Dropdown, 菜单 Menu 等
  • 数据录入型组件: 比方 form 表单, Switch 开关, Upload 文件上传等
  • 数据展现型组件: 比方 Avator 头像, Table 表格, List 列表等
  • 反馈型组件: 比方 Progress 进度条, Drawer 抽屉, Modal 对话框等
  • 其余组件:比方 Anchor 锚点, BackTop 回到顶部等

    目录构造

    咱们以 Element UI 为例,剖析一下工程的目录构造。

  • build:打包工具的配置文件
  • examples:寄存组件示例以及文档
  • packages:寄存组件源码
  • src:寄存入口文件以及次要辅助文件
  • src/directives:搁置自定义指令
  • src/locale:搁置语言的配置文件
  • src/mixins:搁置组件用的混合文件
  • src/transitions:搁置动画配置文件
  • src/utils:搁置用到的工具函数文件
  • src/index:组件注册的入口文件
  • test:寄存单元测试文件
  • types:寄存申明文件,不便引入 typescript 写的我的项目中,须要在 package.json 中指定 typing 字段的值为申明的入口文件才失效
  • commonents.json:配置文件,标注了组件的文件门路,不便 webpack 打包时获取组件的文件门路
  • 清晰牢靠的目录构造能够无效进步开发效率。例如,每次在开发组件前,都须要进行创立组件目录、创立组件文件、初始化组件模板、创立测试目录 / 文件等一系列繁缛又反复的工作。在明确目录构造后,开发人员能够在 scripts 目录中增加脚本。当开发人员须要新增组件时,能够通过脚本在 components 目录下疾速创立组件,进步开发效率。

款式主题

款式主题指组件的 UI 格调。组件在设计规范和技术上反对灵便的款式定制,从而满足业务和品牌多样化的视觉需要,包含但不限于全局款式(主色、圆角、边框)和指定组件的视觉定制。

款式主题通常会借助 CSS 扩大语言的变量能力。例如,Element UI 的款式应用 Sass 作为开发语言,并定义了一系列全局 / 组件的款式变量,开发人员能够依据需要进行相应调整。在 Element UI 中咱们找到 packages/theme-chalk/src/common/var.scss,咱们能够看到款式主题配置变量如下。

当开发人员须要进行款式定制时,能够通过变量笼罩的模式自定义相干参数值。除此之外 Element UI 也提供了在线主题编辑器,可能批改定制 Element 全副全局和组件的 Design Tokens,并可能不便地实时预览款式扭转后的视觉。同时它还可能基于新的定制款式生成残缺的款式文件包,供间接下载应用。

国际化

国际化(Internationalization)是一种设计和制作形式,它能够帮忙产品疾速适应不同国家和区域的要求。它规定开发人员应该从产品中抽离所有与地区语言、国家 / 地区和文化相干的元素,并能通过配置等伎俩疾速替换这些元素。以界面文字为例,不同的国家和地区须要应用不同的语言。

开发人员在开发组件时,应该无意识地将通用词汇保护起来,例如交互反馈(确定、勾销等)。除了词汇,工夫也是国际化须要关注的局部,例如时区、日期展现等。

组件库应该提供全局设置国际化计划的办法。例如,Element UI 中默认提供了 locale 来实现国际化的性能,默认为中文,咱们引入组件库的时候能够设置。

// 残缺引入 Element
import Vue from 'vue'
import ElementUI from 'element-ui'
import locale from 'element-ui/lib/locale/lang/en'

Vue.use(ElementUI, { locale})

当然咱们也能够应用 vue-i18n 插件来提供国际化的能力。国际化计划的底层都是通过保护多套配置信息实现的,其原理大同小异。

组件测试

组件是形象的根底公共模块,因而对其进行单元测试是十分必要的。一方面,单元测试可能笼罩到一些端到端测试笼罩不到的点;另一方面,它也能进步组件代码的可维护性,保障代码品质。

组件测试举荐应用 Jest 框架,它是 Facebook 开源的一个前端测试框架,自带断言库,配置繁难,提供了 mock 零碎、快照测试、异步代码测试、动态剖析后果等性能。

在组件测试中,被利用次数最多的通常是快照测试。快照测试会在测试文件目录下生成快照文件目录 snapshots/**.test.js.snap。开发人员每次执行测试命令时,Jest 都会先执行测试用例,而后将后果与该目录下的快照文件进行比对。如果两个快照的内容不匹配,测试用例就不会通过。生成的快照只有在第一次执行时才会主动变更,后续依赖开发人员手动更新。开发人员须要确认本次生成的快照内容通过,Jest 才会将快照更新为以后执行后果。

在 Element UI 中应用 Karma+Mocha 来做单元测试,Karma 是一个基于 Node.js 的 JavaScript 测试执行过程管理工具(Test Runner)。该工具在 Vue 中的次要作用是将我的项目运行在各种支流 Web 浏览器进行测试。Mocha 是一个测试框架,在 vue-cli 中配合 chai 断言库实现单元测试。后续针对单元测试独自作为一个章节阐明。

文档治理

组件编写实现是组件建设的第一步,只有当组件被理论使用到业务中,可能获得实质性研发提效成绩,组件建设才有意义。组件应用的文档是否足够清晰、欠缺,是决定组件是否被无效使用的要害。一份优良的组件文档必须满足以下两个条件。

组件属性形容齐全:文档应该包含组件的属性名、参数类型、性能形容、默认值、是否必填等内容,开发人员能够通过浏览组件文档疾速理解组件的所有性能,不须要破费大量工夫浏览源码。
次要应用场景全笼罩:丰盛的性能示例能够帮忙开发人员疾速找到对应的应用场景,进步其应用组件的积极性和正确性。
Element UI 的 demo 源码都在 examples 目录中保护,当咱们在 Element UI 工程下运行 npm run dev 的时候,会启动它的开发调试模式,并且运行官网文档和 demo。

对于开发人员来讲咱们常常应用 Markdown 来编写开发文档,社区也有开源的文档生成工具,像 VuePress 和 dumi 帮忙开发人员疾速生成组件文档。

构建打包

组件开发实现后,须要构建打包并输入编译后的文件,便于作为第三方依赖被其余模块应用。在个别状况下,开发人员会将打包后果输入在工程根目录下的 build 或 lib 文件夹下,并把该目录增加到.gitignore 文件中,防止打包后果被 Git 记录后提交到代码仓库中。

在构建打包时须要思考两个内容,一是模块标准,二是组件的理论应用场景。模块标准有 CommonJS、AMD、CMD、UMD 和 ES6 Module,组件的应用场景次要有全量引入和按需引入两种。

全量引入指将所有组件都引入工程,按需加载不会将所有组件作为一个整体打包,而是通过编译的伎俩对每个文件进行独自解决。

以 Element UI 为例,为实现按需引入,须要借助 babel-plugin-component 这个 webpack 插件,并且配置 .babelrc。

{"presets": [["es2015", { "modules": false}]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

将上面这段代码

import {Button} from 'element-ui'

转换成

var button = require('element-ui/lib/button')
require('element-ui/lib/theme-chalk/button.css')

公布标准

当所有组件研发工作都实现后,开发人员须要应用 npm publish 公布组件的模块。每次公布模块都会波及版本号的更新,同样应该恪守开源社区对立约定的语义化版本(Semantic Versioning)标准。

语义化版本标准是一套版本变动的标准,其构造是规范的版本格局:X.Y.Z,每个字母的含意如下。

  • X:主版本号。当进行了不兼容式改变或者有重大更新时,会批改此版本号进行发版。个别对于该版本号的批改极其谨慎,因为这种批改对应用方造成的冲击会很大。
  • Y:次版本号。当进行了小性能的更新或降级时,会批改此版本号进行发版。
  • Z:补丁版本号。当进行了低版本的缺点修复时,会批改此版本号进行发版。

在大多数状况下,版本号都以 0.1.0 开始,并在每次公布时依照改变状况对相应版本号进行批改。当公布的模块被用于正式环境时,应该曾经达到了 1.0.0 版本。

在公布模块的正式版本之前,还存在其余测试版本:

  • Alpha:希腊字母 α 的谐音,指内测版。个别是用于外部交换或者提供给业余测试人员测试用的版本,通常存在大量性能或逻辑缺点,不适宜正式应用。
  • Beta:希腊字母 β 的谐音,指公测版。个别是用于领先测试体验的版本,该版本也会存在一些缺点,不适宜正式应用。
  • Gamma:希腊字母 λ 的谐音,公测版的加强版本,通常来说与行将发行的正式版相差无几。
  • RC:Release Candidate 的缩写,指候选版本,仍然处于 Gamma 阶段,但该版本曾经实现全副性能并修复了大部分 Bug。到了这个阶段只会修复 Bug,不会再对软件做任何大的更改。

    参考内容

  • 闲鱼组件库的建设
  • 爱奇艺常识 WEB 前端组件化实际
  • 从 0 到 1 教你搭建前端团队的组件零碎
  • 前端基础设施怎么搞?看腾讯 TDesign 跨技术栈组件库的最佳实际!
  • 广发挪动端对立组件库 GFDesign 来了
  • 腾讯开源企业级设计体系 TDesign
  • 你好,ArcoDesign
  • 抖音企业级利用设计零碎 Semi Design 正式开源
  • 北汽 (华夏出行) 自研组件库《Essential》开源啦!
  • Vue DevUI 1.0 正式公布
退出移动版