隨著項(xiàng)目的不斷增加螃壤,急切需要統(tǒng)一每個(gè)項(xiàng)目的代碼規(guī)范,將一些低級(jí)錯(cuò)誤在萌芽狀態(tài)下掐死筋帖。所以特此結(jié)合當(dāng)前項(xiàng)目使用的一些規(guī)范奸晴,再根據(jù)社區(qū)推薦的規(guī)范,整合成這個(gè)repo日麸。里面集成了React和Nodejs的編程規(guī)范寄啼,所有的規(guī)范都是基于airbnb,里面細(xì)分了js版本和ts版本代箭,滿(mǎn)足大家的編程需求墩划。
另外其他框架的代碼規(guī)范沒(méi)有實(shí)際項(xiàng)目經(jīng)驗(yàn),所以沒(méi)能集齊所有”龍珠“嗡综,因此在此歡迎大家貢獻(xiàn)出平時(shí)使用的標(biāo)準(zhǔn)編碼規(guī)范(盡量是基于airbnb的)乙帮,共享給社區(qū)其他童鞋。
Eslint生態(tài)依賴(lài)包介紹
在說(shuō)明Eslint配置之前极景,我們先來(lái)掌握Eslint配置的生態(tài)圈中涉及到的一些依賴(lài)包的作用察净,這樣我們方可以知其所以然。
最基礎(chǔ)
- eslint: lint代碼的主要工具盼樟,所以的一切都是基于此包
解析器(parser)
babel-eslint: 該依賴(lài)包允許你使用一些實(shí)驗(yàn)特性的時(shí)候氢卡,依然能夠用上Eslint語(yǔ)法檢查。反過(guò)來(lái)說(shuō)晨缴,當(dāng)你代碼并沒(méi)有用到Eslint不支持的實(shí)驗(yàn)特性的時(shí)候是不需要安裝此依賴(lài)包的译秦。
@typescript-eslint/parser: Typescript語(yǔ)法的解析器,類(lèi)似于
babel-eslint
解析器一樣。對(duì)應(yīng)parserOptions
的配置參考官方的README诀浪。
擴(kuò)展的配置
eslint-config-airbnb: 該包提供了所有的Airbnb的ESLint配置棋返,作為一種擴(kuò)展的共享配置,你是可以修改覆蓋掉某些不需要的配置的雷猪,該工具包包含了react的相關(guān)Eslint規(guī)則(eslint-plugin-react與eslint-plugin-jsx-a11y)睛竣,所以安裝此依賴(lài)包的時(shí)候還需要安裝剛才提及的兩個(gè)插件
eslint-config-airbnb-base: 與上一個(gè)包的區(qū)別是,此依賴(lài)包不包含react的規(guī)則求摇,一般用于服務(wù)端檢查射沟。
eslint-config-jest-enzyme: jest和enzyme專(zhuān)用的校驗(yàn)規(guī)則,保證一些斷言語(yǔ)法可以讓Eslint識(shí)別而不會(huì)發(fā)出警告与境。
eslint-config-prettier: 將會(huì)禁用掉所有那些非必須或者和prettier沖突的規(guī)則验夯。這讓您可以使用您最喜歡的shareable配置,而不讓它的風(fēng)格選擇在使用Prettier時(shí)礙事摔刁。請(qǐng)注意該配置只是將規(guī)則off掉,所以它只有在和別的配置一起使用的時(shí)候才有意義挥转。
插件
eslint-plugin-babel: 和babel-eslint一起用的一款插件.babel-eslint在將eslint應(yīng)用于Babel方面做得很好,但是它不能更改內(nèi)置規(guī)則來(lái)支持實(shí)驗(yàn)性特性共屈。eslint-plugin-babel重新實(shí)現(xiàn)了有問(wèn)題的規(guī)則绑谣,因此就不會(huì)誤報(bào)一些錯(cuò)誤信息
eslint-plugin-import: 該插件想要支持對(duì)ES2015+ (ES6+) import/export語(yǔ)法的校驗(yàn), 并防止一些文件路徑拼錯(cuò)或者是導(dǎo)入名稱(chēng)錯(cuò)誤的情況
eslint-plugin-jsx-a11y: 該依賴(lài)包專(zhuān)注于檢查JSX元素的可訪問(wèn)性。
eslint-import-resolver-webpack: 可以借助webpack的配置來(lái)輔助eslint解析拗引,最有用的就是alias借宵,從而避免unresolved的錯(cuò)誤
eslint-import-resolver-typescript:和eslint-import-resolver-webpack類(lèi)似,主要是為了解決alias的問(wèn)題
eslint-plugin-react: React專(zhuān)用的校驗(yàn)規(guī)則插件.
eslint-plugin-jest: Jest專(zhuān)用的Eslint規(guī)則校驗(yàn)插件.
eslint-plugin-prettier: 該插件輔助Eslint可以平滑地與Prettier一起協(xié)作矾削,并將Prettier的解析作為Eslint的一部分壤玫,在最后的輸出可以給出修改意見(jiàn)。這樣當(dāng)Prettier格式化代碼的時(shí)候哼凯,依然能夠遵循我們的Eslint規(guī)則欲间。如果你禁用掉了所有和代碼格式化相關(guān)的Eslint規(guī)則的話,該插件可以更好得工作断部。所以你可以使用eslint-config-prettier禁用掉所有的格式化相關(guān)的規(guī)則(如果其他有效的Eslint規(guī)則與prettier在代碼如何格式化的問(wèn)題上不一致的時(shí)候括改,報(bào)錯(cuò)是在所難免的了)
@typescript-eslint/eslint-plugin:Typescript輔助Eslint的插件。
eslint-plugin-promise:promise規(guī)范寫(xiě)法檢查插件家坎,附帶了一些校驗(yàn)規(guī)則。
輔助優(yōu)化流程
husky: git命令hook專(zhuān)用配置.
lint-staged: 可以定制在特定的git階段執(zhí)行特定的命令吝梅。
Prettier
Prettier相關(guān)的包有好多個(gè)虱疏,除了上面列舉的兩個(gè),你可能還會(huì)用到下面的三個(gè):
prettier:原始實(shí)現(xiàn)版本苏携,定義了prettier規(guī)則并實(shí)現(xiàn)這些規(guī)則做瞪。支持的規(guī)則參考:傳送門(mén)
prettier-eslint:輸入代碼,執(zhí)行prettier后再eslint --fix輸出格式化后的代碼。僅支持字符串輸入装蓬。
prettier-eslint-cli:顧名思義著拭,支持CLI命令執(zhí)行prettier-eslint的操作
那么Prettier這么多工具包,都是些什么關(guān)系呢牍帚?太容易讓人混淆了儡遮。這里用一段話簡(jiǎn)單介紹一下:
最基礎(chǔ)的是prettier,然后你需要用eslint-config-prettier去禁用掉所有和prettier沖突的規(guī)則暗赶,這樣才可以使用eslint-plugin-prettier去以符合eslint規(guī)則的方式格式化代碼并提示對(duì)應(yīng)的修改建議鄙币。為了讓prettier和eslint結(jié)合起來(lái),所以就誕生了prettier-eslint這個(gè)工具蹂随,但是它只支持輸入代碼字符串十嘿,不支持讀取文件,因此又有了prettier-eslint-cli
這就是5個(gè)工具包互相之間的關(guān)系岳锁。加上prettier之后的提示可讀性高一點(diǎn)绩衷,如下圖:
Eslint配置文件
-
env: 預(yù)定義那些環(huán)境需要用到的全局變量,可用的參數(shù)是:
es6
激率、broswer
咳燕、node
等。es6
會(huì)使能所有的ECMAScript6的特性除了模塊(這個(gè)功能在設(shè)置ecmaVersion版本為6的時(shí)候會(huì)自動(dòng)設(shè)置)browser
會(huì)添加所有的瀏覽器變量比如Windowsnode
會(huì)添加所有的全局變量比如global
更多環(huán)境配置參考Specifying Environments
extends: 指定擴(kuò)展的配置柱搜,配置支持遞歸擴(kuò)展迟郎,支持規(guī)則的覆蓋和聚合。
plugins: 配置那些我們想要Linting規(guī)則的插件聪蘸。
parser: 默認(rèn)ESlint使用Espree作為解析器宪肖,但是一旦我們使用babel的話,我們需要用babel-eslint健爬。
-
parserOptions: 當(dāng)我們將默認(rèn)的解析器從Espree改為babel-eslint的時(shí)候桐早,我們需要指定parseOptions,這個(gè)是必須的鹃答。
ecmaVersion: 默認(rèn)值是5礁蔗,可以設(shè)置為3、5设拟、6慨仿、7、8纳胧、9镰吆、10,用來(lái)指定使用哪一個(gè)ECMAScript版本的語(yǔ)法跑慕。也可以設(shè)置基于年份的JS標(biāo)準(zhǔn)万皿,比如2015(ECMA 6)
sourceType: 如果你的代碼是ECMAScript 模塊寫(xiě)的摧找,該字段配置為
module
,否則為script
(默認(rèn)值)ecmaFeatures:該對(duì)象指示你想使用的額外的語(yǔ)言特性
globalReturn:允許全局范圍內(nèi)的`return`語(yǔ)句 impliedStrict:使能全局`strict`模式 jsx:使能JSX
rules: 自定義規(guī)則牢硅,可以覆蓋掉extends的配置蹬耘。
settings:該字段定義的數(shù)據(jù)可以在所有的插件中共享。這樣每條規(guī)則執(zhí)行的時(shí)候都可以訪問(wèn)這里面定義的數(shù)據(jù)
更多配置選項(xiàng)參考官方文檔Eslint
Eslint配置文件解析
介紹了這么多减余,我們以模板提供的一個(gè)配置例子eslint-react-js來(lái)說(shuō)(說(shuō)明都寫(xiě)在注釋里了~):
module.exports = {
parser: 'babel-eslint', // Specifies the ESLint parser
parserOptions: {
ecmaVersion: 2015, // specify the version of ECMAScript syntax you want to use: 2015 => (ES6)
sourceType: 'module', // Allows for the use of imports
ecmaFeatures: {
jsx: true, // enable JSX
impliedStrict: true // enable global strict mode
}
},
extends: [
'airbnb', // Uses airbnb, it including the react rule(eslint-plugin-react/eslint-plugin-jsx-a11y)
'plugin:promise/recommended',
// 'prettier', // Use prettier, it can disable all rules which conflict with prettier
// 'prettier/react' // Use prettier/react to pretty react syntax
],
settings: {
'import/resolver': { // This config is used by eslint-import-resolver-webpack
webpack: {
config: './webpack/webpack-common-config.js'
}
},
},
env: {
browser: true // enable all browser global variables
},
'plugins': ['react-hooks', 'promise'], // ['prettier', 'react-hooks']
rules: {
// Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
// e.g. '@typescript-eslint/explicit-function-return-type': 'off',
"react-hooks/rules-of-hooks": "error",
"semi": ["error", "never"],
"react/jsx-one-expression-per-line": 0,
/**
* @description rules of eslint-plugin-prettier
*/
// 'prettier/prettier': [
// 'error', {
// 'singleQuote': true,
// 'semi': false
// }
// ]
},
};
因?yàn)槲覀冊(cè)诖a的保存以及提交階段都會(huì)進(jìn)行prettier的格式化综苔,所以在Eslint中禁用掉了所有跟prettier的配置,如果你需要的話佳励,可以重新enable掉休里。
下面對(duì)比一下打開(kāi)prettier和沒(méi)有打開(kāi)prettier的區(qū)別:
和
Prettier影響的規(guī)則
上面prettier介紹了那么多,那么這小節(jié)簡(jiǎn)單介紹以下prettier的一些重要的的規(guī)則:
- printWidth: 確保你的代碼每行的長(zhǎng)度不會(huì)超過(guò)100個(gè)字符
- singleQuote: 轉(zhuǎn)換所有的雙引號(hào)為單引號(hào)
- trailingComma: 確保對(duì)象的最后一個(gè)屬性后會(huì)有一個(gè)逗號(hào)
- bracketSpacing: 自動(dòng)為對(duì)象字面量之間添加空格赃承,比如:{ foo: bar }
- jsxBracketSameLine: 在多行JSX元素的最后一行追加 >
- tabWidth:指定tab的寬度是幾個(gè)空格
- semi: 是否在每行聲明代碼之后都要添加;
更多規(guī)則請(qǐng)參考:Options
讓優(yōu)美的代碼深入到骨髓里~
保存代碼的時(shí)候自動(dòng)格式化(Vscode版本)
安裝Eslint插件
-
Vscode配置:
2.1.
editor.formatOnSave
置為false妙黍,以防默認(rèn)的文件格式化配置和Eslint和Prettier沖突2.2.
eslint.autoFixOnSave
置為true,這樣當(dāng)我們每次保存文件的時(shí)候就可以自動(dòng)fix文件的錯(cuò)誤格式瞧剖。如下圖:
image
image
Lint-staged
Lint-staged幫助你在暫存文件的時(shí)候能夠讓錯(cuò)誤格式代碼不會(huì)提交到你分支拭嫁。
為什么使用Lint-staged?
因?yàn)樘峤淮a前的檢查是最后一個(gè)管控代碼質(zhì)量的一個(gè)環(huán)節(jié),所以在提交代碼之前進(jìn)行l(wèi)int檢查意義重大抓于。這樣可以確保沒(méi)有錯(cuò)誤的語(yǔ)法和代碼樣式被提交到倉(cāng)庫(kù)上做粤。但是在整個(gè)項(xiàng)目上執(zhí)行Lint進(jìn)程會(huì)很低效,所以最好的做法就是檢查那個(gè)被改動(dòng)的文件捉撮。而Lint-staged就是做這個(gè)的怕品。
根據(jù)上面我們提供的生態(tài)圈依賴(lài)包,在package.json
中配置該字段:
"lint-staged": {
"**/*.{tsx,ts}": [ // 這里的文件后綴可以修改成自己需要的文件后綴
"prettier-eslint --write",
"git add"
]
}
與Husky結(jié)合使用
為了讓lint-staged可以在change被staged之前執(zhí)行巾遭,我們這時(shí)候需要借助git的鉤子功能肉康,而提供鉤子功能的社區(qū)解決方案就是husky,該工具提供了git在多個(gè)階段前執(zhí)行的操作灼舍,比如我們這次要在預(yù)提交的時(shí)候進(jìn)行Lint檢查吼和,配置如下:
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
}
這樣每次commit的時(shí)候會(huì)執(zhí)行l(wèi)int操作,如之前所說(shuō)骑素,prettier-eslint-cli會(huì)將代碼prettier一遍后再eslint --fix炫乓,如果沒(méi)有錯(cuò)誤,那么就會(huì)直接執(zhí)行git add
献丑,否則報(bào)錯(cuò)退出末捣。
EditorConfig
因?yàn)椴⒉皇撬械娜硕际褂肰S code,所以為了在同樣的項(xiàng)目下保持一致创橄,比如tab的寬度或者行尾要不要有分號(hào)塔粒,我們可以使用.editorconfig來(lái)統(tǒng)一這些配置。
支持EditorConfig的編輯器列表請(qǐng)走這里筐摘。
下面是模板配置里面推薦的editorconfig的配置
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
[*.md]
trim_trailing_whitespace = false
[*.js]
trim_trailing_whitespace = true
# Unix-style newlines with a newline ending every file
[*]
indent_style = space
indent_size = 2
# 保證在任何操作系統(tǒng)上都有統(tǒng)一的行尾結(jié)束字符
end_of_line = lf
charset = utf-8
insert_final_newline = true
max_line_length = 100
最后
至此Eslint的全解析就完美落幕了,最后再安利一波eslint-config-templates,也歡迎大家PR咖熟。