摘要:的初衷是為了讓程序員可以創(chuàng)建自己的檢測規(guī)則。為了便于人們使用,內(nèi)置了一些規(guī)則,當(dāng)然,你可以在使用過程中自定義規(guī)則。所有的規(guī)則默認(rèn)都是禁用的。在文件里的字段進(jìn)行配置。如何編寫一個知道了的原理,接下來可以自定義一個。
eslint介紹
ESLint 是一個開源的 JavaScript 代碼檢查工具,由 Nicholas C. Zakas 于2013年6月創(chuàng)建。代碼檢查是一種靜態(tài)的分析,常用于尋找有問題的模式或者代碼,并且不依賴于具體的編碼風(fēng)格。對大多數(shù)編程語言來說都會有代碼檢查,一般來說編譯程序會內(nèi)置檢查工具。
JavaScript 是一個動態(tài)的弱類型語言,在開發(fā)中比較容易出錯。因為沒有編譯程序,為了尋找 JavaScript 代碼錯誤通常需要在執(zhí)行過程中不斷調(diào)試。像 ESLint 這樣的可以讓程序員在編碼的過程中發(fā)現(xiàn)問題而不是在執(zhí)行的過程中。
ESLint 的初衷是為了讓程序員可以創(chuàng)建自己的檢測規(guī)則。ESLint 的所有規(guī)則都被設(shè)計成可插拔的。為了便于人們使用,ESLint 內(nèi)置了一些規(guī)則,當(dāng)然,你可以在使用過程中自定義規(guī)則。所有的規(guī)則默認(rèn)都是禁用的。
ESLint 使用 Node.js 編寫。
eslint配置一般都采用.eslintrc.* 的配置文件進(jìn)行配置, 如果放在項目的根目錄中,則會作用于整個項目。如果在項目的子目錄中也包含著.eslintrc文件,則對于子目錄中文件的檢查會忽略掉根目錄中的配置,而直接采用子目錄中的配置,這就能夠在不同的目錄范圍內(nèi)應(yīng)用不同的檢查規(guī)則,顯得比較靈活。ESLint采用逐級向上查找的方式查找.eslintrc.*文件,當(dāng)找到帶有 "root": true 配置項的.eslintrc.* 文件時,將會停止向上查找。
在 package.json文件里的 eslintConfig 字段進(jìn)行配置。
以使用項目為例,簡單介紹一下eslint的具體配置及作用:
module.exports = { parser: "babel-eslint", // parser指定解析器,默認(rèn)的為espree。babel-eslint是一個Babel parser的包裝器,這個包裝器使得 Babel parser 可以和 ESLint 協(xié)調(diào)工作 parserOptions: { sourceType: "module", // 設(shè)置為 "script" (默認(rèn)) 或 "module"(ES6)。 ecmaFeatures: { // 這是個對象,表示你想使用的額外的語言特性: jsx: true // 啟用 JSX } }, extends: ["eslint:recommended"], // 使用eslint推薦的規(guī)則作為基礎(chǔ)配置,可以在rules中覆蓋 plugins: ["html", "vue", "prettier", "import"], // vue是eslint-plugin-vue的簡寫,此插件的作用是可以讓eslint識別.vue中的script代碼 rules: { // 0或者off表示規(guī)則關(guān)閉,出錯也被忽略;1或者warn表示如果出錯會給出警告(不會導(dǎo)致程序退出);2或者error表示如果出錯會報出錯誤(會導(dǎo)致程序退出,退出碼是1) "no-console": "off", "prefer-const": "error", "prettier/prettier": "warn", "prefer-arrow-callback": "warn", "no-debugger": process.env.NODE_ENV === "production" ? 2 : 0 }, globals: { // 允許在代碼中使用全局變量 location: true, setTimeout: true } };
具體的配置文檔:http://eslint.cn/docs/user-guide/configuring
具體的eslint:recommended支持的規(guī)則:https://cn.eslint.org/docs/rules/
“extends”除了可以引入推薦規(guī)則,還可以以文件形式引入其它的自定義規(guī)則,然后在這些自定義規(guī)則的基礎(chǔ)上用rules去定義個別規(guī)則,從而覆蓋掉”extends”中引入的規(guī)則。
{ "extends": [ "./node_modules/coding-standard/eslintDefaults.js", // Override eslintDefaults.js "./node_modules/coding-standard/.eslintrc-es6", // Override .eslintrc-es6 "./node_modules/coding-standard/.eslintrc-jsx", ], "rules": { // Override any settings from the "parent" configuration "eqeqeq": "warn" } }
除了在配置文件中指定規(guī)則外,還可以在代碼中指定規(guī)則,代碼文件內(nèi)以注釋配置的規(guī)則會覆蓋配置文件里的規(guī)則,即優(yōu)先級要更高。平時我們常用的就是 `eslint-disable-next-line
`
可以通過在項目目錄下建立.eslintignore文件,并在其中配置忽略掉對哪些文件的檢查。需要注意的是,不管你有沒有在.eslintignore中進(jìn)行配置,eslint都會默認(rèn)忽略掉對/node_modules/** 的檢查。也可以在package.json文件的 eslintIgnore 字段進(jìn)行配置。
eslint檢查原理要實現(xiàn)靜態(tài)分析則需要自建一個預(yù)編譯階段對代碼進(jìn)行解析。
首先我們看看大部分編譯器工作時的三個階段:
解析:將未經(jīng)處理的代碼解析成更為抽象的表達(dá)式,通常為抽象語法樹,即 AST。
轉(zhuǎn)換:通過修改解析后的代碼表達(dá)式,將其轉(zhuǎn)換為符合預(yù)期的新格式。
代碼生成:將轉(zhuǎn)換后的表達(dá)式生成為新的目標(biāo)代碼。
對于eslint來說,規(guī)則校驗發(fā)生在將JavaScript 代碼解析為 AST 之后,遍歷 AST 的過程中。eslint采用 Espree 來生成AST。具體的生成方法在這里。
我們可以使用AST explorer來查看代碼被解析后生成的AST。
首先來看看eslint源碼中關(guān)于rules的編寫。eslint中的rules源碼存在于lib/rules下。每一個rules都是一個node模塊,用module.exports導(dǎo)出一個meta對象及一個create函數(shù)。
module.exports = { meta: { type: "suggestion", docs: { description: "disallow unnecessary semicolons", category: "Possible Errors", recommended: true, url: "https://eslint.org/docs/rules/no-extra-semi" }, fixable: "code", schema: [] // no options }, create: function(context) { return { // callback functions }; } };
meta 代表了這條規(guī)則的元數(shù)據(jù),如這條規(guī)則的類別,文檔,可接收的參數(shù) schema 等等。
create 返回一個對象,其中定義了一些在 AST 遍歷訪問到對應(yīng)節(jié)點需要執(zhí)行的方法等等。函數(shù)接受一個context對象作為參數(shù),里面包含了例如可以報告錯誤或者警告的context.report()、可以獲取源代碼的context.getSourceCode()等方法,可以簡化規(guī)則的編寫。
function checkLastSegment (node) { // report problem for function if last code path segment is reachable } module.exports = { meta: { ... }, create: function(context) { // declare the state of the rule return { ReturnStatement: function(node) { // 在AST從上向下遍歷到ReturnStatement node 時執(zhí)行 }, // 在AST 從下向上遍歷到 function expression node 時執(zhí)行: "FunctionExpression:exit": checkLastSegment, "ArrowFunctionExpression:exit": checkLastSegment, onCodePathStart: function (codePath, node) { // 在分析代碼路徑開始時執(zhí)行 }, onCodePathEnd: function(codePath, node) { // 在分析代碼路徑結(jié)束時執(zhí)行 } }; } };
遍歷 AST 的過程中會以“從上至下”再“從下至上”的順序經(jīng)過節(jié)點兩次,selector 默認(rèn)會在下行的過程中執(zhí)行對應(yīng)的訪問函數(shù),如果需要再上行的過程中執(zhí)行,則需要添加:exit。
詳細(xì)的原理在官方文檔中有說明,點這里。
詳細(xì)的代碼路徑分析在這里。
知道了rules的原理,接下來可以自定義一個rules。每一個rules需要有三個以該規(guī)則名命名的文件,分別是:
在 lib/rules 目錄下: 一個源文件(例如,no-extra-semi.js)
在 tests/lib/rules 目錄下: 一個測試文件 (例如, no-extra-semi.js)
在 docs/rules 目錄: 一個 markdown 文檔文件 (例如, no-extra-semi)
接下來我們來編寫一個簡單的rules,例如禁止塊級注釋,當(dāng)代碼中使用了塊級注釋,eslint將報錯。
rules文件:
// lib/rules/no-block-comments.js module.exports = { meta: { docs: { description: "禁止塊級注釋", category: "Stylistic Issues", recommended: true } }, create (context) { // 獲取源代碼 const sourceCode = context.getSourceCode() return { Program () { // 獲取源代碼中所有的注釋 const comments = sourceCode.getAllComments() const blockComments = comments.filter(({ type }) => type === "Block") blockComments.length && context.report({ node: node, message: "No block comments" }) } } } }
rules的測試文件:
// tests/lib/rules/no-block-comments.js const RuleTester = require("eslint").RuleTester; const rule = require("../../../lib/rules/no-block-comments"); const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2018 } }); // You do have to tell eslint what js you"re using ruleTester.run("no-block-comments", rule, { valid: ["var a = 1; console.log(a)"], invalid: [ { code: "var a = 1; /* block comments */ console.log(a)", errors: [ { messageId: "blockComments", line: 1, nodeType: "Block" } ] } ] });
官網(wǎng)的working with rules文檔中有關(guān)于如何編寫一個rules的詳細(xì)介紹。
編寫好的rules需要發(fā)布到npm上,作為一個eslint-plugin,在項目中下載下來才能夠使用。例子中代碼的npm在這里。
在項目中的配置:
// .eslintrc.js module.exports = { ... "plugins": [ "eslint-plugin-no-block-comments" // 你 publish 的 npm 包名稱,可以省略 eslint-plugin ], "rules": { // 啟用的規(guī)則及其各自的錯誤級別 "no-console": "off", "no-block-comments/no-block-comments": 2 // 引用no-block-comments插件中的no-block-comments規(guī)則 } };
之后就可以對代碼進(jìn)行檢查了。比如我要檢查的代碼如下:
// src/index.js const a = 1; /* 這里是塊級注釋 */ console.log(a);
在命令行中執(zhí)行eslint src,就可以看到報錯結(jié)果。
ESlint官網(wǎng)
ESLint 工作原理探討
開發(fā) eslint 規(guī)則
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/106449.html
摘要:以前沒時間過,每次項目編輯器的插件就關(guān)掉,老項目都沒注意過相關(guān)的代碼規(guī)范,這次新項目加入進(jìn)去實踐下三個插件功自動有些規(guī)則是沖突的,需要確定優(yōu)先順序,其他插件進(jìn)行自定義化的配置都可以自動保存格式化的功能用和寫出高質(zhì)量代碼在中對兩者進(jìn)行配置使用 以前沒時間過eslint,每次項目vscode 編輯器的eslint插件就關(guān)掉eslint,老項目都沒注意過相關(guān)的代碼規(guī)范,這次新項目加入進(jìn)去實踐...
摘要:配置添加包配置此處如果不使用需要將替換為效果代碼提交的格式不符合標(biāo)準(zhǔn)就會直接被拒絕。 Commitlint 配置 添加包 yarn add @commitlint/cli @commitlint/config-conventional husky -D 配置package.json husky: { hooks: { // 此處如果不使用husky 需要將H...
摘要:自定義規(guī)則校驗代碼業(yè)務(wù)邏輯是社區(qū)中主流的工具,提供的大量規(guī)則有效的保障了許多項目的代碼質(zhì)量。本文將介紹如何通過自定義檢查規(guī)則,校驗項目中特有的一些業(yè)務(wù)邏輯,如特殊作用域特殊使用規(guī)范性等。 自定義 eslint 規(guī)則校驗代碼業(yè)務(wù)邏輯 eslint 是 JavaScript 社區(qū)中主流的 lint 工具,提供的大量規(guī)則有效的保障了許多項目的代碼質(zhì)量。本文將介紹如何通過自定義 eslint ...
須知:使用vite需要node版本在12以上 一:npm構(gòu)建 1、npm init vite@latest 2、Project name:(項目名稱) 3、Select a framework:(選擇要用什么構(gòu)建自己的項目,這邊選vue)然后會有兩個選項一個是vue(vue+js) ,一個是vue+ts,要依照自己需求做選擇 4、cd到項目下npm install 安裝一下依賴 注...
摘要:工具幫助避免在編寫時出現(xiàn)愚蠢的錯誤。并不檢測潛在的,比如,未使用的變量或意外的全局變量等。在提到的所有工具中,它具有最廣泛的功能支持。使用工具是捕獲問題的良好步驟,但只能看到規(guī)則允許的錯誤。也可用于此目的。 Lint工具幫助避免在編寫JavaScript時出現(xiàn)愚蠢的錯誤。盡管有多年的經(jīng)驗,我仍然鍵入不正確的變量名稱,出現(xiàn)語法錯誤,以及忘記正確地處理error。在浪費自己時間,或更糟糕地...
閱讀 780·2021-09-30 09:46
閱讀 3790·2021-09-03 10:45
閱讀 3615·2019-08-30 14:11
閱讀 2549·2019-08-30 13:54
閱讀 2260·2019-08-30 11:00
閱讀 2355·2019-08-29 13:03
閱讀 1561·2019-08-29 11:16
閱讀 3588·2019-08-26 13:52