代码审核规范

代码审核code review

# 代码审核规范

# 为什么要做代码审核

  • 统一编码规范
  • 熟悉业务逻辑
  • 排查低级bug
  • 提升代码质量
  • 让团队成员都参与进来,有助于提升技术氛围。

# 原则

  • 软件设计的各个方面从来都不仅仅是一个纯粹的代码风格问题或者是个人喜好问题。它们是以基本原则为基础的,应当以这些原则为依据,而不仅仅是以个人意见为依据,有时几乎都没有选择的。
  • 如果作者能够证明(通过数据或基于原理的一些事实)他的方法是同样有效的,那么reviewer应该接受作者的偏好。否则,代码风格选择取决于软件设计的标准原则。

# 什么时候做代码评审

  • 一般来讲,是某个需求或项目编码完成,即将进入测试阶段的时候。也有的公司,是在部署到预发环境的时候。这个可以结合自身团队的情况来定。

# 流程

  • 参与者:编码者、业务小组长、主管、其他团队成员视情况而定。
  • 工具:gitlab diff,vs code 等。
  • 如果是日常小需求,就在工位附近就可以;如果是大项目,最好提前预定个会议室。
  • review 过程:
    • 编码者先大致讲一下代码的结构,每个模块是干什么的。
    • 再具体讲核心功能的实现逻辑。
    • 存在问题的地方,需要进行批注,比如在gitlab上添加评论和改进方案。
    • review完成后,由编码者进行修改完成后,还需要做二次确认。
  • reviewer 需要关注:
    • 代码本身逻辑有无问题
    • 是否按照技术方案在实现
    • 代码是否符合团队的编码规范
    • 代码是否存在可优化的空间
    • 等等

# 具体审查细节

  • 是否按照开发方案进行开发
  • 变量名及方法名是否规范统一
  • 注释的代码是否删除、是否有清晰的代码注释
  • 代码可复用的部分是否有抽离并封装
  • 方法传参是否合理
  • 项目中涉及到的地址是否单独写成配置文件
  • 页面请求是否合理,是否没有不必要的请求
  • 请求需要加锁的地方是否有加锁
  • 是否有进行接口返回数据的容错处理
  • ajax请求的超时时间是否设置为3s、是否有设置缓存cache
  • 项目中使用的字体、图片、第三方库等是否涉及到侵权
  • 是否有做iphoneX、折叠屏等适配
  • 页面中是否有写http,https等协议头(客户端协议除外)
  • 图片是否有进行压缩(push场景300K)
  • setInterval,setTimeout定时器是否有清除
  • vue相关:v-for设置键值、模板中不出现复杂的计算、合理的使用v-if或v-show、指令缩写
  • 打开页面查看页面显示是否正常(用户名、手机号等敏感信息是否脱敏处理)
  • 页面中必须引用初始化的css和js,不要使用cb方式引用初始化样式库

# 实践与建议

  • 命名:尽量不使用中文全拼的字母,使用小驼峰英文单词拼写,单词不使用缩写。每个人对缩写的理解不一样,容易引起歧义。
  • 不清楚的业务代码,不允许删除或者修改。或者找相关人员理解透彻后,再做改动。并知晓测试、产品,如果会对开发时间有影响,需要暴露风险。 开发已有项目时,对于基础通用功能和已经实现过的方法需要看懂工作逻辑,不要在没有看懂的情况下修改、调用,会导致代码复杂度提高。
  • 开发已有项目时,需要用到的非业务相关的功能,例如各种格式化处理,接口发送等功能,先找找有没有已经实现的方法,找不到去问之前的开发,之前的开发都不在再考虑自己实现(引用第三方组件一两行代码就能实现的功能不需要封装)
  • 合理使用js内建方法,对字符串先用 “,” 分割然后再用 “/” 拼接这一操作可以直接用 replace 方法替换,不应该先分割再拼接。
  • 使用 scoped 的目的是防止样式泄漏影响其他页面,再在 scoped 中的顶级样式中使用 ::v-deep 穿透 scoped 相当于没有写 scoped。正确做法是在外层添加属于当前组件的选择器,再在里面使用 ::v-deep
  • 不要使用无意义的简写,将 index 简写成 idx 只会增加代码阅读成本,因为作用域的原因无法使用 index ,重新命名比如 xxxIndex
  • 使用 v-if,v-else-if 并列选择多个节点,并且内容只有文本不同,应该使用 methods 或者 computed 直接确定文本并使用插值插入节点中。
  • 绑定到节点的点击事件,没有必须要传递的参数时应该直接写函数名,直接写带括号的函数相当于执行函数,vue 将其作为语句包在匿名函数中绑定给节点,这一操作是冗余并增加代码复杂度的。
  • 如果需要将一个数组处理后的结果作为另一个数组使用,直接使用 map 方法即可,map 设计就是做这个用的,只有在不关心返回值时才需要使用 forEach
  • 代码需要注释,没有注释的代码只能算是半成品。每个方法都尽量写注释,说明方法作用以及有必要说明的地方,比如一些需求特殊要求的地方,代码潜规则等,总之就是自己认为别人接手这个代码的人可能需要了解的东西。
  • 超过两次以上的重复代码,建议封装。

# ajax 请求

  • 页面中ajax请求超时时间设置值3s,过长的超时时间需要和后端确认
  • 页面中ajax请求数据,可以取缓存的,不能使用带时间戳的请求链接,需要设置cache:true
  • ajax请求时需要加进程锁(页面中只请求一次的除外)
  • 页面中需要设置协议头的地方,使用window.location.protocol获取
  • 数据量大的时候,需要进行分页请求
  • 避免同一个数据接口重复请求,可以做本地存储(sessionStorage或localStorage)

# CSS

  • 不要使用奇怪的命名。
  • 必须添加scope
  • 不允许随意添加全局样式。
  • 尽量不使用!important去覆盖样式,而是通过class来覆盖。

# Vue

  • 不允许出现过长的dom,需做换行处理,便于阅读
  • dom 里不要出现 :style 的写法,如需要,请以计算属性替之(避免更新dom重复计算)
  • created中进行数据请求
  • mounted中不操作dom
  • $nextTick(() => {}) 与DOM相关操作写在该函数回调中,确保DOM已渲染后才执行里面的回调函数。

# React

  • 能使用hooks就使用hook写法,不再使用ReactDomClass
  • 使用 useCallBack,useMemo 等语法糖提升性能的函数,都必须使用,避免性能消耗。

# TypeScript

  • 拒绝any,不允许使用any。使用 any,就失去了使用 TypeScript 的意义

# 小案例

# 日期对象初始化

  • var d = new Date('2021-06-24') // good
  • var d1 = new Date(2021,5,24) // bad
  • 为什么说第二种不好,因为不够直观,尤其是第二个参数,虽然传参是 5,而实际指代的是 6 月。对于不熟悉 API 的同学,会造成歧义。第一种方式更容易理解。

# 科学计数法

  • setTimeout(() => {}, 1e3) // bad
  • setTimeout(() => {}, 1000) // good
  • 对于比较小的数字,直接用普通计数法即可。

# 参考