小议前端代码规范
俗话说的好,无规矩不成方圆。
在团队中,代码规范的统一不仅能提高代码质量,对代码的维护者来说也是节省成本的事情。要知道在团队中,我们平常写代码不能仅仅考虑到自己的感受,在业务的更替中,往往维护者也会更替。在业务的交接过程中如何降低交接成本也是很重要的事情,因为我们不可能总是甩手的人,大家往往也是另一个业务的接替者。
因此大家经常谈到编码规范的问题,并探讨如何写出灵活,稳定,高质量和可维护的代码。长此以往也有很多同学总结了一些代码规范,例:[ http://codeguide.bootcss.com/ ],[ http://www.alloyteam.com/2012/07/google-recommends-the-html5-code-specifications/ ],等等。希望以此来规范大家的编码。
但效果可能并不明显。在需求紧张,快速迭代的项目中,大家可能不会也没有时间去遵守一些细节上的规范。这就使得编码规范也就成了纸上谈兵。
于是自动化的规范检查和修改的一些工具也就应运而生了。像JSLint,CSS Lint和ESLint。
这里我们来看看ESLint。
一、什么是ESLint?
ESLint 是鼎鼎大名的 Nicholas C. Zakas 发起的一个开源项目。一个用于识别和反馈代码中模式错误的工具。
对于已有的JSLint,CSS Lint来说,ESLint向前走了几步,这也是Nicholas C.Zakas想要在ESLint中解决的几个问题:
1.单一的运行时环境;
JSHint 和 CSS Lint 都可以运行在 Rhino 和 Node.js中。听起来好像挺不错的样子。但是事实上,要想在两个环境中都良好的运行,要花的时间和测试的成本应该还是挺可观的。
2.规则的开启与禁用;
规则应该有明确的启用和禁用的规则。并且需要有语义的提示。这一点在JSHint做的并不够好。
3.文档;
明确的文档是开发者和使用者的小助手。JSLint 几乎就没有文档,当然JSHint已经改进了些,但在遇到某些问题时还是常常求助无门。所以 ESLint的文档 就相当的完善。
4.规则的配置;
在JSHint中,有些规则要配置true来启用,但是有些却需要配置false来启用,经常会晕乎乎吧。
5.规则的优先级别;
在JSHint中只有error,也就是说你配置了规则,便要要个遵守,因为报了个错嘛。CSS Lint中已经支持了warning,这样更加人性化,因为如果因为空格和tab的冲突而让代码error而不能提交,显得好无语。
6.编写自己的规则;
这就是可扩展性,围绕着ESLint,开发者可以根据自己的需求来开发适应自己业务的插件。
二、ESLint可以为我们做些什么?
1.开始使用ESLint
在我们的项目中使用ESLint只要三步:
1 1.npm install -g eslint; //安装 2 2.eslint --init; //初始化项目,这会让我们回答几个问题,以自动生成初始eslint文件 3 3.eslint app.js //开始lint我们的文件
然后就可以在控制台中看到我们的warnings和errors了。
当然,面对一堆错误和警告,有的可能是分号的问题,有的可能是空格和tab的问题。这对于刚刚开始使用eslint的同学真的很头疼,文件足够大的话,修空格和tab就会让人哭晕在厕所。
不要着急,通过自动fix一些问题,会减轻我们不少的工作量:
eslint app.js --fix
通过执行自动修复,可以把 规则中可自动修复的规则 (这里面的规则中后面括号中是fixable的)给修复掉。
自己试了下,解决了不少编码风格上的问题。
2.ESLint的配置文件
在我们刚刚init的项目的时候,可以看到通过我们回答的问题,eslint会自动生成一个配置文件。
在eslint中,支持几种格式的配置文件,包括:
1 .eslintrc.js 2 .eslintrc.yaml 3 .eslintrc.yml 4 .eslintrc.json 5 .eslintrc
当一个项目中有多个种类后缀的eslintrc文件时,也只会读取其中一种,优先级就是按照上面的顺序。
其实,我们可以在这里看到 ESLint支持的所有规则 。下面我们从一个简单的配置文件看下规则的配置。
这是上面我在自己的一个项目中生成的eslint文件[ .eslintrc.js ]:
1 module.exports = { 2 "rules": { 3 "indent": [ 4 2, 5 "tab" 6 ], 7 "quotes": [ 8 2, 9 "single" 10 ], 11 "linebreak-style": [ 12 2, 13 "unix" 14 ], 15 "semi": [ 16 2, 17 "always" 18 ], 19 // http://eslint.org/docs/rules/no-native-reassign 20 // 不允许 native 变量被重置 21 "no-native-reassign": 1, 22 // http://eslint.org/docs/rules/no-return-assign 23 // 是否允许 return 返回表达式 24 "no-return-assign": 1, 25 // http://eslint.org/docs/rules/no-constant-condition 26 "no-constant-condition": 1, 27 }, 28 "globals": { 29 "KISSY": true, 30 "$": true, 31 "require": true, 32 "module": true 33 }, 34 "env": { 35 "es6": true, 36 "browser": true 37 }, 38 "extends": "eslint:recommended", 39 "ecmaFeatures": { 40 "jsx": true, 41 "experimentalObjectRestSpread": true 42 }, 43 "plugins": [ 44 "react" 45 ] 46 }; View Code
这里一些关键配置的含义大概是这样的:
1 "extends": "eslint:recommended"
eslint有一些推荐的规则,用来捕捉一些比较通用的问题和错误,在后面括号中有recommended字样的 规则 。在配置文件中做上面这个配置,就说明这些推荐的规则全部开启。
1 "env": { 2 "es6": true, 3 "browser": true 4 },
这条配置用于高速eslint你的代码在那个环境中运行。每个环境带有自己一系列的预定义的全局变量。
1 "globals": { 2 "KISSY": true, 3 "$": true, 4 "require": true, 5 "module": true 6 },
用来添加在代码运行时我们允许的额外的全局变量。对全局变量进行约束。
1 "plugins": [ 2 "react" 3 ]
eslint允许使用第三方的变量,我们可以配置在这里。
1 "ecmaFeatures": { 2 "jsx": true, 3 "experimentalObjectRestSpread": true 4 },
eslint允许我们选择性的使用js语言的某些特性。可以通过 ecmaFeatures 来配置
三、小结
纸上谈兵的事情,总是不容易引起注意。
尽管我们可能为了项目的规范制定了一些规则希望大家遵守,但是主观意义上的约束实际上并不靠谱。
借助一些自动化的工具,集成到我们的开发环境中去,是一个不错的选择。
虽然刚刚开始的时候会有些阵痛,但长远来看还是比较有价值的。
四、参考阅读
[ ESLint:The Next-Generation Javascript Linter ]
[ ESLint Doc ]
[ ESLint GitHub ]