JavaScript 代码静态质量检查

jopen 9年前

自鸿蒙初判,Brendan Eich 10 天捏出 Mocha 之后,即便进化成 EcmaScript,这个语言依旧毁誉相随。那些经过重重劫难,侥幸渡劫成功的苦主标识了诸多天坑(见 JavaScript Garden) —— 当然,你也可以称之 feature。据无责任乱猜,Douglas Crockford 也没少踩坑,于是才有了蝴蝶书《JavaScript: The Good Parts》,下雨天与JSLint一起使用会更配哟。

JavaScript 代码静态质量检查

《JavaScript: The Definitive Guide》 V.S. 《JavaScript: The Good Parts》

时至今日,代码的静态质量检查在项目质量保障方面的重要性与必要性已毋庸置疑。越来越多的开发者意识到了这一点,纷纷在项目构建流程或者源码控制系统中添加静态检查的hook。本文将依时间顺序,选出JavaScript史上的主要几个Linter作横向比较,最终属意谁家,那就见仁见智了。

JSLint

JSLint的名字源于早期用于检查C语言代码质量的Lint,老道把认为非Good Parts、有陷阱的部分全部报 warning,而且绝不允许妥协(当前版本已经允许部分的可配置项),固执得令人心疼。

虽然这个在 2002 年的 JSLint 代表着先进的方向,但是前端的发展一日千里,严格不妥协的JSLint开始阻碍前端的发展 —— 例如函数内变量全部集中在顶部定义,推荐一个var定义多个变量等。最最最重要的是,老道拒绝开源JSLint(无责任乱猜,也许JSLint的实现代码违反它自己制定的规则)。

截止 2015年6月9日,JSLint仍然在更新,官网上写着 JSLint edition 2015-06-02 BETA,固执的老道。

JSHint

鉴于JSLint的现状,Anton Kovalyov 以JSLint为蓝本,在社区力量的帮助下实现了开源的JSHint。

相较之下,JSHint更友好,可配置性更高。由于大家受JSLint的压迫太久,而且得益于开源的优势,风头很快盖过JSLint,一时无两,获得大量 IDE/Editor 的支持。然而成败萧何,JSHint的成功源于对JSLint的改进,但同样继承了JSLint的诸多缺点,比如不易扩展,难以根据报错信息定位到具体的规则配置等。虽然有专门的文档说明,但是修复的成本仍旧不低,于是出现了 JSLint Error Explanations 这样的网站,针对JSLint/JSHint/ESLint报的错误作修复说明 —— “啪啪”,这对JSHint团队来说无异于打脸。

JSHint团队也逐渐意识到这个问题的重要性,2012 年时曾有 讨论 使用esprima生成 AST(见 jshint-next,提示该项目已过期,已 merge 到主项目,但在 2013/5 又从主项目移除,现已难觅芳踪,原因未明),并有专门针对JSHint的 warning 作修复的 fixmyjs

Closure Linter

Closure Linter属于Closure家族成员,源于 2004 年的Gmail项目,最初只是内部使用,后来觉得应当兼济天下,于是在 2007 年后作为Closure Tools系列开放给外部使用。Closure Linter主要是按照《Google JavaScript Style Guide》来作检查与修复。限于Closure的家族特性,使用范围并不大。

JSCS

自Marat Dulin于2003.6.17日凌晨发布第一个版本开始,JSCS就专注于代码风格层面的检查,这点从它的名字JSCS - JavaScript Code Style中可窥一斑:

JSCS is a code style linter for programmatically enforcing your style guide. You can configure JSCS for your project in detail using over 90 validation rules, including presets from popular style guides like jQuery, Airbnb, Google, and more.

再看它的package.json中的依赖包:

"dependencies": {   "esprima": "^1.2.5",  "esprima-harmony-jscs": "1.1.0-bin",  "estraverse": "^1.9.3",  } 

可以发现它使用了esprima生成 AST,再通过estraverse遍历作检查,因此性能上会逊于JSLint与JSHint,但是带来的收益是易于维护和扩展,相对于性能上的损失,是完全值得的。另外,JSCS可通过esprima-harmony-jscs实现对ES6的支持,并且自带错误修复技能。

JSCS与JSHint份属同盟,互相使用对方作本项目的代码检查。

ESLint

无独有偶,同样是源于对JSLint与JSHint的不满,Nicholas C. Zakas 也在JSCS发布的当月开始造另一个新轮子 ——JSCheck(浓浓的山寨感扑面而来有没有),不过几天后即更名为ESLint—— 再次表明,好名字重要性。

功能方面,ESLint可以简单的理解成JSHint + JSCS,基本上集成了两大基友的优点。ESLint在初期也是依赖于esprima生成 AST,后来为提高对 ES6 的支持,换成esprima的分支版本espree。然而,espress对 ES6 的支持仍然很有限,不过好在还有 Babel-ESLint

总结

如果你是老道的死忠粉,无条件同意他关于 JavaScript 的一切观点,那么JSLint是你的不二选择。只要把 老道 换成 Google 成立,JSLint换成Closure Linter同样成立。

如果你有良好的单元测试作后续的质量保证,或者只 care 代码风格方面的问题,那么JSCS就完全胜任。

如果你要求不高,更注重开发工具和环境的支持,还想顺便检查一下 HTML 代码中的inline script,严重推荐JSHint。得益于它的高普及度,即使官方文档有隔靴搔痒的无力感,在社区的帮助下也能很快的解决你的问题。

如果你的要求非常高,为团队制定规范非常详细,并且不满足于JSHint与JSCS的组合,不妨试试ESLint。严格的贡献参与流程,快速的响应以及丰富的文档都不过是它诸多优点中的冰山一角。

你还要检查 CSSHTML,甚至还有 Less? 也许只有fecs可以拯救你于水火,至于fecs是什么,那是另一篇文章的内容了。

补充

行文未完,微博发现已有类似的比较: A Comparison of JavaScript Linting Tools,可作参考。

来自: http://efe.baidu.com/blog/js-lints/