在 Code.fun 做 Code Review

0. Code Review 简介

Code Review,翻译成中文应该是“代码评审”,是软件开发中非常重要的一个环节。简单来说,就是 A 做完一个功能后,发给 B 审查;B 确认代码符合规范、没有明显的质量问题后,才允许合并入主干,以及上线。

Code Review 有很多好处:

  1. 提升代码质量,维护代码规范。
  2. 传承知识。Code Reviewe 是非常好的查缺补漏机会,可以针对性补强开发者的知识盲区,纠正不良习惯。
  3. 找出潜在 bug。一个人可能会考虑不周,但多个人同时犯错的几率就会小很多。
  4. 降低安全风险。如果开发者知道自己的代码会被多人审查,那 ta 多半就不会主动引入漏洞和后门。

那么,Code Review 怎么进行呢?实际上,一次提交少则几十行,多则几百上千行代码,想短时间内完全看明白是很困难的。负责审查代码的人自己也有工作,不可能投入太多时间在看别人代码上。所以,真正的 Code Review 并不要求完全弄明白对方的代码,一般重点在下面几个方面:

  1. 确保开发者遵守了规范
  2. 确保开发者提供了测试用例,且测试用例能覆盖需求场景
  3. 确保代码中没有明显的问题

1. Code Review 实操

接下来,我就结合最近两周的 Code Review 工作,分享一下相关经验,希望对大家有所帮助。

1. 不该使用入口文件

我司之前很喜欢把组件全 import 到一个入口文件里,然后全部 export。在需要的地方 import { someComponent } from '@/component'。这样做的坏处是,如果想使用路由 lazy-loading,Webpack 打包的时候,很难判断哪些组件是当前路由需要的,哪些是不需要的,导致大部分组件都被打包进入口文件,影响启动速度。

正确的做法是哪里用组件哪里引用,不要多此一举。

2. 乱用自定义事件

截图中的组件是个 <el-input>,写代码的同事在面前给 <el-form> 加上了 submit.native.prevent,侦听并阻止原生 submit 事件;然后在 <el-input> 里侦听用户按下回车键事件,以提交表格。

这也是很不好的方式。原生的、规范的事件和操作,一般都已得到众多浏览设备的支持,包括浏览器、屏幕阅读器、各种 IoT 设备,等。如果我们禁用原生事件,自己定义新的事件处理函数,可能在我们自己的设备+浏览器里运行正常,在更丰富的环境里则随时有失败的风险。

3. Boolean 属性应使用单一属性值

这是个规范问题,Boolean 属性都应该使用单一属性值,遵守 HTML 规范。

4. 尽量不要写死 style

我们要适配的设备很多,分辨率千奇百怪,写死的属性值可能在部分环境下运行正常,但是在其它环境下就会失败。再来,CSS 和 JS 的环境是分离的,很难共享数据,很可能 CSS 如果要配置 dark mode、响应式、打印策略时会遭遇问题。

所以,当我们需要条件渲染时,建议:

  1. 写类名。于是 CSS 可以修改类的属性值。
  2. 写 CSS Variable。CSS 里用表达式来调整。

5. 谨慎处理循环

Code Review 时一定要特别注意循环的处理,这里是最容易出问题的地方。比如图上这段代码,应该先筛选再映射(.filter().map()),而不是现在这样。那样的话,可以大大节省 map() 的执行时间。

6. 仔细查文档,不要对付

window.postMessage 需要两个参数,但是我的同事只想传一个,但是会过不了 TypeScript 校验,于是他就把 window as any 了。这就是不该偷懒的地方偷懒 。

2. Code Review 的深度,以及我们应当遵守什么规范

因为大量其它代码有类似……的做法,可以等之后统一修改验证

看到我的 changes request 之后,同事这么回复我。其实这也是一个常见问题:已知我们的代码没有严格遵守规范,存在不少历史积累的技术债,我们应当怎么处理?

有些同事说,我们有一些代码是按照老规范写的,如果我们现在按照新规范,就会在代码仓库里留下两个风格的代码,这样是不是更有问题?

我的观点是,我们要把新规范分为几个层次:

  1. 有很大优势。那我们应该尽快完成代码升级、重构,把这些优势带到我们的产品当中。
  2. 有明显优势,但可能没大到值得延后交付去处理。我们应该在新代码中使用这些规范、在触及老代码时顺手修改,不需要担心两种规范的冲突。截图中大部分都在这个级别,我们应该开始改进,但不需要刻意追求覆盖率。
  3. 优势不明显。那就可以只在新代码中使用,旧代码可以留着不改。
  4. 几乎只是风格问题。那应该在采纳成新规范时做决策。

3. 总结

以上是我在我司最近两周作 Code Review 的经验分享,希望对大家有所帮助。质量和效率、如何还技术债,是软件开发领域永恒的话题,我以后也会继续在这方面展开分享。如果诸位读者老爷有什么想问的、想说的,敬请在评论区与我互动。

我现在在 code.fun 工作,我们的产品会把设计稿自动转换成代码,期望大大提升前端的开发效率,如果你对这个产品感兴趣,也可以联系我。

如果您觉得文章内容对您有用,不妨支持我创作更多有价值的分享:


已发布

分类

来自

标签:

评论

《 “在 Code.fun 做 Code Review” 》 有 8 条评论

  1. aaronlam 的头像

    感谢肉大对目前就职公司内 Code Review 的经验分享,感觉说的很到位,我目前公司的内的项目技术债务也是相当的多,所以非常有感悟!
    我个人目前做开发都是会以层次 2 的方式去推进代码质量的改善。如果采用层次 1 的方式,面对那种动一发而牵全身的代码感觉成本还是很高,即使对原有功能或者日后开发效率有很大改善。

  2. aaronlam 的头像

    肉大,有两个问题想请教一下。
    1. 第一点,如果是 ES Modules 的话不是可以走 tree shaking 把未引入的代码自动剔除吗?还是说,按图上的 import * as 这种再从入口文件导出,就失去了 tree shaking 的效用?
    2. 第三点,这里的意思是只写 is-search-empty 就好了吗?不必再多此一举的这样写 is-search-empty=“true”,对吗?

    感谢!

  3. meathill 的头像

    谢谢好评。回答下两个问题:

    1. 这跟 tree shaking 无关,这里的代码都是要用的,只不过我们希望首次加载尽可能少,而不是一打开页面就加载 10+M,几乎是全部的 JS。
    2. 是的。
  4. […] 如果你看过我的上一篇文章《在 Code.fun 做 Code Review》,其实偿还技术债最好的办法就是写自动化测试,因为只有自动化测试才能告诉你重构有没有引入新问题、能不能上线,优化有没有成功;以及,能否推进下一步重构与优化。 […]

  5. […] 关于 Code Review 的介绍和经验,欢迎大家回顾:在 Code.fun 做 Code Review,本文我就不重复了。 […]

回复 aaronlam 取消回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据