寫在前面
團隊開發的專案,如果沒有對程式碼風格作要求,有多少團隊成員,就當然會出現多少種不同的程式碼風格。因此,我們需要一種能夠統一團隊程式碼風格的工具,作為強制性的規範,統一整個專案的程式碼風格。
幸好,我們有 eslint 和 prettier 。
eslint VS prettier
應該大多數專案都已經採用eslint來對程式碼進行質量檢查,可能少部分還會採用其進行一定程度上的統一風格。那為什麼還需要prettier呢?我們先來對它們作一個簡單的瞭解。
各種linters
總體來說,linters有兩種能力:
- 檢查程式碼質量,比如是否有已定義但未使用的變數,或者使用函數語言程式設計的函式是否產生副作用等。
- 檢查程式碼風格,比如每行的最大長度,或者是否使用拖尾逗號等。
其中,eslint文件中,帶扳手圖示的規則就是eslint能夠自動修復的規則。而不帶該圖示的規則,eslint則只能給出錯誤或警告,隨後由開發者人工修復。
prettier
pretter沒有對程式碼的質量進行檢查的能力,其只會對程式碼風格按照指定的規範進行統一,避免一個專案中出現多種不同的程式碼風格。
專案配置
此處使用vue專案作為例子
一、首先配置eslint
如果大家的專案是使用vue cli生成的,並且選擇使用eslint的話,那麼預設在專案根目錄下就會生成.eslintrc.js。如果沒有,也可以在專案根目錄下建立該檔案以及.eslintignore檔案
此處我使用eslint-plugin-vue,選擇的是vue/strongly-recommended規則。
npm install --save-dev eslint eslint-plugin-vue@next
複製程式碼
// .eslintrc.js
extends: {
'plugin:vue/strongly-recommended'
}
複製程式碼
// .eslintignore
/build/
/config/
/dist/
/*.js
/test/unit/coverage/
複製程式碼
如果希望在重新編譯的時候eslint自動修復程式碼,需要在webpack配置中加入eslint,並且設定fix: true
,並且在devserver中開啟eslint。
// config/index.js
module.exports = {
dev: {
useEslint: true,
}
}
複製程式碼
// webpack.base.conf.js
const createLintingRule = () => ({
test: /\.(js|vue)$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src'), resolve('test')],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay,
fix: true,
}
})
複製程式碼
二、配置prettier
由於使用eslint,並不能最大程度地統一程式碼風格,因此我們需要引入prettier。
npm install --save-dev prettier
複製程式碼
按照實際需要配置prettier
//prettier.config.js
module.exports = {
"printWidth": 80, // 每行程式碼長度(預設80)
"tabWidth": 2, // 每個tab相當於多少個空格(預設2)
"useTabs": false, // 是否使用tab進行縮排(預設false)
"singleQuote": true, // 使用單引號(預設false)
"semi": true, // 宣告結尾使用分號(預設true)
"trailingComma": "all", // 多行使用拖尾逗號(預設none)
"bracketSpacing": true, // 物件字面量的大括號間使用空格(預設true)
"jsxBracketSameLine": false, // 多行JSX中的>放置在最後一行的結尾,而不是另起一行(預設false)
"arrowParens": "avoid" // 只有一個引數的箭頭函式的引數是否帶圓括號(預設avoid)
};
複製程式碼
需要在package.json裡面配置呼叫prettier進行格式化的命令
// package.json
"scripts": {
"format": "prettier --write \"src/**/*.js\" \"src/**/*.vue\"",
}
複製程式碼
至此,可以在命令列中輸入npm run format對程式碼進行格式化了。
三、配置husky和lint-staged
由於直接使用prettier進行程式碼格式化仍存在一些弊端,例如:
- 一次性對所有檔案進行格式化,如果是專案中途加入prettier,會對一些早已經編寫完成的程式碼進行格式化,可能會造成衝突或者一些不可預知的問題,降低專案穩定性。
- 每次都要鍵入npm run format進行程式碼格式化,多了額外的操作,開發體驗不良好。
故此,我們可以修改程式碼格式化的時機,僅對本次提交的程式碼進行格式化,並且在程式碼提交之前進行格式化,確儲存入倉庫的程式碼都是格式化後的良好的程式碼。
husky是一款可以幫助我們使用git hooks的第三方庫,可以根據package.json檔案裡定義的鉤子和鉤子執行的命令將要執行的操作寫對應的鉤子指令碼里。
lint-staged,官方說明是一款可以對git提交的程式碼使用linter的第三方庫,其依賴於husky使用git hooks。此處我們不僅僅可以利用其呼叫linters,還可以呼叫prettier對程式碼進行格式化。
npm install --save-dev lint-staged husky
複製程式碼
// package.json
"scripts": {
"precommit": "lint-staged" // precommit鉤子執行lint-staged
},
"lint-staged": {
"src/**/*.{js,json,css,vue}": [
"prettier --write", // 先執行prettier,再執行eslint,保證程式碼質量
"eslint --fix",
"git add"
]
},
複製程式碼
四、同時使用eslint和prettier的配置
由於需要同時使用prettier和eslint,而prettier的一些規則和eslint的一些規則可能存在衝突,所以需要將eslint的一些可能與prettier發生衝突的程式碼格式化規則關閉。這裡使用eslint-plugin-prettier和eslint-config-prettier。
eslint-plugin-prettier可以將prettier的規則設定為eslint的規則,對不符合規則的進行提示。(與eslint-plugin-vue相同)
eslint-config-prettier可以關閉eslint可能與prettier發生衝突的程式碼格式化規則。官方稱eslint-plugin-prettier需要與eslint-config-prettier搭配食用才能獲得最佳效果。
npm install --save-dev eslint-plugin-prettier eslint-config-prettier
複製程式碼
// .eslintrc.js
module.exports = {
extends: [
'plugin:vue/strongly-recommended',
'plugin:prettier/recommended'
]
rules: {
"prettier/prettier": "error"
}
}
複製程式碼
經過上述配置,每次git commit的時候,都會先執行prettier以及eslint對程式碼進行格式化和質量檢查,確保程式碼沒有問題之後再提交
整體配置檔案
npm install -D prettier husky lint-staged eslint-config-prettier eslint-plugin-prettier
複製程式碼
// package.json
{
"scripts": {
"format": "prettier --write \"src/**/*.js\" \"src/**/*.vue\"",
"precommit": "lint-staged"
},
"lint-staged": {
"src/**/*.{js,json,css,vue}": [
"prettier --write",
"eslint --fix",
"git add"
]
},
"devDependencies": {
"eslint": "^4.15.0",
"eslint-config-prettier": "^2.9.0",
"eslint-plugin-prettier": "^2.6.2",
"eslint-plugin-vue": "^4.0.0",
"husky": "^0.14.3",
"lint-staged": "^7.2.0",
"prettier": "^1.14.2",
},
}
複製程式碼
// eslintrc.js
// https://eslint.org/docs/user-guide/configuring
module.exports = {
extends: [
'plugin:vue/strongly-recommended',
'plugin:prettier/recommended'
],
// add your custom rules here
rules: {
// ...other codes
"prettier/prettier": "error"
}
}
複製程式碼
//prettier.config.js
module.exports = {
"printWidth": 80, // 每行程式碼長度(預設80)
"tabWidth": 2, // 每個tab相當於多少個空格(預設2)
"useTabs": false, // 是否使用tab進行縮排(預設false)
"singleQuote": true, // 使用單引號(預設false)
"semi": true, // 宣告結尾使用分號(預設true)
"trailingComma": "all", // 多行使用拖尾逗號(預設none)
"bracketSpacing": true, // 物件字面量的大括號間使用空格(預設true)
"jsxBracketSameLine": false, // 多行JSX中的>放置在最後一行的結尾,而不是另起一行(預設false)
"arrowParens": "avoid" // 只有一個引數的箭頭函式的引數是否帶圓括號(預設avoid)
};
複製程式碼
寫在最後
一般IDE整合了eslint或者prettier工具的話,會預設根據專案根目錄下相關配置檔案進行程式碼檢查。
如果使用vscode,vetur的預設程式碼風格化使用的就是prettier,會自動檢索專案根目錄下的prettier配置檔案進行格式化。eslint檢索工具推薦使用eslint外掛,安裝後也會自動檢索eslint配置檔案進行程式碼檢查,非常方便。
以上就是我對規範程式碼風格的實踐,參考了各家的實踐,並且制定了符合專案實際的規範。
如果有更好更便捷的統一程式碼風格的方式,請不吝告知,謝謝!