什么是静态检查
距离上次写三分钟从零单排(三分钟从零单排gulp-less配置) 的文章过去好久了,这次来聊一聊静态检查。
因为现在正在带学生的js基础课,开始写一些整体项目了。日常遇到很多关于缺少括号,多写了一个点,变量没有声明诸如此类的错误。
而且在编程界一直有一个神秘的现象,就是越简单的bug就越难找到。那种死都改不好的bug基本都是一眼就看的出来,一个小时都找不到的错误,八成是一下子就改好的。从上学的时候就发现了这个规律,所以一旦找了很长时间都找不到bug在哪,赶紧把自己切换到白痴模式,很快就能找到错误。
但是对于新人来说,每天都会犯很多语法细节的错误,并且在其中浪费大量的时间。有很多时候,明明只是一个括号匹配的小问题,结果为了找出来问题就反复修改调试了好几处代码,最后反而把好用的代码改坏了,人也很烦躁,觉得很有挫败感。
当然,静态检查不仅仅是帮助初学者进行学习,对于我们日常工作来说,避免一些小错误也是很有效的。另一个重要的用途是,保持团队的代码风格一致,使得提交git的时候可以避免很多不必要的修改行出现。
所以无论是从学习的角度,还是从团队开发的角度来说,静态代码检查都可以有效的提高开发效率。
Sublime插件
因为我的日常使用Sublime作为开发工具,所以用Sublime的使用举例说明。
首先要安装两个插件:
SublimeLinter
和 SublimeLinter-contrib-eslint
SublimeLinter
是一个可以支持sublime使用各种静态检查工具的工具,可以配置触发条件,显示样式,以及使用什么工具做静态检查。
什么,你问我怎么安装插件?
1、通过快捷键 ctrl+` 或者 View > Show Console
菜单打开控制台
2、粘贴对应版本的代码后回车安装
适用于 Sublime Text 3:
import urllib.request,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib.request.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read())
适用于 Sublime Text 2:
import urllib2,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp)ifnotos.path.exists(ipp)elseNone;urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read());print('Please restart Sublime Text to finish installation')
当安装好SublimeLinter
之后,就可以在Tools > SublimeLinter
看到插件的配置项了。
包括检测模式,报错信息样式,切换检测器等各种配置。所有的配置通过打开Open User Settings
都可以看到。
因为现在还没有任何的检测器,所以还无法工作。
可选用的静态检测的工具有eslint
jshint
jslint
JSCS
等。
JSLint
JSLint是其中最老的工具。在2002年 Douglas Crockford开发了该工具,根据其经验,强制使用js语言中精粹的部分。如果你同意这些精粹,JSLint能成为一个好的工具。
JSLint的缺点是不能配置和拓展。你根本不能禁掉需要特性,并且很多缺少文档。官方文档非常不友好,例如缺少如何将其集成到编辑的信息。
JSHint
作为一个可配置的JSLint版本,JSHint被开发出来。你可以配置每个规则,将其放到一个配置文件中,这样在大项目中可以容易使用。JSHint对每个规则有好的文档,所以可以准确知道每个规则的作用。将其集成到编辑器也是简单的。
ESLint
ESLint是最新出来的工具。它被设计的容易拓展、拥有大量的自定义规则、容易的通过插件来安装。它给出准确的输出,而且包括规则名,这样可以知道哪个规则造成了错误。
横向对比之后,我们选择用ESLint作为静态检测的工具,于是我们还需要插件:Sublime-contrib-eslint
。
这时候打开 Tools > SublimeLinter > Open User Settings
可以看到,linters
配置项已经有了eslint
所以看起来好像已经可以了呢,赶紧迫不及待的打开一个js文件,结果却什么都没有显示,我们用ctrl+`打开控制台看一下,发现有报错
原来是eslint
没有安装,需要手动安装eslint
包,打开cmd
,输入:
npm i eslint -g
全局安装eslint之后重启一下SublimeLinter,结果发现,妈的还是不好使……
再次使用ctrl+`打开控制台,这次说明错误的原因是没有eslint的配置文件。
ESlint 被设计为是完全可配置的,这意味着你可以关闭每一个规则,只运行基本语法验证,或混合和匹配绑定的规则和自定义规则,以让 ESLint 更适合于你的项目。有两种主要的方式来配置 ESLint:
Configuration Comments - 使用 JavaScript 注释把配置信息直接嵌入到一个文件
Configuration Files - 使用 JavaScript、JSON 或者 YAML 文件为整个目录和它的子目录指定配置信息。可以用 .eslintrc.* 文件或者在 package.json文件里的 eslintConfig 字段这两种方式进行配置,ESLint 会查找和自动读取它们,再者,你可以在命令行指定一个配置文件。
其实对于SublimeLinter来说,还有一种一劳永逸的方法,就是把配置文件写在插件设置中
"linters": {
"eslint": {
"@disable": false,
"args": [
"--config",
"${sublime}/user/eslint.conf"
],
"excludes": []
}
}
其中${sublime}/user/eslint.conf是配置文件的路径,${sublime}在我的电脑上路径是C:\Users\USERNAME\AppData\Roaming\Sublime Text 3\Packages
以下是我在使用的配置文件:
{
"env": {
"browser": true,
"node": true,
"es6": true
},
"globals": {
"jest": true,
"describe": true,
"it": true,
"expect": true,
"$": true,
"require": true,
"define": true,
"module": true,
"MZ": true,
"console": true,
"window": true,
},
"rules": { //0 关闭,1 警告,2 错误
"block-scoped-var": 0, //把 var 语句看作是在块级作用域范围之内
"curly": 1, //为所有控制语句指定花括号约定,警告
"eol-last": 0, //强制文件最后一行为空行,关闭
"eqeqeq": 1, //- 要求使用 === 和 !==
"dot-notation": 2, //尽可能的使用点符号
"no-console": 0, //不允许存在 console。关闭
"no-empty": 1, //空的代码块
"no-self-compare": 1, //禁止自身比较
"no-shadow": 2, //定义的变量不允许已在外层作用域定义
"no-undef": 2, //变量未定义
"no-underscore-dangle": 0, //禁止标识符中有悬空下划线。关闭
"no-unused-expressions": 1, //禁止在语句的位置使用表达式
"no-unused-vars": [1, {"vars":"local"}], //变量定义后未使用
"space-infix-ops":2, //要求操作符周围有空格
"no-use-before-define": 1, //不允许在变量定义之前使用它们
"key-spacing":[1, {
"singleLine": {
"beforeColon": false,
"afterColon": true
},
"multiLine": {
"beforeColon": true,
"afterColon": true,
"align": "colon"
}
}],
"no-multi-spaces": [1, {"exceptions": {
"ImportDeclaration": true,
"AssignmentPattern": true,
"VariableDeclarator": true,
"Property": true}
}],
"quotes": [1, "single", "avoid-escape"] //使用单引号
},
"extends": "eslint:recommended",
"ecmaFeatures": {
"jsx": true,
"experimentalObjectRestSpread": true
},
"plugins": [
"react"
]
}
更多规则可以在List of available rules查找配置
所有的规则默认都是禁用的。在配置文件中,使用 "extends": "eslint:recommended" 来启用推荐的规则,报告一些常见的问题,在下文中这些推荐的规则都带有一个绿色对勾标记。
命令行的 --fix 选项用来自动修复规则所报告的问题(目前,大部分是对空白的修复),在下文中会有一个黄色扳手的图标。
现在我们可以看到这个文件有三处运算符没有加空格,两处使用双引号的地方。
终于可以告别学生无休止的小白问题,有时间去看屁股,啊不,去看教案了……