怎樣提升代碼質(zhì)量
盡管寫了多年的代碼悬嗓,但是始終有一件事不敢確定,就是自己的代碼究竟寫得好不好?這個問題很難有確切的答案舟肉,因?yàn)檫@個跟風(fēng)格修噪、規(guī)范有很大關(guān)系,而風(fēng)格路媚、規(guī)范很難說好還是不好黄琼。
但我覺得好的代碼,一定是能讓別人閱讀起來有一種爽心悅目的感覺整慎。
1. 開發(fā)規(guī)范
不管是團(tuán)隊(duì)協(xié)作還是個人獨(dú)立開發(fā)脏款,遵循一定的開發(fā)規(guī)范都是很有必要的。就團(tuán)隊(duì)協(xié)作來說裤园,可能每個人的風(fēng)格迥然不同撤师,如果沒有規(guī)范的約束的話,團(tuán)隊(duì)之間的協(xié)作會大打折扣的拧揽。而就個人獨(dú)立開發(fā)來說剃盾,很難說一年后的你回頭看今天自己寫的代碼是滿意的。
js
開發(fā)規(guī)范
一般前端開發(fā)的主要工作都要 js
部分强法,所以一般前端開發(fā)規(guī)范都是對 js
而言的万俗。
認(rèn)可度比較高的有:
css
開發(fā)規(guī)范
認(rèn)可度比較高的有:
2. 使用工具檢查、自動矯正與優(yōu)化
盡管有規(guī)范可循饮怯,但其實(shí)開發(fā)的時候并不知道自己的代碼是否是符合規(guī)范的闰歪,所以就需要工具來檢查與矯正代碼。
2.1 檢查與自動矯正
認(rèn)可度比較高的有:
- eslint:檢查 js 語法(包括 jsx 語法)蓖墅,然后最大程度的矯正不符合規(guī)范的代碼库倘;
- stylelint:檢查 css 語法(包括 less, scss 語法),然后最大程度的矯正不符合規(guī)范的代碼论矾。
安裝
目錄文件
|-- root/ // 項(xiàng)目根目錄
|-- package.json
|-- .eslintrc // eslint 配置文件
|-- .eslintignore // eslint 忽略配置教翩,類似 .gitignore
|-- .stylelintrc // stylelint 配置文件
|-- .stylelintignore // stylelint 忽略配置,類似 .gitignore
package.json
"scripts": {
"eslint": "eslint .", // 僅檢查
"eslint:fix": "eslint . --fix", // 檢查之后自動矯正
"stylelint": "stylelint \"./**/*.{css,less,sass,scss}\"", // 僅檢查
"stylelint:fix": "stylelint \"./**/*.{css,less,sass,scss}\" --fix" // 檢查之后自動矯正
},
"devDependencies": {
"eslint": "^4.19.1", // eslint 主文件
"babel-eslint": "^8.2.5", // babel 轉(zhuǎn)碼器 for eslint
"eslint-config-airbnb": "^17.0.0", // airbnb eslint 規(guī)則
"eslint-config-prettier": "^2.9.0", // prettier eslint 規(guī)則
"eslint-plugin-babel": "^5.1.0", // eslint 的 babel 轉(zhuǎn)碼插件
"eslint-plugin-import": "^2.13.0", // eslint 檢查模塊輸入輸出是否正確的插件
"eslint-plugin-jsx-a11y": "^6.1.0", // eslint jsx 語法檢查的一個插件
"eslint-plugin-prettier": "^2.6.2", // prettier eslint 插件
"eslint-plugin-react": "^7.10.0", // eslint react 語法檢查插件
"stylelint": "^9.3.0", // stylelint 主文件
"stylelint-config-prettier": "^3.3.0", // prettier stylelint 規(guī)則
"stylelint-config-standard": "^18.2.0" // standard stylelint 規(guī)則
},
.eslintrc
{
"parser": "babel-eslint",
"extends": ["airbnb", "prettier"],
"env": {
"browser": true,
"node": true,
"es6": true,
"mocha": true,
"jest": true,
"jasmine": true
},
"rules": {
... // 更多自己定義的規(guī)則
}
}
.stylelintrc
{
"extends": ["stylelint-config-standard", "stylelint-config-prettier"],
"rules": {
... // 更多自己定義的規(guī)則
}
}
運(yùn)行命令
npm run eslint // 檢查項(xiàng)目中的 js(jsx) 語法
npm run eslint:fix // 檢查項(xiàng)目中的 js(jsx) 語法贪壳,并最大程度的矯正
npm run stylelint // 檢查項(xiàng)目中的 css(less,scss) 語法
npm run stylelint:fix // 檢查項(xiàng)目中的 css(less,scss) 語法饱亿,并最大程度的矯正
2.2 代碼優(yōu)化
eslint 與 stylelint 在對代碼做檢查和自動矯正時,只保證代碼的語法是符合一定的規(guī)范闰靴,并不對代碼的格式做任何優(yōu)化彪笼,所以,自動矯正后的代碼可能格式會不太好蚂且,閱讀性不太高配猫。
所以,一般會在對代碼檢查與自動矯正之后做代碼格式優(yōu)化杏死。
使用比較多的:prettier.
安裝
目錄文件
|-- root/ // 項(xiàng)目根目錄
|-- package.json
|-- .prettierrc // prettier 配置文件
|-- .prettierignore // prettier 忽略配置泵肄,類似 .gitignore
package.json
"scripts": {
// 對 js,jsx,css,less,md,json 文件進(jìn)行優(yōu)化
"prettier": "prettier --write \"./**/*.{js,jsx,css,less,md,json}\""
},
"devDependencies": {
"prettier": "^1.13.7"
},
.prettierrc
{
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 120,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "json" }
}
]
}
運(yùn)行命令
npm run prettier
2.3 強(qiáng)制對代碼進(jìn)行檢查捆交、自動矯正與優(yōu)化
盡管定好了規(guī)范與工具命令,但開發(fā)人員完全可以跳過這些步驟腐巢,這尤其是在團(tuán)隊(duì)開發(fā)中很難強(qiáng)制其他組員會去做代碼檢查品追、自動矯正與優(yōu)化。
所以系忙,使用工具強(qiáng)制開發(fā)人員對代碼進(jìn)行檢查诵盼、自動矯正與優(yōu)化惠豺,就顯得很有必要了银还。
使用比較多的:
- husky:對 git 進(jìn)行 hook,可以在 git 操作之前做一些操作洁墙;
- lint-staged:對當(dāng)前 git 提交的代碼進(jìn)行一些操作蛹疯。
package.json
"scripts": {
"precommit": "npm run lint-staged", // 在 git 提交之前運(yùn)行 lint-staged 命令
"lint-staged": "lint-staged", // 對 git 將要提交的代碼做操作
},
"devDependencies": {
"husky": "^0.14.3",
"lint-staged": "^7.2.0",
},
"lint-staged": {
"**/*.{js,jsx}": [
"eslint --fix", // 對 js,jsx 文件進(jìn)行 eslint 檢查、自動矯正
"prettier --write", // 然后 使用 prettier 進(jìn)行代碼格式優(yōu)化
"git add" // 最后重新添加
],
"**/*.{css,less}": [
"stylelint --fix", // 對 css,less 文件進(jìn)行 stylelint 檢查热监、自動矯正
"prettier --write", // 然后 使用 prettier 進(jìn)行代碼格式優(yōu)化
"git add" // 最后重新添加
],
"**/*.{md,json}": [
"prettier --write", // 使用 prettier 進(jìn)行代碼格式優(yōu)化
"git add" // 最后重新添加
]
},
這樣捺弦,在每次 git commit
之前,都會對將要提交的文件進(jìn)行檢查孝扛、自動矯正與優(yōu)化列吼,如果其中有一項(xiàng)發(fā)生錯誤,本次提交都會失敗苦始。然后開發(fā)人員調(diào)整代碼之后再進(jìn)行提交寞钥,只有每項(xiàng)任務(wù)都是沒問題的,才能提交成功陌选。
這樣理郑,便可使每個開發(fā)人員都是按照一定的規(guī)范與風(fēng)格寫代碼的。
3. 編輯器配置:.editorconfig
有了規(guī)范咨油,也加上了工具做自動化代碼檢查您炉、矯正與優(yōu)化,但還有一點(diǎn)需要提及一下役电,就是在團(tuán)隊(duì)協(xié)作中赚爵,每個開發(fā)人員可能使用的編輯器不一樣,編輯器的配置也不一樣法瑟,這就導(dǎo)致工具在做格式優(yōu)化的時候冀膝,不同的開發(fā)人員中輸出的代碼不一樣。
這就需要配置文件 .editorconfig
去統(tǒng)一每個開發(fā)人員的編輯器配置瓢谢。
目錄文件
|-- root/ // 項(xiàng)目根目錄
|-- .editorconfig // 編輯器配置文件
.editorconfig
# http://editorconfig.org
root = true
[*]
indent_style = space # 輸入的 tab 都用空格代替
indent_size = 2 # 一個 tab 用 2 個空格代替
end_of_line = lf # 換行符使用 unix 的換行符 \n
charset = utf-8 # 字符編碼 utf-8
trim_trailing_whitespace = true # 去掉每行末尾的空格
insert_final_newline = true # 每個文件末尾都加一個空行
[*.md]
trim_trailing_whitespace = false # .md 文件不去掉每行末尾的空格
更多的編輯器配置規(guī)則畸写,可以查看 http://editorconfig.org.
4. 業(yè)務(wù)邏輯優(yōu)化
上面提到的這些只是風(fēng)格、規(guī)范氓扛、語法上的優(yōu)化枯芬,但對編碼質(zhì)量的評估更多的是在業(yè)務(wù)邏輯具體實(shí)現(xiàn)這一塊论笔。
一般來說,業(yè)務(wù)邏輯實(shí)現(xiàn)的優(yōu)化離不開下面幾個方向:
- 模塊化:
- js 的模塊化已經(jīng)很成熟了千所,目前使用最多的是
commonjs
模塊化規(guī)范和es6
模塊狂魔; - css 的模塊化也一直在探索中,之前也專門寫了一篇 CSS 模塊化淫痰,可以參考下最楷;
- html 沒有模塊化,但是可以將一個很長的 html 文件進(jìn)行分塊待错,參考 html-loader籽孙。
- js 的模塊化已經(jīng)很成熟了千所,目前使用最多的是
- 組件化:當(dāng)項(xiàng)目變大、變多火俄,很多公共的代碼需要復(fù)用或者跨項(xiàng)目使用的時候犯建,組件化就變得很必要了,之前也專門寫了一篇 組件化瓜客,可以參考下适瓦;
- 邏輯解耦:把一個復(fù)雜的邏輯,分割成多個子邏輯谱仪,然后將子邏輯串起來玻熙,或者把多個交叉邏輯的公共部分拆出來,然后再挨個串起來疯攒;
- 功能分塊:細(xì)化一個一個的功能為單獨(dú)的模塊嗦随。
5. 邏輯解耦
邏輯解耦就是把一個復(fù)雜的邏輯,分割成多個子邏輯卸例,或者把多個交叉邏輯的公共部分拆成單個邏輯称杨。這樣做的目的是降低應(yīng)用的復(fù)雜度,更據(jù)閱讀性筷转。
比如姑原,3 個串行的 ajax 請求,可以分割成多個子邏輯:
$.getJSON(url1, data1, res1 => {
// do something with res1
$.getJSON(url2, data2, res2 => {
// do something with res2
$.getJSON(url3, data3, res3 => {
// do something with res3
});
});
});
邏輯解耦之后:
const request1 = () => {
$.getJSON(url1, data1, res1 => {
// do something with res1
request2();
}
};
const request2 = () => {
$.getJSON(url2, data2, res2 => {
// do something with res2
request3();
}
};
const request3 = () => {
$.getJSON(url3, data3, res3 => {
// do something with res3
}
};
request1();
再比如呜舒,在不同文件中需要依賴同一個 ajax 請求锭汛,可以把交叉邏輯的部分拆成單個邏輯:
# file1.js
$.getJSON(url, data, res => {
// do something with res
}
# file2.js
$.getJSON(url, data, res => {
// do something with res
}
邏輯解耦之后:
# request.js
module.exports = cb => {
$.getJSON(url, data, res => {
cb(res);
}
};
# file1.js
const request = require('./request');
request(res => {
// do something with res
});
# file2.js
const request = require('./request');
request(res => {
// do something with res
});
6. 功能分塊
細(xì)化功能為單獨(dú)的模塊也是提升代碼質(zhì)量的一個方式。
比如袭蝗,將一個文件拆成多個文件(顆粱脚梗化):
# util.js
module.exports = {
func1: args => { ... },
func2: args => { ... },
func3: args => { ... },
};
將功能分塊之后:
# util/func1.js
module.exports = args => { ... };
# util/func2.js
module.exports = args => { ... };
# util/func3.js
module.exports = args => { ... };
再比如,將一個大功能塊分割成多個小功能塊:
$.getJSON(url, data, res => {
// 渲染頁面
...
// 初始化組件
...
// 裝載數(shù)據(jù)
...
// 綁定模型
...
// ...
...
}
一般這種情況下到腥,一個功能代碼塊就可能會很長朵逝,200 行都有可能,這個時候就需要將其分割成多個小代碼塊:
const renderPages = res => { ... };
const initComponents = res => { ... };
const fillData = res => { ... };
const bindModels = res => { ... };
...
$.getJSON(url, data, res => {
// 渲染頁面
renderPages();
// 初始化組件
initComponents();
// 裝載數(shù)據(jù)
fillData()
// 綁定模型
bindModels();
// ...
...
}
7. 多閱讀
最后乡范,也是最重要的配名,就是多閱讀別人優(yōu)秀的代碼啤咽,閱讀永遠(yuǎn)是獲取知識最重要的途徑,沒有之一渠脉。
8. 后續(xù)
更多博客宇整,查看 https://github.com/senntyou/blogs
版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名(創(chuàng)意共享3.0許可證)