前端工程化:有效地進行拼寫檢查
拼寫錯誤導致的問題
在專案開發過程中,即使我們再細心,也難免忙中出錯,犯下很多低階的錯誤。
比如這樣:
我們錯把 field 拼寫成 filed,這樣打印出來的是 undefined,而不是預期的 name。
ESLint 的基本介紹
但是幸運的是,有一些 Lint 工具會在這方面提供一些幫助。
比如在 TypeScript 中,會有一個錯誤提示。雖然這個提示提供的訊息並不是我們需要的。
當然我們可以選擇一些更專業的 Linter 來完成這項工作。
目前來說,最流行的 JavaScript Linter 是 ESLint。
如果配合 VSCode 這個編輯器使用的話,可以安裝 vscode-eslint 這個外掛。
然後在專案的根目錄下建立 .eslintrc.js 檔案,編寫一些配置。
javascript
/** @type {import('eslint').Linter.Config} */
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
rules: {
"no-undef": ["error"],
},
};
env 屬性指定專案的執行環境。
rules 是具體的規則。
no-undef 這條規則的意思是不可以使用未定義的變數。
no-undef 屬性的值是一個數組,陣列的第一個元素是這條規則的級別。
ESLint 中的所有規則都有 3 個等級,off 表示關閉,wran 表示開啟和 error 表示錯誤。
你可以根據自己對程式碼要求的嚴格程度自定義規則等級。
當我們配置好了這條規則之後,編輯器的錯誤提示就會發生變化。
ESlint 會給我們提示 filed 這個變數沒有被定義,而被直接使用了。
這樣就可以幫助我們發現這個問題,從而更早的解決掉這個問題。
這是一種比較容易發現的問題。
宣告變數時的單詞拼寫錯誤
另一個更加隱祕晦澀的錯誤是,我們在定義變數時就把變數的單詞拼寫錯了。
比如下面這樣:
這種問題 ESLint 是沒有辦法檢測到的,而且真正執行起來也不會有什麼問題。
最大的問題在於維護。
假設這段程式碼的維護者換成了別人,他很難一眼看出這段程式碼究竟在表達什麼意思。
filed?是檔案的過去式,表達的意思是歸檔嗎?
他壓根就不可能會朝 field,也就是欄位的含義上去考慮。
這會讓接下來的整個邏輯流程閱讀起來變得非常費解。
這種問題屬於根源性的問題。
人工解決方案
解決辦法當然存在,建立業務術語表,然後經過人工程式碼審查(CodeReview)。
但是,人在真正意義上是不靠譜的。
即使再強大、再細緻的人,也會有焦急、疲倦、鬆懈的時候。所以即使是通過人工程式碼審查後的程式碼,也未必不會存在上面提到的這種問題。
機器解決方案
那麼能夠有一種更好的方式來避免這類問題呢?
比如能否依靠在真正意義上靠譜的機器來協助人類做這件事情?
當然是可以的。
ESLint 有一套外掛機制,可以通過外掛來擴充套件 ESLint 原本的功能。
其中有一個比較常用的外掛,eslint-plugin-spellcheck。
這個外掛的作用是幫助我們檢查單詞的拼寫錯誤。
安裝也非常簡單。
bash
npm install eslint-plugin-spellcheck
之後需要更新 ESLint 的配置。
javascript
/** @type {import('eslint').Linter.Config} */
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
plugins: [
"spellcheck",
],
rules: {
"no-undef": ["error"],
"spellcheck/spell-checker": ['warn']
},
};
這樣就可以對程式碼中單詞拼寫錯誤的。
拼寫錯誤與意圖表達錯誤
但是,講了這麼多,像上面提到的反例,spell-checker 仍然是無能為力的。
為什麼呢?因為上面提到的反例,表面上看只有一個錯誤,但無形之中還存在另一個錯誤。
- 拼寫錯誤,field 拼寫成了 filed。
- filed 仍然是個正確的單詞。如果將 filed 認為是一個正確的單詞,那麼第二個錯誤將是意圖表達錯誤。
機器只能解決拼寫錯誤,但是意圖表達錯誤這類問題明顯超越了機器目前的能力邊界。
所以我們可以把反例稍微改一下。
filde 不是一個合法單詞,所以就得到 spell-checker 的警告提示。
spell-checker 的實現原理
spell-checker 的實現原理就是羅列出超過 4 萬個英文單詞進行匹配,如果不在這個範圍內的英文單詞就認為是拼寫錯誤。
當然我們也可以擴充套件這個單詞列表。
ESLinter 的 rules 中屬性值都是一個數組。第一個元素是規則級別,第二個元素就是一個物件,表示這個規則對應的配置項。
spell-checker 的配置項中有一個 skipWords,表示可以跳過一些單詞。
跳過特殊單詞
比如你在使用 ESModule 的方式來開發應用,其中用到了 Vue 這個庫。
我們需要在 .eslintrc.js 中新增一項配置,讓 ESLint 的直譯器以模組的方式解釋程式碼。
javascript
module.exports = {
// ...
parserOptions: {
sourceType: 'module'
}
}
但是 Vue 並不是一個合法的單詞。
我們就可以通過配置這個配置項來跳過對 Vue 的檢測。
javascript
module.exports = {
rules: {
"spellcheck/spell-checker": [
"warn",
{
skipWords: ["Vue"],
},
],
}
這樣程式碼就不會再出現警告了。
但是到目前為止,問題還是沒有完全解決。
因為一些庫中提供的 API 仍然不是合法單詞。比如 Teleport。
我們可以選擇手動新增 Teleport 這個單詞到 skipWords 中。
但問題是,Vue 中仍然提供了很多 API 不在合法單詞範圍內,比如 withCtx:
如果我們碰到哪個單詞就朝 skipWords 裡面新增哪個單詞,在使用的庫比較少的時候還可以接受。如果我們的專案中依賴了大量的庫,而這些庫中又存在了大量的不合法單詞 API,這會讓我們感到非常的繁瑣和痛苦。
另外一個問題就是,Node.js 很多內建模組的 API 同樣不是合法單詞。比如常用的 fs 和 readdir。
那有沒有什麼方法可以解決上面的兩個問題呢?
答案是有的。
modules-words
modules-words 是一個獲取模組 API 單詞的庫,通過這個庫配合 spell-checker 可以很好的幫助我們跳過很多第三方模組或者 Node.js 內建模組的 API 單詞檢查。
首先安裝這個模組。
bash
npm add modules-words --save-dev
之後修改 .eslintrc.js 配置檔案。
```javascript
const { getWords, getGlobalWords } = require("modules-words");
/* @type {import('eslint').Linter.Config} / module.exports = { // ... rules: { // ... "spellcheck/spell-checker": [ "warn", { skipWords: ["", ...getWords("vue"), ...getGlobalWords()], }, ], }, }; ``` 通過 modules-words 提供的 getWords 和 getGlobalWords 兩個函式,成功地將專案中可能使用到的單詞過濾出來,讓 spell check 能夠以更加符合我們預期的方式執行。
- 絲滑的 ChatGPT:探索 Web3 與 ChatGPT 的完美結合!
- 作為一個學會智慧合約的前端開發者,該如何找到 Web3 工作?
- 還在考慮要不要加入Web3?Web3求職全攻略
- 8年了,Web3到底給這個世界帶來了什麼?
- 揭祕web3元宇宙千萬級專案的財富密碼:憑什麼一個div賣一千塊?
- 聊聊Web3為什麼能賺錢?為什麼不要All in Web3?
- 一文聊透 Solidity 語法:助你成為智慧合約專家
- 24 歲技術人不太平凡的一年
- 為什麼不要在 useEffect 中進行 API 呼叫?
- 前端小白的幾個壞習慣
- 2022年能讓你早點下班的36個JavaScript實用函式!
- 你到底懂不懂JavaScript?來做做這12道面試題試試!
- 50 VSCode外掛,幫你打造地表最強IDE!
- 前端框架大比拼:2022年的Vue與React誰更勝一籌?
- 你需要知道的 12 個常用的 JavaScript 函式
- RxJS系列04:操作符 Operators(上)
- 前端工程化:有效地進行拼寫檢查
- Golang 定時器詳解
- 使用 Vue 和 Gridsome 構建靜態站點
- 聊聊程式中的隨機數