前端工程化之 ESLint + Prettier
前言
對於前端專案而言,如果是一人團隊、自己處理所有的code,那其實愛怎麼寫就怎麼寫、程式跑得動就好;但如果是多人協作的團隊、甚至是要跟外包的人協作,如果沒有事先訂好基本的前端規範,輕則不知道該導入的組件在哪裡、需要的函數要去哪裡找,重則難以閱讀該代碼塊、導致該代碼只能由寫出它的工程師來維護修改(俗稱Legacy Code)。
而在專案一開始就建立清晰的代碼規範,不但能夠讓程式碼的可閱讀性有一定的保障、更加易於維護,更可以減少在code review
時的一些爭議(團隊裡和氣最重要是吧?)
而前端規範,最基本的就是Eslint
和Prettier
的設置,一個是程式碼規範的檢查器,一個是程式碼格式化的工具。
基本Eslint和Prettier設置
依賴安裝
在同時使用Eslint
和Prettier
時,「程式碼質量」和「程式碼格式化」兩者的一些設置會造成衝突。如下圖:
(image from logrocket)
因此需要先解決這個衝突問題。所需要的npm dependency為 eslint
、eslint-plugin-prettier
、eslint-config-prettier
、prettier
npm i -D eslint eslint-plugin-prettier eslint-config-prettier prettier
而各自依賴的作用如下表所示:
依賴 | 作用 |
---|---|
eslint | Eslint核心庫 |
eslint-plugin-prettier | 將 Prettier 的規則以plugin的形式加入到Elsint裡面 |
eslint-config-prettier | 關掉所有和 Prettier 衝突的 ESLint 的配置 |
prettier | Prettier核心庫 |
eslint和prettier設定
安裝好之後,在專案的根目錄下新增.eslintrc.js
(也是可以用.eslintrc.json
,但JSON檔沒辦法加註釋,所以比較偏好使用.js),再根據 eslint-plugin-prettier 官方的推薦,在.eslintrc.js
中撰寫
module.exports = {
//如果有其他extends的話,要記得把prettier放最後一個
"extends": ["plugin:prettier/recommended"]
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error"
}
}
之後,如果要新增prettier的規則(如:tab=4space),便可以改寫在"rules"
下的prettier選項:
"prettier/prettier":[
"error",
{
tabWidth: 4,
}
]
或者直接在根目錄中新增檔案.prettierrc
,把規則寫在裡面。
補充:.eslintrc.js
中的其他設定項目
module.exports = {
env: {},
extends: [],
overrides: [],
parser: '',
parserOptions:{},
plugins: [],
rules: {},
settings: {},
}
- env:定義環境,可以讓Eslint知道有哪些可用的環境變數,完整文檔可以查看官網,常見的有
- browser—瀏覽器全局變量,如window
- node—NodeJS全局變量
- es6—ECMAScript 6 功能
- jest—Jest 全局變量
- extends:根據指定的規範,去檢查指定類型的檔案,如根據
@typescript-eslint/recommended
去檢查ts程式碼。extends裡面的項目,可以看作「引入別人配置好的.eslintrc.js
」- 如果規則有衝突,後面的會覆蓋前面的。所以官方才建議把
prettier
放在最後一項。
- 如果規則有衝突,後面的會覆蓋前面的。所以官方才建議把
- plugins:在Eslint中使用第三方plugin,需要自己手動先npm安裝;可以理解為「加載了插件」,但要在
extends
和rules
定義後才會生效 rules:套用的規則。
假設npm下載了
@typescript-eslint/eslint-plugin
,該如何配置extend、plugin、rule?{ "plugins": [ "@typescript-eslint" // 插件聲明 ], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended" // 這裏是對修改插件下的某一類配置對象的引用。 ], "rules": { "@typescript-eslint/rule-name": "error" // 對具體@typescript-eslint插件下的某個規則的使用 } }
overrides:讓一組文件(通常是看檔案名稱的命名規則)不受規則檢查、或者使用另一種規則來檢查
讓xxx.test.js檔案禁用某個規則
"rules": {...}, "overrides": [ { "files": ["*-test.js","*.spec.js"], "rules": { "no-unused-expressions": "off" } } ]
parser:Eslint會對程式碼進行檢查,parser的作用是把程式碼轉換成ESTree,然後Eslint再對ESTree再進行檢查校驗。
parserOptions:對parser的補充。如預設的 ESLint 並沒有支援所有最新的 ES6 語法,因此若有需要可以加上
{ "parserOptions": { "ecmaVersion": 6 } }
的設定。Eslint對ts進行解析的設置:
parser: '@typescript-eslint/parser', parserOptions: { ecmaVersion: 'latest', sourceType: 'module', },
settings:目前的使用場景,是在專案中有利用
webpack.config.js
或tsconfig.json
使用別名import(ex: import xxx from “@/compoments/xxx”),而造成Eslint報錯。在這情況下可以使用settings來解決Unable to resolve path to module
的問題利用
webpack.config.js
設定路徑別名時,先npm安裝eslint-import-resolver-webpack
,在.eslintrc.js
中修改settings:"settings": { "import/resolver": { "webpack":{ "config":"webpack.config.js" } } }
VS-code設定
假設專案團隊裡面的成員所使用的IDE都是vscode,可以設置在每次的 on save 時,vscode自動修正 Eslint 和 Prettier 的錯誤:
- 在專案root目錄下新增資料夾
.vscode
- 在該資料夾內新增
settings.json
撰寫該JSON檔:
{ "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, "eslint.alwaysShowStatus": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "editor.formatOnSave": true }
("[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
這一項,是為了eslint可以format到根目錄的一些js檔,如webpack.config.js等等)
結語
基本上,Eslint+Prettier的設置就完成、接下來就是看團隊共識了。
之後,我們會來看看在Vue/React + Typescript的專案中,還需要多些什麼設置。
ChangeLog
- 20220911-新增結語
- 20220901-初稿