团队协作规范学习总结

154 阅读19分钟

代码命名规范

代码的注释不是越详细越好。实际上好的代码本身就是注释,我们要尽量规范和美化自己的代码来减少不必要的注释。若编程语言足够有表达力,就不需要注释,尽量通过代码来阐述。——《Clean Code》

良好的命名,可以增强代码的可读性、减少阅读代码的成本,是程序最好的注释。相反,没有规则甚至是和代码内容不匹配的命名,会大大增加我们阅读代码的成本,甚至会误导我们的思维,导致对代码的理解完全错误,后患无穷。

命名方法

我们先来介绍几个在编程时国际通用的、不区分国界、不区分语言的命名方法~

  • 小驼峰命名法(lowerCamelCase)  :第一个单词以小写字母开始,第二个单词的首字母大写,例如:firstName、lastName。
  • 大驼峰命名法(CamelCase)  :每一个单词的首字母都采用大写字母,例如:FirstName、LastName。
  • 匈牙利命名法(HN case)  :基本原则为:变量名 = 属性 + 类型 + 对象描述。
  • 下划线命名法(snake_case) :下划线命名法也叫蛇形法,全由小写字母和下划线组成,在两个单词之间用下滑线连接。例如:first_name。
  • 中划线命名法(kebab-case) :中划线命名法也叫串式命名法,各个单词之间通过下划线“-”连接。例如:first-name。

命名方法是我们命名的基础,我们需要在不同的场景约定好使用哪一种命名方式,比如给文件资源命名通常使用中划线命名法(kebab-case)、JS 中的变量通常使用小驼峰方式(lowerCamelCase),TS 中的类型通常使用大驼峰方式(CamelCase)、CSS 属性名使用中划线命名法(kebab-case)等。

布尔值

命名方式:小驼峰方式。

命名规则:前缀为判断性动词。

动词含义
has判断是否含有某个值true:含有此值; false:不含有此值
is判断是否为某个值true:为某个值; false:不为某个值

使用判断性动词作为前缀会让代码更好理解,通过名称就判断出该变量为布尔值。

函数

命名方式:小驼峰方式(构造函数使用大驼峰命名法)。

命名规则:前缀为动词。

动词含义
can判断是否可执行某个动作
on监听事件的回调
handle处理事件
get获取某个值
set设置某个值

还有一些比如 complete、calculate、compute 这些就不一一介绍了,使用动词作为函数的前缀主要是让函数名称变得更加有描述性,容易理解。

常量

命名方法:全部大写。

命名规范:使用大写字母和下划线来组合命名,下划线用以分割单词。

例如:USER_NAME、PHONE_NUMBER。

类的成员

  • 公共属性和方法:同变量命名方式。
  • 私有属性和方法:前缀为下划线(_)后面跟公共属性和方法一样的命名方式。

例如:

function Student(name) {
    var _name = name; // 私有成员

    // 公共方法
    this.getName = function () {
        return _name;
    }

    // 公共方式
    this.setName = function (value) {
        _name = value;
    }
}
var st = new Student('tom');
st.setName('jerry');
console.log(st.getName()); // => jerry:输出_name私有变量的值

在起名称的时候,应该本着描述性以及唯一性这两大特性来命名,才能保证资源之间不冲突,并且每一个都便于记忆。命名规则要望文知义,简单明了。

最后,我再给你推荐一个变量命名神器:变量命名神器:CodeIf ,该根据是从Github、Bitbucket、Google代码、Codeplex、Sourceforge、Fedora、GitLab中搜索项目,查找实际使用变量名称,然后给你推荐返回结果。

img

并且还提供了 VS Code 插件,可以在写代码的时候直接右键选择 “CodeIf” 就可以跳转到网页搜索。

img

工作流程 workflow

编写代码,是软件开发交付过程的起点,发布上线,是开发工作完成的终点。代码分支模式贯穿了开发、集成和发布的整个过程,是工程师们最亲切的小伙伴。那如何根据自身的业务特点和团队规模来选择适合的分支模式呢?又如何进行多人代码管理呢?

说到分支管理和代码协作,首先想到的就是 Git,Git 是我们用到版本控制工具。主流的版本控制工具有两款:Git 和 svn。svn 的理念是集中式,必须要把代码提交到中心控制器。而 Git 的理念是分布式,每一个开发者在本地都有一个 Git 仓库。因为现在大部分公司或者个人使用 Git,所以在这里我们主要介绍 Git 相关的工作流程。

Git workflow 是有关如何使用 Git 以高效协作开发的规则或策略建议,下文这些常见工作流程只是作为指导参考,这些工作流不是一成不变的,我们应该根据自己的项目选择或制定合适自己的工作流。

我们先来了解下在 workflow 中常见的发布模式和分支模式。

发布模式

我们常见的发布模式有两种:

  • 一种是有明确版本规划、需要有多个版本支持的“版本发布”模式,常用于终端类产品,比如我们常见的手机上的 APP 就是其中一种。
  • 另一种是一个功能分支开发完毕没有问题后就立即可以发布上线的“持续发布”模式,常用于网页产品,因为其迭代快、无需审核,只需要关注最新版本即可。

分支模式

一般情况下,在开发的过程中,我们会使用到以下几种不同类型的分支:

  • master:主干分支,一个项目应该有且只有一个主干分支,并且为 protected 分支。作为最稳定的分支,通常情况是线上环境运行的分支。不能在 master 分支上直接开发,只能被其他分支合入。
  • develop:开发分支,在不同的 workflow 中有不同的用途。
  • feature:功能分支,针对每个功能创建一个 feature 分支进行独立开发。
  • hotfix:bug 修复分支,针对已合并的功能分支有需要修复的 bug ,就创建一个 hotfix 分支。
  • release:预发分支,在正式发版之前,需要一个预发布版本进行回归测试。

主流 workflow

在了解了常见的发布模式和分支模式之后,我们再看下传统的主流的 workflow。传统的主流 workflow 有三种:

  • git flow
  • github flow
  • gitlab flow

我们分别来简单介绍下。

git flow

git flow 是诞生最早的一种 workflow。git flow 工作流下会长期存在两个稳定分支,develop 和 master。master 分支是生产环境运行的分支。而 develop 分支是待上线分支,包含了待上线的功能。大多数情况下,develop 分支的代码会领先 master 分支。

在新迭代开始的时候,会先从 develop 分支中拉取出 feature 或者 hotfix 分支用来平时的开发和 bug 的修复工作,开发完成后,会先将 feature 或 hotfix 合入 develop。然后根据发布计划,将 develop 分支合并到 master 分支进行版本发布的操作。具体工作流程如下图:

img

git flow 模式主要适用于“版本发布”模式。“版本发布”的特点是收集多个功能,并且通常只有在特定的时间才会进行新版本的发布。

github flow

github flow 是 github 使用的工作流。github flow 只有 master 一个稳定分支。在新迭代开始的时候,从 master 创建一个 feature 或者 hotfix 分支进行开发或者 bug 修复。开发完毕后,需要向 master 发起一个 pull request,在 pull request 中可以对代码进行 code review,一旦 pull request 被合并(merge),那么该分支就会自动合并到 master 分支中。

img

比起 git flow 适用于的“版本发布”模式,github flow 更适用于“持续发布”模式。

github flow 更适用于库、框架、工具这些非最终应用的产品,因为该 workflow 只有 master 一个稳定分支,所有的改动也都只合并(merge)到 master 中,所以这就对贡献者的代码质量要求较高。因为一些库、框架、工具通常都不需要调用数据库,可以在本地进行开发、调试和测试,所以开发完毕后只需要将开发分支合并到 master 分支就可以了。

gitlab flow

gitlab 是前面两者的结合,是 gitlab 使用的工作流,更适用于直接面向用户的产品,即可以支持“版本发布”也可以支持“持续发布”。

gitlab flow 也是只有一个主分支 master,并且还有一个原则就是“上游优先”,即只能在上游分支采纳的代码才能同步到其他分支,master 为最上游分支。

对于需要“持续发布”的项目,可以创建不同的环境分支,比如有开发环境(master)、预发环境(release)、生产环境(production)。那么开发环境就是预发环境的上游,预发环境就是生产环境的上游。代码合并遵循“上游优先”的原则,必须按照 开发环境 => 预发环境 => 生产环境 这样的顺序进行代码合并。

img

对于需要“版本发布”的项目,首先要有一个主分支 master 分支作为集成分支,每一个需要发布的版本从 master 新创建分支作为发布分支。发布分支只允许合入 bugfix 分支。

img

综合上面三种 workflow,团队内部可以根据团队的情况进行自由选择和组合,灵活选择。

代码规范

eslint

一个按照规则执行代码检查的工具,它可以在编码阶段进行静态分析,给出检查报告。

prettier

一个代码格式化(美化)工具,可以按照设定的规则配置进行代码格式化,统一风格。

代码提交规范

husky

Git Hook 工具,可以设置在 git 各个阶段触发我们的命令,安装后,它会自动在仓库中的 .git/ 目录下增加相应的钩子。

lint-staged

一个仅仅过滤出 Git 代码暂存区文件(被 git add 的文件)的工具。

commitlint

帮助你的团队遵守commit约定,检查你的提交消息是否符合传统的提交格式。

例如:当我们运行 git commmit -m 'xxx' 时,用来检查 xxx 是否满足固定格式的工具。

UI 设计规范

了解完命名规范,我们来看一下另一个在开发中很有用的规范:UI 设计规范。

我们平时经常要和交互、视觉同学打交道,我们需要按照给出的 UI 稿进行开发,最后还需要经过交互和视觉同学的验收。那么我们如何更高效和愉快地进行合作呢?下面我们就一起来了解下。

为什么需要设计规范?

用户在使用我们开发出来的系统的时候,首先看到的就是我们的 UI 页面,如果设计师没有一定的规范,那么用户看到的页面五颜六色、间距有大有小(当然,可能这些凌乱也是一种设计风格),对于非展示性的产品显然用户不会留下一个好的印象。

第一,培养用户心智,减少用户的学习成本。

交互视觉规范我觉得最重要的意义是培养用户心智,减少用户的学习成本。页面中的每一个元素都有自己的“意义”,形成统一之后,就会减少用户大脑的思考,随之带来的是培养用户习惯,让用户的潜意识能够直接判断出设计者想要传达的设计思想,节省用户的脑力。

比如,当你进行一个删除操作之后,如果出现的 Toast 背景是绿色的,那么就算不看文字描述,你的第一反应是不是你刚刚的动作有了成功的反馈?如果 Toast 的背景是红色的,那么自然会认为刚刚的操作出现了问题。可能是因为受到红灯停、绿灯行的影响,所以我们大部分人的认知当中,绿色是一个成功的反馈色、红色是一个错误的反馈色、黄色是警告的反馈色。所以我们在我们的 UI 规范中,就需要借助于这些公知,培养用户心智、降低用户的理解成本。

再比如,我们都知道,一个网页上,文字的颜色会有很多种各种各样的灰色。那么 UI 是如何借助于这些各种各样的灰色传达出页面的信息呢?我们要和设计同学约定好不同颜色的“语义”,比如颜色越重那么代表文字的重要性更高。相反,颜色越浅,代表文字的重要性越低。那么我们可以将文字颜色分为以下几种,来应对不同场景下的文字颜色。

  • Primary Text #303133
  • Regular Text #606266
  • Secondary Text #909399
  • Placeholder #C0C4CC

Primary Text 代表重要色,一般用在文章或者页面的标题最显眼的位置,和比较少的文字、大字号搭配使用突出页面的重点、传达总述性信息。Regular Text 代表常见色,一般用在文章或者页面的具体内容,和大段的文字、中等字号(一般是 14px)一起搭配使用。Secondary Text 代表次要色,一般用在描述性文字,去掉该文字也不影响页面整体要表达的内容,所以颜色会较浅,和少部分文字、小字号搭配使用。Placeholder 相信大家都比较熟悉了,一般用于 input、textarea 等占位文字的颜色,用作输入提示的占位作用。

通过上面几个例子,可以看出,我们做到了 UI 规范的统一之后,用户就能够方便、正确、高效地去理解我们的产品。

第二,提高可维护性。

统一 UI 设计规范还有一个重要原因是提高项目的可维护性,如果有一天,公司换老板了,老板觉得现有的主题色、logo 太丑了,要将红色的主题色改成蓝色;原有的间距太宽了,导致页面展示的内容太少了,要改成紧凑型,所有的间距都要缩小一点。

如果之前没有一套 UI 规范的话,这些颜色、间距会零散的出现在代码的各个地方,可想而知,你就需要将所有有主图色、logo、间距的页面找出来,一一去修改,可能有些祖传页面你都从来没有修改过 ⊙﹏⊙|||,你哭晕在厕所。但是!如果是按照统一的 UI 规范来开发的,前端可以将所有这些颜色、字体、间距抽象为变量,需要更改的时候,只需要改其数值就可以了。这工作量和效率差的不是一点半点吧~~

第三,提高开发效率。

有的同学可能会说:“这些和我有什么关系,我只是一个小小的前端开发呀!我不关心设计稿是怎么设计出来的,我也不关心用户感觉我们产品不专业不规范乱七八糟,我只负责按照设计稿上的样式进行开发就可以了”。

那么,我告诉你,统一 UI 规范,前端的开发同学也是受益者。试想一下,如果设计稿上的边框有 4px、6px、8px、12px 等不同的尺寸,前端同学凭肉眼比较难区分(当然,设计同学的像素眼是可以找出来你开发尺寸的不对的 (╯︵╰)),那么在开发的时候,频繁在设计稿上去寻找这些尺寸和颜色等信息,会浪费我们大量的开发时间,并且这些相对而言都是一些重复的劳动,对提升我们的专业技能基本上可以说毫无帮助(只能加深我们近视的程度)。

所以,有了统一的 UI 规范之后,我们就可以和设计同学约定,我们按照 UI 规范来开发,设计同学按照 UI 规范来设计,不需要重复做图、标记。对前端开发者而言,可以定义一个符合 UI 设计规范的 CSS 样式库,在需要的时候直接引用定义好的语义化的变量名,就不需要在开发过程中一次又一次的写 CSS 参数值了。这样不仅提高设计的效率而且提高了开发的效率。

甚至在一些对 UI 要求不高的项目,比如 toB 的项目,很多公司可以不需要设计,前端直接使用内部沉淀的或者开源的三方组件库将页面“拼凑”而成。

UI 设计规范范围

前面说了那么多 UI 设计规范的必要性和优点之后,那么 UI 设计规范应该包括哪些内容呢?

UI 设计规范应该是由 UI 同学主导。通常情况下,UI 同学在设计页面的时候都会有一些自己的原则。我们只需要将设计同学的设计原则转换为代码形式即可,当然,我们也要提出可行性的建议。

根据我个人的开发经验并且参考一些开源组件库的设计规范,我个人觉得 UI 设计规范应该包含基础设计元素规范和组件规范这两者。

(1)基础设计元素规范

基础设计元素为抽象出来的最底层的设计元素,包括标准色、尺寸、文字、边距、间距、圆角、动画等。基础设计元素是页面展示的基础,决定了我们项目页面的基调。因为其在最底层,所以理论上应该是在前端开始开发项目前就已经确定好内容。基础设计元素规范的质量直接影响了后续前端开发的效率。

下图列举了基础设计规范的具体内容,主要包括标准色、文字、圆角、边距、间距和动画: 设计元素规范

(2)组件规范

组件规范是在基础设计元素之上的,由多个基础设计元素组合构成。我们就拿要设计一个 Button 组件为例,看一下组件规范需要考虑哪些因素。

首先,我们的 Button 组件需要按照功能分为不同的类型,比如默认按钮、用于超链接的链接按钮、只有图标的图标按钮、用于深色背景的幽灵按钮。这需要用到底层基础设计元素的功能色和文字颜色还有圆角。不同场景下还需要有不同的操作状态:危险、成功、警告、禁用... 这也用到了功能色。同时还要有不同的尺寸规格:大、中、小、迷你,这就用到尺寸元素。颜色、尺寸、文字、圆角这些基础元素互相组合,形成了我们的组件规范。

如下图按钮 Button 组件所示,Button 组件的不同状态是由不同的基础设计元素组合而成。

img

而我们的组件规范,应该包括整个项目中需要用到的基础组件,比如按钮、输入框、模态框、选择框等等不一一列举了。然后需要制定出各个场景的使用规则和对应的样式,基础设计元素规范为组件规范提供底层规范支持。

如果是要开发自己团队内部的组件规范,那么可以“按需开发”,也就是说我们开始可以只设计和开发一些现在用到的组件和场景,随着项目的迭代,再慢慢补充组件或者扩展组件功能。如果是做开源项目,那么就必须要将所有可能用到的场景和扩展在开发前设计好。

项目文件和结构规范

项目结构规范包括文件命名、文件目录组织方式。一个项目的文件结构就像是一本书的目录,是其他开发者了解项目最快的方法。代码的组织方式,也是项目架构设计的体现,比如如何划分视图层、控制层等。如果你是项目的创建者,那么你需要好好设计项目的文件结构和代码的组织方式,框架搭好了,再加砖添瓦就容易了。如果你是项目的维护者,那么你需要遵守项目的文件结构规范,风格统一了后续才好维护,同时也避免了公共函数\组件重复开发的问题。

对于文件目录组织方式,通常我们会在根目录下,按照职能进行划分出多个目录。以 Vue 举例,一般的 Vue 项目一级目录内容如下:

  • 存放公共资源的 public目录(该文件内容不会被 webpack 处理);
  • 用来存放源代码资源的src目录;
  • 用于存放测试用例的 tests目录;
  • 还有自动安装的依赖 node_modules

除了这些一级目录之外,还会有一些配置文件,比如 TS 的配置文件tsconfig.json 、babel 的配置文件 babel.config.js等,还有一些项目文档,比如说明文档 README.md。一个常见的 vue 项目的一级目录结构如下:

.
├── node_modules
├── public
├── src
├── tests
├── README.md
├── package-lock.json
├── package.json
├── babel.config.js
└── tsconfig.json

src 又可以细分为用于接口请求的api 目录、存放静态资源的目录 assets、存放公共组件的目录 components、存放样式文件的目录 styles、项目的路由统一存放在router 中、页面统一存储的变量store、一个公共工具utils、项目的视图集合views

├─api (接口)
├─assets (静态资源)
├─components (公共组件)
├─styles (样式)
├─router (路由)
├─store (vuex)
├─utils (工具函数)
└─views (页面)

项目结构看似很简单,但确是在项目创建初期要仔细思考的问题。项目结构混乱,就如同一本书的目录混乱,目录混乱那么你项目的“读者”能快速争取的理解项目的内容吗?建立统一的目录结构和规范的命名方式有助于其他人快速找到需要的资源。