具備基本工程素養(yǎng)的同學都會注重編碼規(guī)范,而代碼風格檢查(Code Linting椿争,簡稱 Lint)是保障代碼規(guī)范一致性的重要手段怕膛,你的工作流中有 Lint 環(huán)節(jié)么?有的話你用的爽么秦踪?你在團隊中推廣過 Lint嘉竟,但是大家都不買賬?究竟是為啥?
Lint 是什么舍扰?
探討怎么做之前倦蚪,我們很有必要給 Lint 來個清晰、準確的定義边苹,wikipedia 的定義如下:
In computer programming, lint is a Unix utility that flags some suspicious and non-portable constructs (likely to be bugs) in C language source code; generically, lint or a linter is any tool that flags suspicious usage in software written in any computer language. The term lint-like behavior is sometimes applied to the process of flagging suspicious language usage. Lint-like tools generally perform static analysis of source code.
簡單來說陵且,Lint 就是對代碼做靜態(tài)分析,并試圖找出潛在問題的工具个束,實戰(zhàn)中我們也用 Lint 來指使用工具的過程慕购。
為什么要 Lint?
使用 Lint 會有什么好處呢茬底?在我看來至少具有如下 3 點:
- 更少的 Bug沪悲,劍橋大學的研究發(fā)現(xiàn),全世界每年因為軟 Bug 造成的經(jīng)濟損失約 3120 億美金阱表;
- 更高的開發(fā)效率殿如,工程師平均會花掉 50% 的工作時間定位和解決各種 Bug,其中不乏那些顯而易見的低級錯誤最爬,而 Lint 很容易發(fā)現(xiàn)低級的涉馁、顯而易見的錯誤;
- 更高的可讀性爱致,代碼可讀性的首要因子是“表面文章”烤送,表面上看起來亂糟糟的代碼通常更難讀懂;
可以毫不客氣的說糠悯,如果你不做 Lint帮坚,就是在浪費自己的時間,浪費公司的資源互艾。既然做 Lint 的預期效果很好叶沛?該怎么做呢?
提交后 Lint:反饋鏈條太長忘朝?
說到怎么做灰署,多數(shù)人會自然而然的想到各種 Lint 工具,目前社區(qū)中針對各種語言都開發(fā)了 Lint 工具局嘁,前端能用到的就有大把:ESLint溉箕、Standard、SCSSLint悦昵、JSONLint肴茄、HTMLHint 等。GitHub 官方出品的 Lint 工具列表 也是個非常不錯的參考但指。
很多同學選擇在持續(xù)集成階段(后文用 CI 代稱)做 Lint寡痰,比如使用遠程的 Git Hooks 來觸發(fā)抗楔。但是從實際的經(jīng)歷來看,這種做法的反饋鏈條通常如下:
代碼提交 --> 發(fā)現(xiàn)問題(遠程) --> 修復問題 --> 重新提交 --> 通過檢查(遠程)
整個過程可能會浪費掉你不少時間拦坠,畢竟 CI 過程通常不僅是在做 Lint连躏,如果你是那種不知道自己時間每天都去哪兒了的工程師,可以反思下自己或者團隊的工作流是否是這樣贞滨。并且入热,請相信我,你不是少數(shù)人晓铆。
你有沒有這樣的經(jīng)歷:吭哧吭哧寫了幾天代碼勺良,各種驗收都通過了,最后被 CI 拒絕骄噪,竟是因為你的代碼中少加了一個逗號尚困,這時候心情簡直崩潰到無法形容:
從 GitHub 上各種修復 Lint 的提交數(shù)量不難發(fā)現(xiàn)工程師在修復 Lint 問題上浪費的時間,比如搜索 "fix lint"链蕊,多達 45W 次提交:
再比如搜索 “fix indent”事甜,多達 226W 次提交,是不是很觸目驚心示弓?
只在 CI 流程做 Lint 的缺點也是顯而易見的:
- Lint 在整個開發(fā)工作流中的反饋鏈條太長讳侨,浪費時間呵萨、注意力和資源奏属,最致命的;
- CI 流程搭建成本比較高潮峦,即使有各種 CI 服務囱皿,步驟也還是比較繁瑣;
我們該怎么改進忱嘹?
提交前 Lint:錯誤信息不相關(guān)嘱腥?
為了縮短 Lint 的反饋鏈條,把 Lint 挪到本地是最有效的辦法拘悦。常見做法是使用 husky 或者 pre-commit 在本地提交之前做 Lint齿兔。
使用 husky 的具體做法如下:
首先,安裝依賴:
npm install -D husky
yarn add --dev husky
然后修改 package.json础米,增加配置:
{
"scripts": {
"precommit": "eslint src/**/*.js"
}
}
最后嘗試 Git 提交分苇,你就會很快收到反饋:
git commit -m "Keep calm and commit"
但是在遺留代碼倉庫上工作的同學很快會遇到新的問題,開啟 Lint 初期屁桑,你可能會面臨成千上萬的 Lint Error 需要修復医寿。部分同學對下面這個圖可能并不陌生:只改了文件 A,但是文件 B蘑斧、C靖秩、D 中也有大量錯誤须眷。
把整個倉庫都格式化不失為一種選擇,但是實際上需要很大的勇氣沟突。多數(shù)人在項目中運用新工具都希望是漸進式的花颗,而不是推到重來式的,因為相比而言事扭,業(yè)務系統(tǒng)穩(wěn)定是更重要的事情捎稚。簡單的把 Lint 挪到本地,反饋鏈條是縮短了求橄,但是面對每次改動今野,工具還是給出了太多不相關(guān)的信息,這無疑與小步快跑的互聯(lián)網(wǎng)節(jié)奏是相違背的罐农。
該怎么破条霜?
只 Lint 改動的:66666
如果把 Lint 挪到本地,并且每次提交只檢查本次提交所修改的文件涵亏,上面的痛點就都解決了宰睡。Feedly 的工程師 Andrey Okonetchnikov 開發(fā)的 lint-staged 就是基于這個想法,其中 staged 是 Git 里面的概念气筋,指待提交區(qū)拆内,使用 git commit -a
,或者先 git add
然后 git commit
的時候宠默,你的修改代碼都會經(jīng)過待提交區(qū)麸恍。
lint-staged 用法如下:
首先,安裝依賴:
npm install -D lint-staged
yarn add --dev lint-staged
然后搀矫,修改 package.json 配置:
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"src/**/*.js": "eslint"
}
}
最后抹沪,嘗試提交的效果:
實際上,lint-staged 給了你提交前代碼操作的更大自由度瓤球,比如使用下面的配置融欧,自動修復錯誤:
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"src/**/*.js": ["eslint --fix", "git add"]
}
}
或者使用下面的配置,自動格式化代碼(謹慎使用):
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"src/**/*.js": ["prettier --write", "git add"]
}
}
此外卦羡,lint-staged 和 prettier 已經(jīng)集成到 create-react-app 中了噪馏。你是不是也應該好好打磨下自己的 Lint 工作流了?
總結(jié)
有人說前端攻城獅是世界上最奇怪的動物绿饵,提交代碼時用 prettier 把代碼排版的很美觀欠肾,但部署上線時又使用 uglify 把代碼壓縮的連親媽都不認了,事實是蝴罪,如果我們寫出來的代碼本來就很丑陋董济,就根本不需要用 uglify。希望讀到這里的你能把 Lint 工作流打磨到極致要门,把更多時間專注在解決真正的問題上虏肾,成為真正高效的工程師廓啊。
One More Thing
本文作者王仕軍,商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)封豪,非商業(yè)轉(zhuǎn)載請注明出處谴轮。如果你覺得本文對你有幫助,請點贊吹埠!如果對文中的內(nèi)容有任何疑問第步,歡迎留言討論。想知道我接下來會寫些什么缘琅?歡迎訂閱我的掘金專欄或知乎專欄:《前端周刊:讓你在前端領(lǐng)域跟上時代的腳步》粘都。