什麼是靜態檢查
距離上次寫三分鐘從零單排(三分鐘從零單排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:UsersUSERNAMEAppDataRoamingSublime Text 3Packages
以下是我在使用的配置檔案:
{
"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 選項用來自動修復規則所報告的問題(目前,大部分是對空白的修復),在下文中會有一個黃色扳手的圖示。
現在我們可以看到這個檔案有三處運算子沒有加空格,兩處使用雙引號的地方。
終於可以告別學生無休止的小白問題,有時間去看屁股,啊不,去看教案了……