做者简介: 李浩成(Kayo),腾讯广州研发部 UI 工程师。git
通过长时间的打磨迭代,QMUI Web 做为腾讯广研 QMUI 团队的一个开源项目,正式发布到 Tencent Github。QMUI Web 是一个 Web UI 的解决方案,从零开始,由编码规范,到组件和工具方法的制做,再到工做流的整合,不断在迭代,也不断在优化,走过了很多的路。趁着发布的机会,咱们正好回顾这一路的探索过程,分享其中的点滴,也但愿能借此让你们更了解 QMUI Web。github
2014 年中,QMUI 团队支持的主要项目是 QQ 邮箱,Web 端的邮箱是个庞大的项目,但其并无统一的 UI 基础库,多年的高速迭代使得项目的 UI 代码变得混乱,各个模块之间各自开发,除了在代码层面表现出混乱和不可控以外,表现层面也并无很好地统一块儿来。所以,项目急需一套统一的团队编码规范以及一个 UI 基础库。 刚好,这个时候 Sass 等 CSS 预处理器已经发展成熟,自动化工做流的工做模式也日趋完善,所以,咱们决定基于这些技术制做一套通用于不一样项目的 Web UI 框架。框架的场景定位很明确:须要控制总体样式,而且能够适应频繁迭代打磨的大型项目。因此,这套即将诞生的 Web UI 框架的特性也很明确:须要方便地控制项目的总体样式,应对频繁的界面变更,并保持项目质量稳健。 此后通过三年的发展,QMUI Web 最终发展为包含编码规范、样式工具方法与样式管理、内置工做流,配套的 GUI 桌面 App,以及拥有完整文档的解决方案。gulp
在制做框架的过程当中,咱们把框架须要的特性进行整理和思考,造成了一套对于该框架的设计理念,在这些设计理念之中,最核心的关键为通用于多个项目,高效迭代和保持代码稳健,框架的设计也遵循这三个核心点,体如今框架上,具体就是:浏览器
而具体到代码层面,则能够概括为两个方面:框架
做为一个 Web UI 框架,编写代码主要是 CSS 与 HTML,而提到 CSS 与 HTML 的编写,首先要处理的是 Class-name 的命名,在过往的开发中,Class-name 的命名并无固定的规范,开发人员各自进行开发,一个项目通过长时间的迭代后,常常会遇到如命名冲突,命名混乱等问题,这使得项目的迭代变得笨重,也很差维护。所以,咱们须要一套具备以下特色的 Class-name 命名规范:工具
所以,最终 QMUI Web 制定了一套以命名空间为核心的命名方式,这个命名方式主要由“命名空间”,“业务与组件的拆分”,“精确表达 View”三个部分构成。测试
一个 QMUI Web Class-name 应该包含一个命名空间,也是 Class-name 的开头,若是是业务,则以业务内容为命名空间,若是是公共组件,则全局使用项目的名字(或缩写)为命名空间。如一个名为 Demo 的项目,项目缩写能够是 dm,那么该项目下的项目组件和公共类能够这样命名: dm_btn
(按钮)、dm_icon
(图标)、dm_ipt
(输入框)、dm_toolbar
(工具栏)。 逻辑模块命名以具体业务做为前缀,如简历(resume)功能里面的非公共组件部分,以 resume_ 做为前缀(resume_mod
、resume_text
、resume_list
),我的信息(profile)页面的非公共组件部分,则能够以 profile_ 做为前缀(profile_statge
、profile_stage_title
)。 命名空间做为一种基础的隔离,把组件与业务,以及不一样的业务之间的 Class-name 命名隔离开来,避免冲突,然后父子元素之间逐级展开编写,保证了项目内多人协助不易冲突,同时命名带有语义,也方便理解和阅读。字体
接着,QMUI Web 中把项目的代码划分为通用组件(跨项目的组件),项目全局组件(适用于某个具体项目),业务组件(适用于某个业务),以及业务逻辑代码,这样区分出4个颗粒度可使得代码更容易被组织和复用,一个模块随着设计元素迭代,也能够在这4个颗粒度之间进行迭代,从而使得模块在迭代时会更加稳健。而 QMUI Web 框架中的组件应该只收纳通用组件,即跨项目组件。优化
精准表达 View 是指在命名 DOM 节点时要明确这是一个怎样的 View,这里的 View 指的就是 UI 层面上这个元素表示的含义,常见的场景是,一个命名为 resume_head 的元素,在经历屡次迭代后实际在代码中却充当了页脚,这样的命名在多人协做时很容易给后面的开发者形成困扰,而精准表达 View 则要求咱们明确一个 UI 元素的含义,并在命名时准确地表达。编码
前面的“Class-name 命名规范”主要是在规范层面上去实践 QMUI Web 的核心理念,而接着更多地就是在代码层面上去实践了,主要包括三点:
前文提到,QMUI Web 把组件划分为通用组件,项目全局组件,业务组件三种组件,而 QMUI Web 框架收纳的则是通用组件,也是跨项目的组件,但每一个项目的 UI 表现并没有关联,如何处理跨项目组件就成为了一个问题。为此,QMUI 在处理组件时采起的是“半封装”的处理方式,QMUI 框架封装的是代码,所谓半封装,即封装那些与项目具体 UI 表现没有必然联系的代码。例如按钮组件,QMUI Web 中只封装了文字居中对齐,鼠标手型,浏览器样式重置,低版本 IE 兼容性处理等代码,而经常使用的样式如边框、背景、字体表现等,都抽取成变量控制,这些组件的变量最终都聚集到一个配置表 Sass 文件中,配合全局的颜色变量、字体变量等变量,就能够作到跨项目抽取组件,每一个新项目只须要关注具体 UI 表现而无需再处理各类常见的 UI 问题,同时方便地经过调整这些变量的值而快速修改整个项目的样式。
在处理组件时,继承的方式是指一个组件类承担复杂的功能,而组合的方式则是把组件类拆分红一个基类,以及多个子类,每一个子类承担的功能不重复,对于咱们的主场景——频繁迭代,保持稳健,显然组合会更加适合,这种方式避免了在频繁的迭代中须要不断修改组件类,每次迭代只须要修改对应的子类便可。
对于组件的抽取,时常要考虑颗粒度的划分,颗粒度自己就是一个比较开放性的问题,在这里与你们分享一些沉淀的经验:
以上即是 QMUI Web 具体的设计理念,经过命名规范、基础样式配置与半封装组件来保证多人协做时的高效率与可维护性,也使得一个 UI 框架能为不一样的项目服务。
做为一个框架,QMUI Web 主要提供了四种能力来提高 UI 开发的效率与质量,对应前文提到的框架设计理念,QMUI Web 提供的这些功能都是为了帮助开发者方便地控制项目总体样式,应对频繁变更,同时保持代码稳健。
前文提到,框架中会有一份配置表,是各类 Sass 的变量,这些变量控制了一个网页基本的字体样式,连接颜色,通用组件的样式配置等基础样式,在建立一个新项目时,应该先根据设计稿配置好这些信息,当这些信息配置完成,那么一个项目的基本样式就能够快速实现了。例以下图中这些配置属于 QMUI 通用配置,经过修改这些配置则能够快速修改项目的字体策略、正文字体大小,连接颜色等 UI 经常使用的 CSS 属性。
QMUI 中包含一个基于 gulp 的内置工做流,用于快速解决大量重复劳动力的工做,从而提高效率。QMUI 的 gulp 中预先实现了监控 Sass 文件并自动编译和优化,雪碧图处理,模板 include 能力(能够传参和使用条件判断),浏览器自动刷新,图片压缩,文件清理,文件合并以及自动变动等能力。
QMUI 中提供了大量基于 Sass 的 CSS 预处理的方法,包括 CSS Reset,一些常见的 CSS 类(例如清除浮动),计算长度值的简便方法(例如获取 padding 在某个方向的值,计算两个长度值的中间值),快速实现一些样式效果的工具方法(例如实现 border 三角形,适应多倍屏幕的 1px 边框等),这些都是用于提升样式开发的效率和质量。
扩展组件并非由 QMUI Web 的主源码提供,而是由 Demo 提供,一般是由于这类组件结构较复杂,所以业务性没法很好地剥离,从而不能抽取成公共组件,所以这类组件就放在一个 Demo 页,以参考组件的形式帮助开发。
咱们提供了一个用于管理 QMUI Web 项目的桌面 App,在代码层面它独立于 QMUI Web 的源码。它经过 GUI 界面处理 QMUI Web 的服务开启/关闭,并提供了编译提醒,出错提醒,进程关闭提醒等额外的功能,在处理多项目,多分支时能更方便地进行开发。
在经历较长时间的迭代后,QMUI Web 也逐渐完善起来,此时咱们也开始将 QMUI Web 进行开源。开源意味着 QMUI Web 会进入更加全面的环境中去打磨,在框架的非主体内容如代码规范、注释、文档上面也须要更费心思,考虑的点也须要更加周全。这对团队来讲无疑是个很好的机会,能够有更多的渠道审视框架,吸取建议,持续进行优化。
在加入开源的大环境后,咱们从 Github、社区论坛中都获取了很多建议,除了 bug 的反馈外,也指出了一些待完善的地方和提出一些优化的解决方案,从而使得 QMUI Web 注入了更多活力,所以咱们也逐步进行了如“自动化测试用例”、“gulp 结构化”,“引入 SassDoc 自动化生成文档”,“编译 Sass 时引入增长更新”等优化,其中很多优化点咱们也在项目的 Github Wiki 中进行了详细的分享,有兴趣的用户能够自行浏览。
至此,QMUI Web 发展为如今这套完整的方案,也终于开源到 Github Tencent 与你们分享,咱们指望经过开源与你们进行更多的交流,也使得 QMUI Web 进入更加全面的环境中去打磨,造成对代码规范、注释、项目文档感谢公司与部门给咱们提供了一个平台,能够在大型项目中经历迭代和沉淀。开源只是一个开始,咱们后续仍会不断进行探索和优化,期待更好的 QMUI Web。
关注 QMUI Web, 来 Github 给咱们 star 吧!