前端代码质量管理(一)

导语: 随着业务的增加和开发团队的成员快速增长,其中不少新人来自于五湖四海各大门派,在编码的风格和习惯中也出现各异。 一般在相互 codereview 时发现不少代码上的问题,长此以往代码出现了代码难以维护的问题,甚至还会出现低级错误。 所以,我尝试在前端代码质量的管控上作了些探索,也总结了一些经验分享给你们。
做者:郑振波css

本文大纲介绍

  • 编码规范
  • 冗余文件与代码

1. 编码规范

在一些老项目里咱们常会遇到如下问题:html

编码规范
相信编码规范对于你们来讲不算是陌生,若是在 9102 年再次聊起这个话题,恐怕耳朵会起茧,但编码规范从制定到落地是一个艰难的旅程,特别是对于不一样成员的编码习惯,还有棘手的祖传代码。不管你是老司机仍是新手不妨了解一下。

1.1 编码规范的制定

如何制定编码规范?这是一个永恒的话题,甚至出现过开发者按照本身的习惯和想法不停的去修改 eslint rules,没错,主观性很是强的开发者就会这么干,最后发现 eslint rules 成了一锅粥。前端

若是客观些也许会在这三个方面去思考问题:

  • 兼顾习惯:尽量兼顾团队各成员习惯,人是有个性的,要兼顾彷佛不大可能。
  • 规则从严:规则越严格越好,也毫不让他松散无约束。
  • 投个票:投票彷佛是最民主的决定,但每每最具争议的 rules 会出现票数差别不大。

若是你能从以上三个方法中取得成果,那说明你是老板,这一切就会变得太简单了。但不管如何,每个被扩展的 rule 都能找到具支持点和反驳点,在制定规范时同窗们一般每每会在几个点去发表他的意见:node

  • 习惯:“我一直都这样干,没问题”
  • 业界标准:“你去看某某大公司的开源代码吧”
  • 必要性:“行尾不加分号我从没见过跑不起来的JS”
  • 耗时:“按一次 tab 比按两次 tab 省时省力;行尾加分号简直浪费生命”

1.2 在编码质量和编码效率之间取得平衡

有没有办法能够解决这些争论?怎样取得平衡?开源社区各团队开源出的 eslint rules 能够说是遍地开花,prettier,eslint-config-standard,airbnb 等等,在编码规范选型时应该考虑如下几点:webpack

  • 适合项目的技术选型:好比咱们的团队技术栈使用了 React 、Node.js,ES6,那么就能够很清晰地知道怎么选择方向了。
  • 社区承认度高:相信社区争论程度不亚于团队成员,若是一个规范获得 stars 超过 1w,已是很了不得的事情了。
  • 是否有插件支持:可以支持 ESLint,JSCS 等。

基于以上标准,咱们选择了超过 8w + 由 airbnb 前端团队维护的 eslint rules。 标准制定后, 如何让团队成员快速适应起来?git

  • 配置编辑器:若是使用 VSCode,能够配置 "eslint.autoFixOnSave": true,这样保存代码时会自动根据 eslint rules 去 fix 代码,同窗们就很舒服了。
  • 编辑器插件:若是使用 VSCode 能够安装 Eslint 插件,这样能够实时提示不规范的代码。

  • 构建时提示: 若是使用 webpack ,可使用 eslint-loader,再配合 eslint-friendly-formatter 能够给到开发者很好的提示。能够参考该文章 webpack引入eslint详解

这样 eslint 规范就初步落地了。github

1.3 整改祖传代码

定制好规范并落地后,如何对于祖传代码怎么办?因而咱们又遇到不一样的声音:web

  • 这代码不是我写的:”谁写谁来 fix 啊“
  • 我不敢改: “改出问题要背锅怎么说”
  • 下次再改:“赶时间发布呢,要不就下次再改”
  • eslint-disable:“disable 大法好,没有东西能够拦住我了”

如下是咱们对祖传代码的整改之路: 首先要看看问题有多严重:npm

npx eslint src
复制代码

eslint errors
25W+ Eslint 报错,这不知道要改到什么猴年马月了。

1.3.1 添加 .eslintignore 文件,排除第三方 js 文件

但通过排查发现,这里面大部分报错是来自于第三方库,但又不是 npm 包,这些文件每每是不能知足当前的编码规范的,而且有部分是通过代码压缩,更不该该走 eslint 检查。屏蔽掉第三方文件的检测后,剩下的 eslint errors 还有 2w+,错误归类: json

eslint errors
能够发现错误类型最多的是换行符。

1.3.2 关于CRLF

在文本处理中,各操做系统也是有本身的一套标准:

Dos 和 windows 采用“回车+换行,CR/LF”表示下一行; UNIX/Linux 采用“换行符,LF”表示下一行; 苹果机(MAC OS 系统)则采用“回车符,CR”表示下一行。

因此,若是团队中还有 windows 玩家那么建立文件的换行符就是 CRLF,这也谈不上是什么很大的缺点,但在若是赶上了 Vim 或 Emacs 玩家打开文件就会看到这样的状况:

每行后面会带上个 ^M。为了维护代码世界的和平,一般须要统一转换为 LF 换行符:

  • 设置 IDE 换行符,如 VSCode:

  • VSCode 默认配置:文件 - 首选项 - 设置 -搜索:默认行尾字符。修改成 \n
  • EditorConfig: 若是你的项目中有 EditorConfig 那就更好了:

#Unix-style newlines with a newline ending every file [*] end_of_line = lf insert_final_newline = true

  • 配置 git config:能够在 git commit 时把代码统一转为 LF,那么能够了解一下 git config core.autocrlf ,也许你会见过这个配置,但不必定正确使用,其实他有3个值可配置:

ture: git pull 时会把 LF 结尾转为 CRLF false: git pull 时不作任何转换 input: git pull 时会把 CRLF 转换为 LF

那么这里应该使用的是 git conifg core.autocrlf input 以上任何一条均可以解决你的换行符问题。

1.3.3 自动修复

解决好这一切以后,能够尝试让 ESLint 自动修复一波了: npx eslint src --fix

自动修复后还有 800+ ESLint 报错,因而打开这些代码 review 后,发现有不少问题,觉得规范人人都懂,正如那句电影台词**“听过不少道理,却依然过很差这一辈子”**。
这些都是很低级的错误,若是你尚未使用上 ESLint 那最好别太相信本身的代码。

1.3.4 按期整顿

800+ 的错误分布在各个页面,能够给团队成员每人分配几个页面修复并分批上线,这样大规模的修复最重要的是发布后的监控:

发布后监控

1.4 曾经觉得 ESLint 是万能的

也许你会认为 ESLint 没有报错那就 O**K了,其实坑每每没那么容易被发现,就像下面这个例子:

这里提示 绝对路径的引入应写在 相对路径引入的前面,因而快速改他一波:
这里就有问题了,你看出来了吗?应该怎么改?

1.5 守住规则

咱们通过制定规范,代码整改,接下来须要守住规则,不然一切徒劳

  • git hook:可使用 pre-commit,husky 等工具来配置 git 钩子,配合上 npm script 能够作到在提交代码前执行 eslint 命令来检测变动文件是否符合规范,不然 exit 非零值来终止 git commit。但在前端使用 git hook 缺点也是有的,好比每次提交代码都要等待 eslint 一遍,致使开发体验大大降低;也会出现有同窗自行删除 pre-commit hook 文件来绕过检测的状况;也能够经过添加 --no-verify 来关闭检测。
  • web hook:好处是使用服务端来作校验,没法在前端绕过,缺点是须要使用服务器资源。关于如何搭建 web hook,能够参考这篇文章

1.6 关于前端代码规范的其余思考

以上提到的是关于 JS 代码规范的内容,对于 CSS 也可使用 stylelint 来作规范检测,但这些更多的是对代码的格式作规范,若是想把代码写好 ESLint 之类的并非全能的,好比代码的整洁之道,这里列举了很多能够参考的范式,恰又是 ESLint 没法帮你 hold 住的点,因此 ESLint 并非万能的。

2.冗余文件与代码

2.1 关于冗余文件

也许你会认为冗余文件是一个问题,但他不是一个很关键的痛点,若是你的团队追求极致,有很是的代码洁癖,那么冗余文件也应该重视起来。即便你是一名老鸟,也有可能产生冗余文件。

2.2 为何会产生冗余文件

在代码的迭代过程当中,每每容易忽略删除相应的文件,大概有两种场景: 一、删除 JS 代码中的 require,却忘记删除相应的文件(img/css/js/etc.)。 二、删除 CSS 中的 background ,忘记删除相应的图片文件。 删除代码很痛快,只要页面刷新一波没有报错就以为 o**k 了,日积月累的冗余文件慢慢让整个仓库愈来愈大。

2.3 清理冗余文件

若是使用 webpack 构建,那就能够很方便地分析出整个项目的依赖关系。 第一步:在根目录跑命令,把文件的依赖关系导到 stats.json 中,这个步骤耗时略长,我在项目中跑了一次,1420 个文件耗时 35s。

webpack --json > ./stats.json
复制代码

第二步:使用 glob 获取目录下的全部文件路径:

glob('!(node_modules)/**/*.*')
复制代码

结合第一步生成的 stats.json 能够过滤出未被引用的文件。

2.4 冗余代码

2.4.1 关于冗余的 CSS

要分析项目中冗余的CSS,实际上是比较困难的,主要缘由有 3 个方面: 一、页面的元素或组件的嵌套:致使没法只从静态分析的层面上判断样式是否有做用于对应的元素上。 二、样式的全局做域:a.css 中声明一个样式,他能够做用于页面上的任何一个 dom,这样分析起来要遍历项目中全部的 dom 和 css,一个样式的声明须要检查全部的 dom,若是有N个样式声明那将会有很是大的计算量。 三、css 没有约束: 多个 css 文件的样式也能够做用于一个 dom 元素上,由于每每会用到开源的 ui 库,会根据设计的要求对相应的 dom 元素作样式覆盖,因此这种过于灵活的特性带来的不可控形成难以管理。

2.4.2 解决冗余的 CSS

CSS Modules 能够把 css 做用域收敛,能够显式声明哪一个 class 样式做用于 dom 上,能够保证某个组件的样式不会影响到其余组件:

样式与 dom 造成了强依赖关系,这样就能够便于作静态分析,能够借助 eslint-plugin-css-modules
若是 scss 里面存在未使用到的 className,会获得提示:
若是在代码中使用了未定义的 className,也会有提示:

2.5.1 关于冗余的 JS

在代码迭代中,颇有可能删除掉一些方法的使用,那么会在 Class 留下一些多余的方法,这些也是难以经过 eslint 来检测到的,由于没办法判断这些方法在实例化后,是否会在某个时刻被使用到。若是要找出这些冗余的方法,也须要从整个项目开始分析全部 JS 的依赖关系,那么计算量就会很是大,而且很耗时。

2.5.2 尝试解决冗余的 JS

目前没有什么好的办法来解决这个问题,或许能够经过两种方式来分析出来: 一、命名约定: 好比如下划线开头的方法是私有方法,那么就能够只针对本文件全部的私有方法是否被使用来作分析了。 二、注释标记:若是不喜欢下划线的方式,那么也能够考虑添加注释来标记。

2.6 冗余文件/代码 小结

一、删除代码要留心 二、分析冗余 三、合理运用工具 四、发布后监控

相关文章
相关标签/搜索