玩转Grunt(三): JSHint静态代码检查

在这篇文章中让我们来看一下JShint静态代码检查工具以及它如何与Grunt集成。

1. 静态代码检查

静态程序分析(Static program analysis)是指在不执行计算机程序的条件下,进行程序分析的方法。-wikipedia

静态代码检查通过分析程序的语法、结构、调用流程等来检查正确性、是否满足编写规范,找出其中可能隐藏的错误与缺陷,比如错误的逻辑表达式,比如程序中不安全不明确模糊的调用部分,eval,比如无用的代码、比如死循环,比如复杂的代码嵌套等。统计证明,在整个软件开发生命周期中,30% ~ 70% 的代码逻辑设计和编码缺陷是可以通过静态代码分析来发现和修复的。

2. Javascript中静态代码检查工具

基于Javascript语言的特性,很多tricky的问题让人抓狂,不正确的使用会导致不可预测的bug,比如==比较操作,所以静态代码检查工具显得尤为重要。另外从代码规范检查角度来讲,可以有助于项目保持统一的编写风格。

在Javascript语言中谈到静态代码检查就不得不提到JSLint和JSHint,其中JSLint是Douglas Crockford编写的,将他认为的那些重要的js编程实践作为静态检查项,但是因为JSLint相关检查项过于严格,无法妥协,JSLint的使用程度并不如想象中的广泛。

JSHint就是在这样一种社区驱动的情况下出现的,是轻量级的JSLint,可以自定义检查选项,相对比较灵活。它的源代码是fork自JSLint,可在Github JSHint找到。它的检查选项主要分为四大类,语法约束、代码风格、代码复杂度和环境相关的选项(e.g.全局变量)。

3. 常用的JSHint选项

名字 说明
bitwise = true 禁止使用位运算符
camelcase = true 强制变量名为驼峰式
curly = true 强制代码块有大括号
eqeqeq = true 强制===和!==
immed = true 禁止无括号调用函数
indent = true 强制代码缩进
latedef = true 禁止使用未声明的变量
newcap = true 强制构造函数名称大写
noarg = true 禁止arguments.caller和arguments.callee
noempty = true 强制无空代码块
undef = true 禁止使用显示的未声明的变量
unused = true 警告未使用的变量
strict = true 严格模式
trailing = true 禁止以空格结尾
asi = false 警告缺失分号
boss = false 使用条件判断而不是赋值语句
evil = false 警告使用eval
lastsemic = false 分号
laxbreak = false 多行字符
laxcomma=false 以逗号开头的多行字符
loopfunc=false 警告在循环中定义function
smarttabs=true 隐藏关于tab与空格混合的使用
maxcomplexity 最大圈复杂度
maxdepth 最大嵌套深度
jquery 允许jquery全局变量
global 定义允许的全局变量
-W026=true 内嵌的函数应该放在包含的方法的顶端

更多的选项以及解释可参见我翻译的JShint在线文档,另外也可参照JSHint内置的警告和错误码增添警告和错误码的配置,如例子中的w026,

4. How to enable JSHint

有两种方式,第一,是安装JSHint的命令行工具;第二,与Grunt集成。

4.1 Install JSHint CLI

JSHint有一个命令行的程序,是npm的一个模块,可以通过以下方式安装jshint。

npm install jshint -g

具体可参见我翻译的JSHint在线文档

4.2 与Grunt集成

需要使用grunt-contrib-jshint帮助集成jshint到Grunt。具体安装方法和其它插件一样,这里就不详述了,可以参见第一篇Grunt的博客

4.2.1 安装

npm install grunt-contrib-jshint –save-dev

4.2.2 配置JSHint选项

目前Grunt文件中JSHint任务的options与.jshintrc中的选项是不能互相merge的,所以一种可以将JSHint的选项定义在jshint构建任务的options中,另外一种是配置jshintrc选项指定jshint的配置文件,在这里采取第二种。

config jshint
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

module.exports = function (grunt) {
'use strict';


grunt.initConfig({
// task configuration
pkg: '',
jshint: {
options: {
'jshintrc':'.jshintrc',
'reporterOutput': 'jshint.text'
},
all: ['app/js/**.js', 'app/lib/**.js']
}
});

// Load the plugin
grunt.loadNpmTasks('grunt-contrib-jshint');

// Default task(s)
grunt.registerTask('default', ['jshint']);
};

配置完后在命令行运行 grunt jshint,就可以得到jshint的检查结果,包括行号,错误码以及原因,一目了然。
{:height=”300px” width=”400px”}

4.3 Report

JSHint的输出结果可以自己定制,也可以选取缺省的report工具,诸君如果感兴趣可参考Writing your own reporter或者jshint-path-reporter

5 参考

  1. shttp://jslinterrors.com/
  2. http://anton.kovalyov.net/p/why-jshint/
  3. http://www.elijahmanor.com/2012/09/control-complexity-of-your-javascript.html
  4. http://xianjing.github.io/blog/2013/10/16/jshint-doc/
  5. http://xianjing.github.io/blog/2013/10/21/jshint-options/
Share Comments