JS代碼檢查工具ESLint

前面的話

  ESLint是一個JavaScript代碼靜態檢查工具,能夠檢查JavaScript的語法錯誤,提示潛在的bug,能夠有效提升代碼質量,維持前端團隊高度一致的編碼風格。ESLint不但提供一些默認的規則,也提供用戶自定義規則來約束所寫的JavaScript代碼。本文將詳細介紹ESLint前端

 

發展歷史

  Douglas Crockford大神根據本身的理念用JavaScript寫了一個JavaScript代碼規範檢查工具,這就是JSLint。後來很是流行,也的確幫助了廣大的JavaScript程序員。可是,大神對於本身的代碼規範不作絲毫的妥協,對開源社區的反饋的迴應也不禮貌。因而,JSLint從一個幫助程序員規範代碼,避免Bug的工具,變成了一個讓代碼像Crockford的工具。在最不信神的IT界,這固然不能忍了vue

  2011年,一個叫Anton Kovalyov的前端程序員藉助開源社區的力量弄出來了JSHint,該工具的思想基本上和JSLint是一致的,但具備如下幾點優點:一、可配置規則。二、社區支持度高。三、可定製結果報表node

  起初幾年,JSHint 一直是前端代碼檢測工具的首選。但在 2013 年,Zakas 大佬發現 JSHint 已經沒法知足本身定製化規則的需求,並且和 Anton 討論後達成共識這根本在不可能在 JSHint 上實現。同時 Zakas 還設想發明一個基於 AST 的 lint,能夠動態執行額外的規則,同時能夠很方便的擴展規則react

  2013 年的 6 月份,Zakas 發佈了全新的 lint 工具——ESLint。ESLint 的出現並無撼動 JSHint 的霸主地位。因爲前者是利用 AST 處理規則,用 Esprima 解析代碼,執行速度要比只須要一步搞定的 JSHint 慢不少;其次當時已經有許多編輯器對 JSHint 支持完善,生態足夠強大。真正讓 ESLint 逆襲的是 ECMAScript 6 的出現jquery

  2015 年 6 月,ES2015 規範正式發佈。可是發佈後,市面上瀏覽器對最新標準的支持狀況極其有限。若是想要提早體驗最新標準的語法,就得靠 Babel 之類的工具將代碼編譯成 ES5 甚至更低的版本,同時一些實驗性的特性也能靠 Babel 轉換。這時 JSHint 就略尷尬,ES2015 變化很大,短時間內沒法徹底支持。ESLint 可擴展的優點一下就體現出來了,不只能夠擴展規則,甚至連解析器也能替換。Babel 團隊就爲 ESLint 開發了 babel-eslint 替換默認解析器,讓 ESLint 率先支持 ES2015 語法git

  也是在 2015 年,React 的應用愈來愈普遍,誕生不久的 JSX 也越發流行。ESLint 自己也不支持 JSX 語法。仍是由於可擴展性,eslint-plugin-react 的出現讓 ESLint 也能支持當時 React 特有的規則程序員

  至此,ESLint 完美躺贏,替代 JSHint 成爲前端主流工具es6

 

詳細配置

【註釋配置】github

  有兩種主要的方式來配置 ESLint,其中一種就是註釋配置,使用 JavaScript 註釋把配置信息直接嵌入到一個代碼源文件中web

  能夠在文件中使用如下格式的塊註釋來臨時禁止規則出現警告

/* eslint-disable */ alert('foo'); /* eslint-enable */

  也能夠對指定的規則啓用或禁用警告:

/* eslint-disable no-alert, no-console */ alert('foo'); console.log('bar'); /* eslint-enable no-alert, no-console */

  若是在整個文件範圍內禁止規則出現警告,將 /* eslint-disable */ 塊註釋放在文件頂部:

/* eslint-disable */ alert('foo');

【文件配置】

  另外一種是文件配置,使用 JavaScript、JSON 或者 YAML 文件爲整個目錄和它的子目錄指定配置信息

  ESLint 支持幾種格式的配置文件

JavaScript - 使用 .eslintrc.js 而後輸出一個配置對象。 YAML - 使用 .eslintrc.yaml 或 .eslintrc.yml 去定義配置的結構。 JSON - 使用 .eslintrc.json 去定義配置的結構,ESLint 的 JSON 文件容許 JavaScript 風格的註釋。 (棄用) - 使用 .eslintrc,可使 JSON 也能夠是 YAML。 package.json - 在 package.json 裏建立一個 eslintConfig屬性,在那裏定義配置。

  若是同一個目錄下有多個配置文件,ESLint 只會使用一個。優先級順序以下

1 .eslintrc.js 2 .eslintrc.yaml 3 .eslintrc.yml 4 .eslintrc.json 5 .eslintrc 6  package.json

  除了配置一個獨立的 .eslintrc.* 文件,也能夠直接在 package.json 文件裏的 eslintConfig 字段指定配置,ESLint 將自動在要檢測的文件目錄裏尋找它們,緊接着是父級目錄,一直到文件系統的根目錄

{ "name": "mypackage", "version": "0.0.1", "eslintConfig": { "env": { "browser": true, "node": true } } }

  或者使用 -c 選項傳遞命令行將文件保持到任意地方

eslint -c myconfig.json myfiletotest.js

【配置語言】

  ESLint 容許指定想要支持的 JavaScript 語言選項。默認狀況下,ESLint 支持 ECMAScript 5 語法。能夠覆蓋該設置,以啓用對 ECMAScript 其它版本和 JSX 的支持

ecmaVersion - 默認設置爲3,5(默認), 可使用 6789 來指定想要使用的 ECMAScript 版本。也能夠用使用年份命名的版本號指定爲 2015(同 6),2016(同 7),或 2017(同 8)或 2018(同 9) sourceType - 設置爲 "script" (默認) 或 "module"(若是代碼是 ECMAScript 模塊) ecmaFeatures - 這是個對象,表示想使用的額外的語言特性: globalReturn - 容許在全局做用域下使用 return 語句 impliedStrict - 啓用全局 strict mode (若是 ecmaVersion 是 5 或更高) jsx - 啓用 JSX experimentalObjectRestSpread - 啓用實驗性的 object rest/spread properties 支持

  配置示例

"parserOptions": { "ecmaVersion": 6, "sourceType": "module", "ecmaFeatures": { "jsx": true } }

【配置環境】

  一個環境定義了一組預約義的全局變量。這些環境並非互斥的,能夠同時定義多個。可用的環境包括

browser - 瀏覽器環境中的全局變量。 node - Node.js 全局變量和 Node.js 做用域。 commonjs - CommonJS 全局變量和 CommonJS 做用域  shared-node-browser - Node.js 和 Browser 通用全局變量。 es6 - 啓用除了 modules 之外的全部 ECMAScript 6 特性(該選項會自動設置 ecmaVersion 解析器選項爲 6) worker - Web Workers 全局變量。 amd - 將 require() 和 define() 定義爲像 amd 同樣的全局變量。 mocha - 添加全部的 Mocha 測試全局變量。 jasmine - 添加全部的 Jasmine 版本 1.32.0 的測試全局變量。 jest - Jest 全局變量。 phantomjs - PhantomJS 全局變量。 protractor - Protractor 全局變量。 qunit - QUnit 全局變量。 jquery - jQuery 全局變量。 prototypejs - Prototype.js 全局變量。 shelljs - ShellJS 全局變量。 meteor - Meteor 全局變量。 mongo - MongoDB 全局變量。 applescript - AppleScript 全局變量。 nashorn - Java 8 Nashorn 全局變量。 serviceworker - Service Worker 全局變量。 atomtest - Atom 測試全局變量。 embertest - Ember 測試全局變量。 webextensions - WebExtensions 全局變量。 greasemonkey - GreaseMonkey 全局變量。

  能夠在JavaScript 文件中使用註釋來指定環境

/* eslint-env node, mocha */

  也能夠在配置文件裏指定環境,使用 env 關鍵字指定想啓用的環境,並設置它們爲 true

{ "env": { "browser": true, "node": true } }

  若是想在一個特定的插件中使用一種環境,確保提早在 plugins 數組裏指定了插件名,而後在 env 配置中不帶前綴的插件名後跟一個 / ,緊隨着環境名

{ "plugins": ["example"], "env": { "example/custom": true } }

【配置插件】

  ESLint 支持使用第三方插件。在使用插件以前,必須使用 npm 安裝它。

  在配置文件裏配置插件時,可使用 plugins 關鍵字來存放插件名字的列表。插件名稱能夠省略 eslint-plugin- 前綴

{ "plugins": [ "plugin1", "eslint-plugin-plugin2" ] }

  注意:因爲 Node.js 的 require 函數的行爲,全局安裝的 ESLint 實例只能使用全局安裝的 ESLint 插件,本地安裝的版本,只能用本地安裝的插件。不支持混合本地和全局插件

【配置規則】

  ESLint 附帶有大量的規則。可使用註釋或配置文件修改項目中要使用的規則。要改變一個規則設置,必須將規則 ID 設置爲下列值之一:

"off"0 - 關閉規則 "warn"1 - 開啓規則,使用警告級別的錯誤:warn (不會致使程序退出) "error"2 - 開啓規則,使用錯誤級別的錯誤:error (當被觸發的時候,程序會退出)

  爲了在文件註釋裏配置規則,使用如下格式的註釋:

/* eslint eqeqeq: "off", curly: "error" */

  也能夠在配置文件中進行規則配置

{ "rules": { "eqeqeq": "off", "curly": "error", "quotes": ["error", "double"] } }

  配置定義在插件中的一個規則的時候,必須使用 插件名/規則ID 的形式

{ "plugins": [ "plugin1" ], "rules": { "eqeqeq": "off", "curly": "error", "quotes": ["error", "double"], "plugin1/rule1": "error" } }

  也可使用這種格式的註釋配置

/* eslint "plugin1/rule1": "error" */

【配置繼承】

  一個配置文件能夠被基礎配置中的已啓用的規則繼承

  值爲 "eslint:recommended" 的 extends 屬性啓用一系列核心規則,這些規則報告一些常見問題。這個推薦的子集只能在 ESLint 主要版本進行更新

"extends": "eslint:recommended"

  插件是一個 npm 包,一般輸出規則。一些插件也能夠輸出一個或多個命名的 配置。要確保這個包安裝在 ESLint 能請求到的目錄下

{ "plugins": [ "react" ], "extends": [ "eslint:recommended", "plugin:react/recommended" ], "rules": { "no-set-state": "off" } }

  extends 屬性值能夠是基本配置文件的絕對路徑或相對路徑。 ESLint 解析基本配置文件的相對路徑相對使用的配置文件,除非那個文件在主目錄或非 ESLint 安裝目錄的父級目錄。在這些狀況下,ESLint 解析基本配合文件的相對路徑相對於被檢測的項目目錄(尤爲是當前工做目錄)

{ "extends": [ "./node_modules/coding-standard/eslintDefaults.js", "./node_modules/coding-standard/.eslintrc-es6", "./node_modules/coding-standard/.eslintrc-jsx" ], "rules": { "eqeqeq": "warn" } }

【配置忽略】

  能夠經過在項目根目錄建立一個 .eslintignore 文件告訴 ESLint 去忽略特定的文件和目錄

  .eslintignore 文件是一個純文本文件,其中的每一行都是一個 glob 模式代表哪些路徑應該忽略檢測

  例如,如下將忽略全部的 JavaScript 文件:

**/*.js

  若是沒有發現 .eslintignore 文件,也沒有指定替代文件,ESLint 將在 package.json 文件中查找 eslintIgnore 鍵,來檢查要忽略的文件

{ "name": "mypackage", "version": "0.0.1", "eslintConfig": { "env": { "browser": true, "node": true } }, "eslintIgnore": ["hello.js", "world.js"] }

 

NodeJS

  下面來介紹NodeJS環境下如何配置airbnb-base的eslint規則

  一、本地安裝eslint、eslint-config-airbnb-base、eslint-plugin-import

npm install --save-dev eslint npm install --save-dev eslint-config-airbnb-base npm install --save-dev eslint-plugin-import

  注意: 最好使用npm,而不是cnpm安裝。由於在使用本地安裝的eslint時,會使用其安裝路徑。而npm和cnpm的安裝路徑不一致

  二、安裝成功後,package.json文件中增長以下字段

"devDependencies": { "eslint": "^4.19.1", "eslint-config-airbnb-base": "^12.1.0", "eslint-plugin-import": "^2.12.0" }

  三、在根目錄下設置.eslintrc.js配置文件

module.exports = { "extends": ["airbnb-base"], "env": { "es6": true, "node": true }, "rules": { "comma-dangle": ["error", "never"], // 要求或禁止末尾逗號:不容許逗號
    "indent": ["error", 2], // JavaScript代碼強制使用一致的縮進:2格縮進
    "semi": ["error", "never"], // 不使用分號
    "arrow-parens": ["error", "as-needed"], // 箭頭函數的參數能夠不使用圓括號
    "linebreak-style": "off", // 取消換行符\n或\r\n的驗證
    "object-curly-newline": ["error", { "consistent": true }], // 花括號內的換行符不必定要格式一致
    "function-paren-newline": "off", // 不驗證函數括號內的換行
    "import/extensions": "off", // 取消對文件擴展名的驗證
    "no-param-reassign": "off", // 容許對函數參數進行再賦值
    "no-underscore-dangle": "off", // 容許在標識符中使用下劃線
    "no-use-before-define": "off", // 容許變量和函數在定義前使用
    "no-unused-expressions": "off", // 容許使用未使用過的表達式,以此來支持a && a()的代碼形式
    "no-console": "off", // 啓用console控制檯
    "consistent-return": "off", // 關閉函數中return的檢測
    "no-shadow": "off", // 可使用同名變量,
    "newline-per-chained-call": "off", //取消方法鏈調用中的換行符的檢測
    "import/newline-after-import": "off" } }

  四、在命令行工具中使用命令,對文件進行lint校驗

PS D:\blog\api\node_modules\.bin> ./eslint ../../index.js D:\blog\api\index.js 16:1  error  'a' is not defined  no-undef ✖ 1 problem (1 error, 0 warnings)

 

React

  一、安裝eslint-config-airbnb配置合集

npm install --save-dev eslint-config-airbnb

  Airbnb包括瞭如下三個插件

eslint-plugin-import eslint-plugin-react eslint-plugin-jsx-a11y

  二、在根目錄下建立.eslintrc.js配置文件

module.exports = { // 指定校驗的ECMAScript的版本及特性
  "parserOptions": { "ecmaVersion": 7, // ECMAScript版本,7爲ES7
    "sourceType": "module", //默認script,若是代碼是ECMAScript模塊,設置爲module
    "ecmaFeatures": { // 使用額外的語言特性
        "jsx": true // 啓用JSX
 } }, // 當訪問未定義的變量時,no-undef 規則將發出警告 // 指定腳本的運行環境。每種環境都有一組特定的預約義全局變量
  "env": { "es6": true, "node": true, "browser": true, }, // 當訪問未定義的變量時,no-undef 規則將發出警告 // 腳本在執行期間訪問的額外的全局變量
  "globals": { "document": true, "navigator": true, "window":true, "node":true }, // 使用第三方airbnb開發配置合集
  "extends": "airbnb", // eslint-config-airbnb包括瞭如下3個插件
  "plugins": [ "react", "jsx-a11y", "import" ], // 定義本身的規則
  "rules": { "comma-dangle": ["error", "never"], // 要求或禁止末尾逗號:不容許逗號
    "indent": ["error", 2], // JavaScript代碼強制使用一致的縮進:2格縮進
    "semi": ["error", "never"], // 不使用分號
    "arrow-parens": ["error", "as-needed"], // 箭頭函數的參數能夠不使用圓括號
    "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], //reajs文件的後綴名爲.js或.jsx都可
    "linebreak-style": "off", // 取消換行符\n或\r\n的驗證
    "object-curly-newline": ["error", { "consistent": true }], // 花括號內的換行符不必定要格式一致
    "function-paren-newline": "off", // 不驗證函數括號內的換行
    "import/extensions": "off", // 取消對文件擴展名的驗證
    "import/no-unresolved": "off", // 取消自動解析路徑,以此開啓alias的別名路徑設置
    "no-shadow": "off", // 取消變量聲明覆蓋的驗證,保證mapDispatchToProps的正確使用
    "no-param-reassign": "off", // 容許對函數參數進行再賦值
    "no-underscore-dangle": "off", // 容許在標識符中使用下劃線
    "no-use-before-define": "off", // 容許變量和函數在定義前使用
    "no-unused-expressions": "off", // 容許使用未使用過的表達式,以此來支持a && a()的代碼形式
    "jsx-a11y/anchor-is-valid": [ "error", { "components": [ "Link" ], "specialLink": [ "to" ]}], // 容許正常地使用Link
    "import/no-extraneous-dependencies": "off", //使用history/createBrowserHistory引入包時,不會報錯
    "no-console": "off" // 啓用console控制檯
 } };

 

Vue

  使用vue-cli建立項目時,若是使用eslint,會有以下圖所示的選項,選擇使用standard仍是airbnb規範

  以standard規範建立成功後,package.json文件,會出現以下字段

"eslint": "^4.15.0", "eslint-config-standard": "^10.2.1", "eslint-friendly-formatter": "^3.0.0", "eslint-loader": "^1.7.1", "eslint-plugin-import": "^2.7.0", "eslint-plugin-node": "^5.2.0", "eslint-plugin-promise": "^3.4.0", "eslint-plugin-standard": "^3.0.1", "eslint-plugin-vue": "^4.0.0",

  與此同時,在根目錄下自動生成.eslintrc.js配置文件

// https://eslint.org/docs/user-guide/configuring
 module.exports = { root: true, parserOptions: { parser: 'babel-eslint' }, env: { browser: true }, extends: [ // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
    'plugin:vue/base', // https://github.com/standard/standard/blob/master/docs/RULES-en.md
    'standard' ], // required to lint *.vue files
  plugins: ['vue'], // add your custom rules here
 rules: { // allow async-await
    'generator-star-spacing': 'off', // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', } }

  若是須要更改成更嚴格的驗證,能夠下載並使用airbnb規範

npm install --save-dev eslint-config-airbnb-base

  在extends字段中,將standard更改成airbnb-base,將plugin:vue/base更改成plugin: vue/recommended

 extends: [ 'plugin:vue/recommended', 'airbnb-base' ],

   添加一些自定義的規則,最終的配置文件以下所示

// https://eslint.org/docs/user-guide/configuring
 module.exports = { root: true, parserOptions: { parser: 'babel-eslint' }, env: { browser: true }, extends: [ // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
    'plugin:vue/recommended', // https://github.com/standard/standard/blob/master/docs/RULES-en.md
    'airbnb-base' ], // required to lint *.vue files
  plugins: ['vue'], // add your custom rules here
 rules: { // allow async-await
    'generator-star-spacing': 'off', // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', "linebreak-style": "off", // 取消換行符\n或\r\n的驗證
    "semi": ["error", "never"], // 不使用分號
    "arrow-parens": ["error", "as-needed"], // 箭頭函數的參數能夠不使用圓括號
    "comma-dangle": ["error", "never"], // 不容許末尾逗號
    "consistent-return": "off", // 關閉函數中return的檢測
    "object-curly-newline": ["error", { "consistent": true }], // 花括號內的換行符不必定要格式一致
    "global-require": "off", // 取消對require的驗證,使得可使用require來加載圖片的相對路徑
    "function-paren-newline": "off", // 不驗證函數括號內的換行
    "import/no-unresolved": "off", // 取消自動解析路徑,以此開啓alias的別名路徑設置
    "no-param-reassign": "off", // 容許對函數參數進行再賦值
    "import/extensions": "off", // 取消對文件擴展名的驗證
    "max-len": "off", // 取消行的最大長度的驗證,使SVG不用從新調整格式
    "no-underscore-dangle": "off", //容許標識符中有下劃線,從而支持vue中插件的使用
    "no-console": "off", // 啓用console控制檯
    "no-unused-expressions": "off", // 容許使用未使用過的表達式,以此來支持a && a()的代碼形式
    "no-shadow": "off", // 取消變量聲明覆蓋的驗證
    'vue/attribute-hyphenation': 0, // 取消對元素特性只能使用中劃線或小駝峯形式的驗證
    'vue/max-attributes-per-line': 0 // 取消元素有多個特性時,每一個特性獨佔一行的驗證
 } }
相關文章
相關標籤/搜索