对于中大型前端项目,项目规范与代码质量尤其重要。当功能需求变动或须要重构时,为所欲为的(糟糕的)代码可能带来比从新开发还麻烦的问题。javascript
这个问题不用做过多阐述,想必接手过他人代码的同窗,多少都有些体会。简单来讲,太过随意的代码会让强迫症患者难以容忍,难以阅读理解的代码有时甚至不如推倒重来。css
什么样的代码是低质量或高质量的?好的代码可能会让你如读小说通常被吸引,糟糕的代码会让你看一眼就不想继续、甚至看半天而不知所云。html
有人可能认为初级程序员才会有这种问题,其实否则,一些工做经验两三年的同窗写的代码依然如此。对于一些我的自学意识不够积极、没有团队规范性指引的同窗,很容易习惯成“学习半年、而后重复三年无长进”的状况。前端
拿出来你可能不太愿意相信,下面这些例子即来源于真实项目。你能尽量地找出其中存在的各类问题吗?vue
图1java
图2node
图3git
图4程序员
图5es6
图6
图7
以上只是截取的一些很简短的列子,那么涉及大块复杂逻辑的地方会是怎样的,试试发挥一下你的想象力。
这种问题实际上是很是广泛的。一个函数几百行、一个文件数千行、一个类几十个方法、方法参数定义随意、没有任何注释、方法与变量命名无明确的语义、数据修改与变动穿插在各类方法中等等。 这样的编码方式,你要去理解它的逻辑每每真的很难,通常只能一块块一行行的去作阅读理解(可能还会开启边看边骂娘模式)。
这主要缘由在于开发者我的的基础知识能力、编码经验和意识等的不足。
其实针对这种状况,常见的开源的编码规范都会有所说起。个人建议是这些同窗应该好好温习一下面向对象编程、函数式编程、数据结构、常见设计模式,看一看各类开源的编码规范并尝试去真正的理解它们。当你回顾一个月前的代码时,发现能够改进或重构使得编码逻辑更为简洁清晰,说明你是在成长与进步的。
常常看到各类社区中都会有同窗问这类问题:新项目正在选型,Vue.js、React、Angular 三大框架哪一个合适?其实团队开发成员对这些都比较有经验,哪一种均可以;若是团队成员前端开发经验大都不是太丰富或人员不够稳定,选择 Vue.js 最适合,为何?由于它更简单简洁,容易上手。Vue.js 经过 prop、data、computed、method、watch 等各类钩子,必定程度上限定了编码方式与风格,使得初级开发者写出来的代码也不会太难看,这也是它愈来愈受社区推崇的缘由之一。
如何保障前端项目的编码质量呢?依我看来能够从这几个角度考虑:制定编码规范、开发工做流 lint 风格强制检查、按期 Code Review、单元测试。
团队协做项目中,编码规范尤其重要。对于初级程序员,因经验欠缺,编码规范的要求能够避免许多低级问题的产生;对于多人团队来讲,风格一致的编码约定,在协做开发、代码移交等时,能够在很大程度上下降风险和成本。
那么编码规范应当如何制定?
没有最好的风格,只有团队认同的一致性约定。通常来讲能够由团队负责人牵头制定,成员提意见补充,最后落地成团队规范并严格执行。业界有不少优秀前端团队开源的规范可供参考。如:
学习编码规范约定是有必要的,但你能在看完后并真正的理解它们吗?
在开发工做流中引入工具辅助,能够强制性地实现编码书写和提交过程当中的 lint 校验。能够怎么作?条条大道通罗马,下面以当前流行的 Git Hook 方案举例供参考。
咱们在项目中配置 TSLint
插件以校验 typeScript
;配置 styleLint
插件以校验 CSS/LESS。
咱们约定团队开发均采用 vscode
编辑器,并至少安装如下插件辅助开发:
因为不一样开发者可能使用的编辑器不一样,但各类编辑器基本都支持 .editorconfig, 故每一个项目都应当包含 .editorconfig
,用来统一配置编辑器的换行、缩进存储格式。
配置参考:
# http://editorconfig.org root = true [*] indent_style = space # 输入的 tab 都用空格代替 indent_size = 2 # 一个 tab 用 2 个空格代替 # end_of_line = lf # 换行符使用 unix 的换行符 \n charset = utf-8 # 字符编码 utf-8 trim_trailing_whitespace = true # 去掉每行末尾的空格 insert_final_newline = true # 每一个文件末尾都加一个空行 [*.md] trim_trailing_whitespace = false # .md 文件不去掉每行末尾的空格 复制代码
借助 Git Hook
,能够在提交代码时执行风格检测与修正,当存在没法经过的内容时,提交会被 block,从而实现编码规范的强制性执行。
能够利用如下几个工具来实现这个流程:
husky
它会安装一系列 git hook 到项目的 .git/hook
目录中,这些钩子能够检测 package.json
中的 scripts
脚本命令配置,并在代码提交时执行它(咱们这里利用 pre-commit
钩子)lint-staged
能够取得全部被提交的文件并依次执行配置好的任务命令styleLint/TSLint/ESlint
各类 lint 校验工具,能够配置到 lint-staged
的任务中prettier
配置到 lint-staged
的任务中,能够实现修正可自动格式化的编码风格package.json
中的相关配置信息参考:
{ "scripts": { "precommit": "lint-staged", }, "lint-staged": { "*.ts": [ "tslint --fix", "prettier --parser typescript --single-quote --print-width 120 --write", "git add" ], "*.less": [ "stylelint --fix", "prettier --parser less --print-width 120 --write", "git add" ] }, "devDependencies": { "husky": "^0.14.3", "prettier": "^1.13.5", "prettier-stylelint": "^0.4.2", "stylelint-config-standard": "^18.2.0", "stylelint": "^9.4.0", "stylelint-config-prettier": "^4.0.0" } } 复制代码
.prettierrc
配置文件参考:
{ "singleQuote": true, "trailingComma": "es5", "printWidth": 120, "overrides": [ { "files": ".prettierrc", "options": { "parser": "json" } } ] } 复制代码
.stylelintrc
配置配置参考:
{
"extends": [
"stylelint-config-prettier",
"stylelint-config-standard",
"./node_modules/prettier-stylelint/config.js"
],
"rules": {
// 定义一些适合团队约定的规则
}
}
复制代码
经过以上配置,当代码提交时,会在 pre-commit
阶段执行 .git/hook/precommit
钩子,该钩子会查找并执行 scrpits
中的 precommit
命令,因而 lint-staged
定义的任务会被逐个执行。这套方案也是当前比较流行的作法,在不少开源项目中都有所应用。
拓展阅读:
编码规范与 lint 检查只能让你们的编码风格保持一致性,却没法避免低质量输出的问题。而这种问题对团队和产品来讲每每倒是致命的。
低质量的代码不只仅只是会制造各类低级 bug,让测试同窗测到没脾气,对产品来讲,可能很小的需求改动却须要代码有巨大的变更,致使产品迭代周期被潜在地延长。另外,当你们的精力老是聚焦于需求开发和 bug 修复时,产品设计的细节就顾不了那么多了(别跟我说什么精益求精,赶时间解决完 bug 就烧香拜佛了),这对产品体验来讲也是很要命的。
什么样的代码是好的,什么样的代码是很差的?这来源于知识的学习运用和开发经验的日积月累。低质量的编码说到底仍是经验不一样、水平存在差别。对于我的来讲要经过不断的学习积累自我提高,对于团队来讲进行 Code Review 评审是有必要的。
那么 Code Review 应当如何进行?
Code Review 的形式能够多种多样。如 GitHub 上许多流行项目采用 PR(Pull Request) 工做流的方式,一个 PR 至少通过三人次 review 经过才能合入,这能从流程上较好地保障项目代码质量。在有的开发团队或企业,会引入 gerrit 这种代码审核平台,过程与此大体类似。但对许多快速迭代的业务产品开发团队来讲,这种须要多人评审经过的模式都不太适合:人力有限、时间紧迫、顾不了那么多了,因而即便 gerrit 也流于形式,编码质量只能落到开发人员我的的肩膀上。
相比较而言,按期进行小组讨论形式,问题的提出能够获得快速反馈和总结,这会让你们更有动力一些。
通常来讲团队内有新人入职,基本的 Code Review 是有必要的,这时候编码规范与风格是 review 的重点。当你们对常见的基本问题都有了比较一致且明确的认识后,探讨交流学习则会逐渐成为 Code Review 的主要内容。
对于内部交流氛围浓厚的团队,能够鼓励成员之间互相审阅提交的编码。对大多数团队来讲,能够这么来作:主要负责人以抽查浏览的形式快速审阅成员提交的代码,发现有问题的地方提出并打回改进(问题较多的同窗的代码应重点关注);团队按期(能够是每周)以例会讨论的形式,对一周提交的代码进行抽样和总结式评审,学习好的编码方式、探讨很差的编码的理由,甚至进而沉淀出适合团队的编码约定。
另外注意一点,Review 过程的操做方式和表达用语很是重要,应当是轻松的沟通交流学习的方式,不要把 Code Review 执行成了批判会。
拓展阅读:
前端项目写单元测试,对不少人来讲是不肯意的,由于编写过程太过复杂。但基本的单元测试是能够写的,公共方法和组件的修改可能会为某些调用模块制造潜在的 BUG,良好的单元测试能够在出现问题时快速反馈出来。
咱们当前对项目单元测试的基本要求是这样的:
Vue.js/React/Angular 三大框架都有完善的单元测试实现体系,在项目中引入单元测试的成本并不高,高的是测试代码编写的过程。在某些状况下我认为这种“高成本”是值得的。另外需注意,单元测试的执行必定要与 CI 集成,才能真正发挥它实时性反馈问题的做用。
JavaScript 是一种语法简单使用灵活的弱数据类型语言,而正是这种过于灵活的特性,使得开发者可以任性地书写,但任性是须要成本和代价的。
有时会看到一些后端同窗会说,前端看上去也没那么难嘛,我只学了一天就开始上手撸代码了。他们或许说的没错,可是有经验的前端同窗去看一下他们此时产出的代码,每每都会表示不忍直视。许多前端开发的同窗并不是计算机相关专业出身,没有太多相关的基础理论知识做为背景,刚开始干活时在代码输出上“为所欲为任意妄为”的状况更为广泛。
TypeScript 和 Flow 近两年来愈来愈火热,几乎当前流行的前端开源产品都在转向使用它们,这足以体现它们存在的重要价值。静态检查语言在编码阶段便可检测并提示出潜在的类型引用风险,能够在很大程度上避免许多因粗心、误用带来的逻辑 bug。良好的类型定义会使得项目模块逻辑结构更为清晰可控。借助编辑器强大的类型提示功能,代码编写甚至无需看详细文档便可快速了解用法。特别是中大型的复杂项目,选用它们绝对是利大于弊。
对于产品质量而言,监控体系是很是重要的一部分。对于前端来讲,能够经过设计网站埋点统计平台来收集页面信息,如脚本报错、页面性能卡顿等问题,基于统计信息回溯分析问题根源,进而进行问题修复和代码改进。固然统计数据的做用毫不止这些,这里不做过多的扩展讲述。
拓展阅读:
关于前端编码质量,你有哪些经验体会呢?欢迎来一块儿探讨交流。