三分鐘從零單排js靜態檢查

王德福發表於2019-01-29

什麼是靜態檢查

距離上次寫三分鐘從零單排(三分鐘從零單排gulp-less配置) 的文章過去好久了,這次來聊一聊靜態檢查。

因為現在正在帶學生的js基礎課,開始寫一些整體專案了。日常遇到很多關於缺少括號,多寫了一個點,變數沒有宣告諸如此類的錯誤。

而且在程式設計界一直有一個神祕的現象,就是越簡單的bug就越難找到。那種死都改不好的bug基本都是一眼就看的出來,一個小時都找不到的錯誤,八成是一下子就改好的。從上學的時候就發現了這個規律,所以一旦找了很長時間都找不到bug在哪,趕緊把自己切換到白痴模式,很快就能找到錯誤。

但是對於新人來說,每天都會犯很多語法細節的錯誤,並且在其中浪費大量的時間。有很多時候,明明只是一個括號匹配的小問題,結果為了找出來問題就反覆修改除錯了好幾處程式碼,最後反而把好用的程式碼改壞了,人也很煩躁,覺得很有挫敗感。

當然,靜態檢查不僅僅是幫助初學者進行學習,對於我們日常工作來說,避免一些小錯誤也是很有效的。另一個重要的用途是,保持團隊的程式碼風格一致,使得提交git的時候可以避免很多不必要的修改行出現。

所以無論是從學習的角度,還是從團隊開發的角度來說,靜態程式碼檢查都可以有效的提高開發效率。

Sublime外掛

因為我的日常使用Sublime作為開發工具,所以用Sublime的使用舉例說明。

首先要安裝兩個外掛:

SublimeLinterSublimeLinter-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看到外掛的配置項了。

三分鐘從零單排js靜態檢查

包括檢測模式,報錯資訊樣式,切換檢測器等各種配置。所有的配置通過開啟Open User Settings都可以看到。

三分鐘從零單排js靜態檢查

因為現在還沒有任何的檢測器,所以還無法工作。

可選用的靜態檢測的工具有eslint jshint jslint JSCS等。

JSLint

JSLint是其中最老的工具。在2002年 Douglas Crockford開發了該工具,根據其經驗,強制使用js語言中精粹的部分。如果你同意這些精粹,JSLint能成為一個好的工具。

JSLint的缺點是不能配置和擴充。你根本不能禁掉需要特性,並且很多缺少文件。官方文件非常不友好,例如缺少如何將其整合到編輯的資訊。

JSHint

作為一個可配置的JSLint版本,JSHint被開發出來。你可以配置每個規則,將其放到一個配置檔案中,這樣在大專案中可以容易使用。JSHint對每個規則有好的文件,所以可以準確知道每個規則的作用。將其整合到編輯器也是簡單的。

ESLint

ESLint是最新出來的工具。它被設計的容易擴充、擁有大量的自定義規則、容易的通過外掛來安裝。它給出準確的輸出,而且包括規則名,這樣可以知道哪個規則造成了錯誤。

橫向對比之後,我們選擇用ESLint作為靜態檢測的工具,於是我們還需要外掛:Sublime-contrib-eslint

三分鐘從零單排js靜態檢查

這時候開啟 Tools > SublimeLinter > Open User Settings 可以看到,linters配置項已經有了eslint

三分鐘從零單排js靜態檢查

所以看起來好像已經可以了呢,趕緊迫不及待的開啟一個js檔案,結果卻什麼都沒有顯示,我們用ctrl+`開啟控制檯看一下,發現有報錯

三分鐘從零單排js靜態檢查

原來是eslint沒有安裝,需要手動安裝eslint包,開啟cmd,輸入:

npm i eslint -g

全域性安裝eslint之後重啟一下SublimeLinter,結果發現,媽的還是不好使……

三分鐘從零單排js靜態檢查

再次使用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查詢配置

三分鐘從零單排js靜態檢查

所有的規則預設都是禁用的。在配置檔案中,使用 “extends”: “eslint:recommended” 來啟用推薦的規則,報告一些常見的問題,在下文中這些推薦的規則都帶有一個綠色對勾標記。
命令列的 –fix 選項用來自動修復規則所報告的問題(目前,大部分是對空白的修復),在下文中會有一個黃色扳手的圖示。

三分鐘從零單排js靜態檢查

現在我們可以看到這個檔案有三處運算子沒有加空格,兩處使用雙引號的地方。

終於可以告別學生無休止的小白問題,有時間去看屁股,啊不,去看教案了……

三分鐘從零單排js靜態檢查

相關文章