規(guī)范化是前端工程化的一個(gè)重要部分。現(xiàn)在,有許多工具能夠輔助我們實(shí)行代碼的規(guī)范化,比如你一定知道的 ESLint 和 Prettier。
今天,來(lái)聊聊這些工具的工作原理和基本使用,了解它們是如何發(fā)揮作用的,以及如何更好地利用這些工具去規(guī)范項(xiàng)目的代碼。
本文主要聊聊這些工具的作用和基本使用方式,不會(huì)有細(xì)致的使用步驟和教程,這些內(nèi)容我希望你能從官方指引中查看。
1. ESlint - 檢查你的 JavaScript 代碼
讓我們先從知名度最高的?ESLint[1]?開(kāi)始。
1.1. ESLint 及其作用
Lint 是一類專門(mén)用于檢查代碼的工具軟件, 也稱 linter。ESLint ,即 JavaScript (ECMAScript)代碼的檢查工具。
正如官網(wǎng)的介紹 —— “Find and fix problems in your JavaScript code”,ESLint 能夠輔助查找出你的 JavaScript 代碼中的問(wèn)題,包括:
-
代碼風(fēng)格問(wèn)題(styles)。比如,運(yùn)算符兩邊的空格、語(yǔ)句末尾的分號(hào)。
-
不好的寫(xiě)法。比如,使用?
==
?進(jìn)行比較而不是?===
。 -
可能存在邏輯問(wèn)題的代碼模式。比如,定義了一個(gè)變量,但沒(méi)有使用到它。
此外,ESLint 還能夠幫你自動(dòng)修復(fù)一些簡(jiǎn)單的問(wèn)題。
我們將在下一小結(jié)學(xué)習(xí)如何使用 ESLint 檢查我們的 JavaScript 代碼,并修復(fù)其中的一些問(wèn)題。
1.2. ESLint 快速上手
為了在項(xiàng)目中使用 ESLint,需要先安裝它。
#?初始化一個(gè)?npm?項(xiàng)目
mkdir?eslint-test
cd?eslint-test
npm?init?-y
#?安裝?eslint
npm?init?@eslint/config
復(fù)制代碼
回答一系列問(wèn)題后,你可以看目錄中的配置文件?.eslintrc.js
,這個(gè)配置文件告訴 ESLint 如何去解析項(xiàng)目,這個(gè)項(xiàng)目采用了哪些規(guī)范和規(guī)則。
ESLint 是一個(gè)高度配置化的工具。尤其需要留意?extends
?和?rules
?字段,它們定義了在項(xiàng)目中采用哪些規(guī)則。一段代碼有沒(méi)有問(wèn)題,取決于項(xiàng)目中應(yīng)用了哪些規(guī)則。比如:{semi: ["error", "always"]}
?要求必須在語(yǔ)句末尾添加分號(hào),相反,semi: ["error", "never"]
?禁止任何不必要的分號(hào)。
具體的配置教程可以參考官方配置文檔[2],不是這里三兩句能說(shuō)完的。
在這里,我使用的是?airbnb-base[3]?規(guī)范。
module.exports{
??//?...
??extends:?'airbnb-base'
??//?...
}
復(fù)制代碼
寫(xiě)一段簡(jiǎn)單的 JavaScript 代碼用于測(cè)試:
//?file?-?add.js
function?add(x,y)?{
??return?Number(x)+Number(y);
}
//???這是一個(gè)錯(cuò)誤的調(diào)用
add("2"+'3')
復(fù)制代碼
ESLint 是一個(gè)命令行工具,這個(gè)命令調(diào)用之前安裝的 ESLint 去檢查?add.js
?代碼:
npx?eslint?add.js
復(fù)制代碼
輸出結(jié)果:
eslint-test/add.js
1:15 error A space is required after ',' comma-spacing
2:19 error Operator '+' must be spaced space-infix-ops
5:5 error Strings must use singlequote quotes
5:8 error Operator '+' must be spaced space-infix-ops
5:8 error Unexpected string concatenation of literals no-useless-concat
? 5 problems (5 errors, 0 warnings)
4 errors and 0 warnings potentially fixable with the `--fix` option.
復(fù)制代碼
可以看到,ESLint 發(fā)現(xiàn)了代碼中的 5 個(gè) error 等級(jí)的問(wèn)題,并且提示其中的 4 個(gè)問(wèn)題是可修復(fù)的。根據(jù)提示,執(zhí)行:
npx?eslint?add.js?--fix
復(fù)制代碼
可以看到,現(xiàn)在提示只有一個(gè)問(wèn)題:
eslint-test/add.js
5:9 error Unexpected string concatenation of literals no-useless-concat
? 1 problem (1 error, 0 warnings)
復(fù)制代碼
重新查看?add.js
?文件,可以看到 4 個(gè)格式化問(wèn)題已經(jīng)被自動(dòng)修復(fù)了。檢查第 5 行?add('2' + '3');
, 發(fā)現(xiàn)正確寫(xiě)法應(yīng)該是?add('2', '3');
。
很好,所有的問(wèn)題都解決了,ESLint 可幫了大忙 ?? 。
盡管在實(shí)際中,我們很少直接調(diào)用?eslint
?命令,更多是配合編輯器和一些工作流工具使用(后面小結(jié)內(nèi)容)。不過(guò),記住 ESLint 原本是一個(gè)命令行工具,對(duì)我們理解它的工作原理很有幫助。
1.3. 配合編輯器使用的 ESLint
上一節(jié)中,我們是在命令行下使用 ESLint,并從命令行的輸出中看到代碼中的問(wèn)題。
image.png
許多人是從編輯器里接觸 ESLint 的。的確,當(dāng) ESLint 與編輯器配合工作時(shí),它的威力才真正顯現(xiàn)出來(lái)。
以 VSCode 為例,在 VSCode 上使用 ESLint 需要安裝?ESLint 插件[4]。啟用插件后,可以在編輯代碼的同時(shí)看到哪些代碼有問(wèn)題,及時(shí)發(fā)現(xiàn),及時(shí)修復(fù)。使用鼠標(biāo) hover 紅線,或者在下方的 PROBLEMS 面板中都可以看到具體的錯(cuò)誤提示。
Awesome!不過(guò),問(wèn)題來(lái)了:
-
插件做了什么,這種功能怎么實(shí)現(xiàn)的?
-
裝了插件還需要在項(xiàng)目里安裝 ESLint 嗎?
-
不同的項(xiàng)目中使用的 ESLint 版本和配置的規(guī)則不同,會(huì)發(fā)生沖突嗎?
回答:
-
插件原理:插件我們敲碼的時(shí)候,在后臺(tái)自動(dòng)執(zhí)行?
eslint
?命令分析代碼,并根據(jù)結(jié)果實(shí)時(shí)回顯到編輯器中。 -
需要每個(gè)項(xiàng)目?jī)?nèi)安裝 ESLint??床寮奈臋n:
The extension uses the ESLint library installed in the opened workspace folder. If the folder doesn't provide one the extension looks for a global install version.
插件使用當(dāng)前項(xiàng)目目錄中安裝的 ESLint 庫(kù)。如果目錄中沒(méi)有安裝,則嘗試使用全局安裝的。
說(shuō)明,插件并不包含 ESLint 核心庫(kù),而是嘗試讀取本地或全局安裝的 ESLint,并使用查找讀取項(xiàng)目?jī)?nèi)的?eslintrc.*
?配置文件。
?? 如果插件無(wú)法正確讀取項(xiàng)目中的 ESLint 程序和配置,會(huì)導(dǎo)致插件啟動(dòng)失敗。這個(gè)問(wèn)題常常是因?yàn)?ESLint 沒(méi)有安裝在打開(kāi)目錄的根部??梢酝ㄟ^(guò)修改插件的配置[5]解決。
-
因?yàn)椴寮冀K使用工作目錄中的 ESLint 程序和配置,當(dāng)使用本地安裝時(shí),每個(gè)項(xiàng)目都是獨(dú)立的,不會(huì)沖突。
1.4. 啟用編輯器的保存自動(dòng)修復(fù)功能
編輯器還有一個(gè)強(qiáng)大的功能,可以在保存時(shí),自動(dòng)修復(fù)那些支持自動(dòng)修復(fù)的問(wèn)題,不用執(zhí)行額外的?eslint \--fix files
?命令,?強(qiáng)烈推薦開(kāi)啟。
在 VSCode,你可能需要添加設(shè)置來(lái)啟用自動(dòng)修復(fù)功能:
{
??//?...
??"editor.codeActionsOnSave":?{
????"source.fixAll.eslint":?true
??}
}
復(fù)制代碼
WebStorm 用戶可以參考這里[6]設(shè)置。
啟用后,就幾乎不用手動(dòng)執(zhí)行?eslint
?命令了。
2. Prettier
另一個(gè)廣為人知的工具是?Prettier[7],它是一個(gè)代碼格式化工具。
2.1. 使用 Prettier
當(dāng)你了解了 ESLint 的使用后,自然你也能理解 Prettier 的使用。
Prettier 同樣支持配置,不過(guò)相對(duì)簡(jiǎn)單,同樣可以通過(guò)命令行執(zhí)行,同樣可以有編輯器插件可以和編輯器配合,具體可以參考官方文檔。
2.2. Prettier vs ESLint
你可能好奇 Prettier 和 ESLint 有什么區(qū)別?
首先,雖然它們都會(huì)對(duì)代碼 AST(語(yǔ)法樹(shù))進(jìn)行檢查,但 Prettier 只會(huì)進(jìn)行語(yǔ)法分析,只能檢查并歸正代碼的格式問(wèn)題,而 ESLint 還會(huì)進(jìn)一步對(duì)代碼進(jìn)行語(yǔ)義分析,能發(fā)現(xiàn)格式問(wèn)題和代碼模式問(wèn)題。比如,用 let 聲明了一個(gè)變量,但是這個(gè)變量在后面并沒(méi)有被重新賦值,因?yàn)闆](méi)有格式問(wèn)題,Prettier 會(huì)通過(guò),而 ESLint 則能發(fā)現(xiàn)這里應(yīng)該使用 const 聲明更好。
既然 ESLint 也能做格式化工具,那為什么還需要 Prettier?因?yàn)?ESLint 只能檢查 JavaScript 代碼以及 TypeScript、JSX 等衍生代碼(需配置解析器),無(wú)法檢查項(xiàng)目中的 CSS、HTML 等代碼。Prettier 則天然支持對(duì)大多數(shù)項(xiàng)目文件的格式化,包括 JSX、Vue、TypeScript、CSS、HTML、JSON、Markdown、YAML 等。
2.3. 同時(shí)使用 Prettier 和 ESLint
從上面可以看出,在 JavaScript 及其衍生語(yǔ)言的格式化上,ESLint 和 Prettier 是有重合的。所以,在實(shí)際運(yùn)用中,我們需要保證這些文件只會(huì)采用其中一種進(jìn)行格式化,避免不必要的格式化。更遭的情況是啟用了兩個(gè),而且兩個(gè)工具的風(fēng)格配置互相沖突。我就曾在項(xiàng)目中遇到這種情況,ESLint 格式化之后,Prettier 也執(zhí)行格式化,結(jié)果 ESLint 檢查還是不通過(guò)。
我推薦在 JavaScript 中也使用 Prettier。因?yàn)?ESLint 需要我們把風(fēng)格配置成 error 等級(jí),才會(huì)支持自動(dòng)修復(fù)。但是,這樣,一旦有格式問(wèn)題,編輯器就會(huì)標(biāo)紅,很煩人,強(qiáng)迫癥受不了,而 Prettier 不會(huì)有。下圖是一段只有風(fēng)格問(wèn)題的代碼在分別啟用這兩種工具時(shí)的編輯器顯示。
image.png
要同時(shí)使用二者,就需要關(guān)閉 ESLint 中可能和 Prettier 沖突的規(guī)則,而這就是?eslint-config-prettier[8]?所做的事。所以,想同時(shí)使用兩者,你需要在 ESLint 中使用該配置,具體的配置方式參考使用文檔即可。
如果你只想在 JavaScript 中使用 ESLint,可以在?.prettierignore
?中忽略所以的 JavaScript 文件即可。
3. Stylelint
顧名思義,Stylelint[9]?就是樣式代碼的 linter。
A mighty CSS linter that helps you avoid errors and enforce conventions.
它的功能和使用,都和 ESLint 類似,不過(guò)作用目標(biāo)不同而已。
和 Prettier 的區(qū)別在于,它和 ESLint 一樣,是一個(gè) linter,會(huì)進(jìn)行語(yǔ)義分析,能發(fā)現(xiàn)一些模式問(wèn)題。在 Stylelint 15 之前,如果同時(shí)使用 Stylelint 和 Prettier,也需要使用?stylelint-config-prettier[10]?避免在樣式文件上的規(guī)則沖突。Stylelint 15 廢棄了所有風(fēng)格規(guī)則,不會(huì)和 Prettier 沖突。
4. 工作流工具
將 linter/formatter 與一些工作流工具配合,能夠?qū)崿F(xiàn)團(tuán)隊(duì)規(guī)范的自動(dòng)化。
規(guī)范化原則是:越早發(fā)現(xiàn)不規(guī)范的代碼,改正的成本越低。
4.1. 編碼時(shí):編輯器支持
從編碼開(kāi)始,就推薦你啟用編輯器的代碼檢查功能,這可能是需要插件或者設(shè)置來(lái)實(shí)現(xiàn)。同時(shí),建議開(kāi)啟保存時(shí)自動(dòng)格式化,這能持續(xù)保證你的代碼是符合規(guī)范的。
4.2. 提交時(shí):Git hooks + lint-staged
Git pre-commit hook 可以讓我們?cè)谔峤恢皥?zhí)行一些命令,利用這點(diǎn),可以在提交前對(duì)代碼執(zhí)行代碼的 lint 檢查和格式化,自動(dòng)修復(fù)一些可以修復(fù)的問(wèn)題,如果有不可自動(dòng)修復(fù)的問(wèn)題,取消本次提交,從而,避免不規(guī)范的代碼被提交到代碼倉(cāng)庫(kù)。
默認(rèn)的 Git hook 不容易設(shè)置,社區(qū)中流行使用?husky[11]?進(jìn)行配置。
每次提交時(shí)的檢查應(yīng)該是針對(duì)當(dāng)前 commit 內(nèi)修改的內(nèi)容,而不是全部文件,也就是只檢查暫存區(qū)內(nèi)的文件。????lint-staged[12]可以實(shí)現(xiàn)這種效果。
具體的配置方式請(qǐng)參閱這兩個(gè)工具的文檔。
4.3. 交付時(shí):CI 集成
pre-commit 檢查可以通過(guò)?git commit \--no-verify
?跳過(guò),導(dǎo)致一些不規(guī)范的代碼被 push 到代碼倉(cāng)庫(kù)。
可以通過(guò) Gitlab-CI 或 Github Action 這類 CI 工具集成代碼檢查,在代碼被 push 到遠(yuǎn)程倉(cāng)庫(kù),或者 merge request 發(fā)起時(shí),執(zhí)行特定的任務(wù)對(duì)代碼發(fā)起檢查。
值得一提的是,CI 集成可以是整個(gè)代碼倉(cāng)庫(kù)統(tǒng)一的,這樣,可以實(shí)現(xiàn)公司層面的所有項(xiàng)目統(tǒng)一標(biāo)準(zhǔn),而不只是基于團(tuán)隊(duì)和項(xiàng)目。
5. 其它工具
5.1. commitlint:規(guī)范提交消息
commitlint \- Lint commit messages[13]?是規(guī)范提交消息(commit message)的一個(gè)工具,可以避免有些小伙伴就喜歡?git commit \-m "u"
,要求一個(gè)提交消息符合Conventional Commits[14]規(guī)范,即以下形式:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
復(fù)制代碼
commitlint 本身是一個(gè)命令行工具,用于判斷一個(gè)消息是否符合規(guī)范。
#?Lint?from?stdin
echo?'foo:?bar'?|?commitlint
????input:?foo:?bar
????type?must?be?one?of?[build,?chore,?ci,?docs,?feat,?fix,?perf,?refactor,?revert,?style,?test]?[type-enum]
????found?1?problems,?0?warnings
????Get?help:?https://github.com/conventional-changelog/commitlint/#what-is-commitlint
復(fù)制代碼
為了實(shí)現(xiàn)在 commit 時(shí)檢查消息,需要和 git commit-msg hook 配合。配合上面提到的 husky:
npx?husky?add?.husky/commit-msg??'npx?--no?--?commitlint?--edit?${1}'
復(fù)制代碼
5.2. branch-name-lint: 規(guī)范分支名
如果希望規(guī)范團(tuán)隊(duì)項(xiàng)目中的分支名稱,可以使用branch-name-lint[15]。
一般地,項(xiàng)目只需要規(guī)范成員 push 到遠(yuǎn)程倉(cāng)庫(kù)的分支名稱符合規(guī)范即可,不限制本地分支。按這個(gè)思路,可以利用 git pre-push hook:
npx?husky?add?.husky/pre-push??'npx?--no?--?branch-name-lint?<your-configuration.json>'
復(fù)制代碼
5.3. EditorConfig: 統(tǒng)一編輯器配置
EditorConfig[16]是一個(gè)跨編輯器/IDE 的編輯器配置工具。與 linter 和 formatter 不同,它的作用對(duì)象不是代碼,而是去約束編輯器的配置,比如縮進(jìn)風(fēng)格是 tab 還是空格,縮進(jìn)多少個(gè)字符。同時(shí)也說(shuō)明,它是作用于文件級(jí)別的,對(duì)代碼語(yǔ)法是無(wú)感的,對(duì)所有文件都生效。
許多編輯器都支持 EditorConfig,有的可能需要安裝插件,不需要項(xiàng)目安裝什么依賴包,只需要在根目錄下創(chuàng)建一個(gè)?.editorconfig
?文件。
EditorConfig 適用于團(tuán)隊(duì)成員中使用不同編輯器的場(chǎng)景。當(dāng)所有編輯器都使用項(xiàng)目根目錄下的?.editorconfig
?文件作為配置時(shí),能一定程度上保持代碼文件的統(tǒng)一性。
6. 總結(jié)
前端工程化的常見(jiàn)代碼規(guī)范工具有:
-
ESLint: 一個(gè)用于 JavaScript、JSX 等語(yǔ)言的可配置的代碼檢查工具。
-
Stylelint: 一個(gè) CSS/Less/Sass 等樣式代碼的 linter。
-
Prettier: 支持多種語(yǔ)言的代碼格式化工具。
-
Husky: 一個(gè)流行的用于配置 git hooks 的工具。
-
lint-staged: 對(duì)提交到暫存區(qū)的文件進(jìn)行檢查的工具。
-
EditorConfig: 統(tǒng)一不同編輯器配置的工具。
-
commitlint: 檢查提交消息是否符合規(guī)范。
-
branch-name-lint: 檢查代碼分支是否符合規(guī)范。
在使用中,要善于利用編輯器、git hooks、CI 工具來(lái)自動(dòng)化執(zhí)行代碼檢查和格式化。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-443529.html
最后,謹(jǐn)記,工具雖好,但不要一把梭,需要根據(jù)團(tuán)隊(duì)情況和項(xiàng)目情況選擇必要的幾個(gè)即可。實(shí)踐中,ESLint + Prettier + Husky + lint-staged 是大部分人的選擇。如果過(guò)分使用,會(huì)引入一些不必要的工作內(nèi)容和理解成本。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-443529.html
到了這里,關(guān)于前端開(kāi)發(fā)代碼規(guī)范工具的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!