淺談前端開(kāi)發(fā)規(guī)范,你學(xué)會(huì)了嗎?
一個(gè)好的程序員肯定是要能書(shū)寫(xiě)可維護(hù)的代碼,而不是一次性的代碼,怎么能讓團(tuán)隊(duì)當(dāng)中的其他人,甚至過(guò)一段時(shí)間之后的你,再看自己某個(gè)時(shí)期寫(xiě)的代碼,依然能看懂?這就涉及到規(guī)范你的代碼了。
一、規(guī)范代碼的好處
1.從根本上降低開(kāi)發(fā)成本:
提高代碼整體的可讀性、可維護(hù)性、可復(fù)用性。
2.保證代碼的一致性:
軟件系統(tǒng)中最重要的因素之一就是編碼的一致性。如果編碼風(fēng)格一致,也更加易于維護(hù),因?yàn)閳F(tuán)隊(duì)內(nèi)任何人都可以快速理解并修改。
3.提升團(tuán)隊(duì)整體效率:
開(kāi)發(fā)人員通常需要花費(fèi)大量的時(shí)間來(lái)解決代碼質(zhì)量問(wèn)題,如果都按照規(guī)范編寫(xiě),也有助于團(tuán)隊(duì)盡早發(fā)現(xiàn)問(wèn)題,這將提高整個(gè)交付過(guò)程的效率。
二、不規(guī)范代碼的弊端
1.增加團(tuán)隊(duì)成員間的協(xié)作負(fù)擔(dān):
由于缺乏規(guī)范,導(dǎo)致代碼風(fēng)格不一,極端情況下,某段代碼只有某個(gè)人能修改。
2.團(tuán)隊(duì)間協(xié)作更加困難:
由于開(kāi)發(fā)人員要適應(yīng)不同的風(fēng)格,會(huì)導(dǎo)致效率低下。
3.回顧困難:
在review期間,可能經(jīng)常為類(lèi)似的事情做過(guò)多的討論。
4.影響降低團(tuán)隊(duì)整體效率:
影響團(tuán)隊(duì)的生產(chǎn)力和質(zhì)量,嚴(yán)重的甚至?xí)绊憟F(tuán)隊(duì)和諧。
三、為什么很多團(tuán)隊(duì)缺乏規(guī)范
1.當(dāng)開(kāi)發(fā)人員被要求在短時(shí)間內(nèi)完成任務(wù)時(shí),通常會(huì)回避質(zhì)量標(biāo)準(zhǔn)。
2.長(zhǎng)時(shí)間養(yǎng)成的開(kāi)發(fā)習(xí)慣很難在短時(shí)間內(nèi)去改變。
3.有的時(shí)候雖然達(dá)成了一致,但在開(kāi)發(fā)中依舊我行我素。
四、規(guī)范包含哪些內(nèi)容
我們平時(shí)理解的前端開(kāi)發(fā)規(guī)范,更多層面的是編碼層面的規(guī)范,實(shí)際上遠(yuǎn)不止這一個(gè)。比如技術(shù)棧規(guī)范、瀏覽器兼容規(guī)范、項(xiàng)目文件結(jié)構(gòu)規(guī)范、UI設(shè)計(jì)規(guī)范、前后端協(xié)作規(guī)范等,以下主要從這六個(gè)方面簡(jiǎn)單介紹下前端開(kāi)發(fā)規(guī)范。
1.技術(shù)棧規(guī)范
前端目前主要有三大框架Vue、React和AngularJS。每一個(gè)框架背后都是一個(gè)架構(gòu)、一個(gè)生態(tài)。每個(gè)框架背后牽涉著開(kāi)發(fā)思維、生態(tài)系統(tǒng)、配套工具、最佳實(shí)踐、性能調(diào)優(yōu)。要精通和熟練一個(gè)框架需要付出的成本是很高。
所以說(shuō)團(tuán)隊(duì)的開(kāi)發(fā)效率是基于穩(wěn)定且熟練的技術(shù)棧的。穩(wěn)定的技術(shù)棧規(guī)范有利于團(tuán)隊(duì)協(xié)作和溝通; 另外如果團(tuán)隊(duì)精通這個(gè)技術(shù)棧,當(dāng)出現(xiàn)問(wèn)題或者需要深入調(diào)優(yōu), 會(huì)相對(duì)輕松。
前端技術(shù)棧規(guī)范主要包含下面這些類(lèi)型:
① 編程語(yǔ)言 - Typescript或Javascript。
② UI框架及其配套生態(tài)(路由、狀態(tài)管理、組件庫(kù)、國(guó)際化、動(dòng)畫(huà)、服務(wù)端渲染、腳手架、CLI工具、組件測(cè)試等)。
③ 樣式。命名規(guī)范、預(yù)處理器等。
④ 動(dòng)畫(huà)引擎。
⑤ 項(xiàng)目構(gòu)建工具流。webpack、vue-cli。
⑥ 包管理器。npm、yarn。
⑦ 開(kāi)發(fā)工具、工具庫(kù)(moment.js)、版本管理(gitlab)等。
2.瀏覽器兼容規(guī)范
前端團(tuán)隊(duì)?wèi)?yīng)該根據(jù)應(yīng)用所面對(duì)的用戶(hù)情況、應(yīng)用類(lèi)型、開(kāi)發(fā)成本、瀏覽器市場(chǎng)統(tǒng)計(jì)數(shù)據(jù)等因素,來(lái)制定自己的瀏覽器兼容規(guī)范。不過(guò)確定哪種兼容策略,應(yīng)該取決于用戶(hù)比重,如果大部分用戶(hù)使用的是現(xiàn)代瀏覽器,就應(yīng)該使用優(yōu)雅降級(jí),為現(xiàn)代瀏覽器提供最好的體驗(yàn),而舊瀏覽器則退而求之次,保證大概的功能,反之選擇漸進(jìn)增強(qiáng),保證低版本瀏覽器的體驗(yàn),對(duì)于支持新特性的新瀏覽器提供稍好的體驗(yàn)。
有了瀏覽器兼容規(guī)范,前端開(kāi)發(fā)和兼容性測(cè)試就有理有據(jù),避免爭(zhēng)議; 同時(shí)它也是前端團(tuán)隊(duì)的一種對(duì)外聲明,除非特殊要求,不符合瀏覽器兼容規(guī)范的瀏覽器,前端開(kāi)發(fā)人員可以選擇忽略。
我們也可以根據(jù)瀏覽器市場(chǎng)分布情況、用戶(hù)占比、開(kāi)發(fā)成本等因素對(duì)將瀏覽器劃分為多個(gè)等級(jí),不同等級(jí)表示不同的支持程度:
① 完全兼容: 保證百分百功能正常。
② 部分兼容: 只能保證功能、樣式與需求大致一致。對(duì)于一些不影響主體需求和功能的bug,會(huì)做降低優(yōu)先級(jí)處理或者不處理。
③ 不兼容: 不考慮兼容性。
3.項(xiàng)目文件結(jié)構(gòu)規(guī)范
主要包含項(xiàng)目的命名、項(xiàng)目的文件結(jié)構(gòu)、版本號(hào)規(guī)范等。
下面簡(jiǎn)單列舉一類(lèi)項(xiàng)目文件結(jié)構(gòu):
① README.md: 項(xiàng)目說(shuō)明。你可以在這里提供關(guān)于項(xiàng)目的關(guān)鍵信息或者相關(guān)信息的入口。一般包含下列信息:
- 簡(jiǎn)要描述、項(xiàng)目主要特性;
- 運(yùn)行環(huán)境/依賴(lài)、安裝和構(gòu)建、測(cè)試指南;
- 簡(jiǎn)單示例代碼;
- 文檔或文檔入口, 其他版本或相關(guān)資源入口;
- 聯(lián)系方式、討論群;
- 許可、貢獻(xiàn)/開(kāi)發(fā)指南。
② CHANGELOG.md: 放置每個(gè)版本的變動(dòng)內(nèi)容, 通常要描述每個(gè)版本變更的內(nèi)容。方便使用者確定應(yīng)該使用哪個(gè)版本。
③ package.json: 前端項(xiàng)目必須. 描述當(dāng)前的版本、可用的命令、包名、依賴(lài)、環(huán)境約束、項(xiàng)目配置等信息。
④ .gitignore: 忽略不必要的文件,避免將自動(dòng)生成的文件提交到版本庫(kù)。
⑤ docs/: 項(xiàng)目的細(xì)化文檔, 可選。
⑥ examples/: 項(xiàng)目的示例代碼,可選。
⑦ build: 項(xiàng)目工具類(lèi)腳本放置在這里,非必須。如果使用統(tǒng)一構(gòu)建工具,則沒(méi)有這個(gè)目錄。
⑧ dist/: 項(xiàng)目構(gòu)建結(jié)果輸出目錄。
⑨ src/: 源代碼目錄。
- src 開(kāi)發(fā)目錄
- pages 視圖
- module-a 模塊A
- components 私有組件
- ComA.tsx
- ComB.tsx
- index.module.less
- index.tsx
- Content.tsx
- module-b 模塊B
- components 公共組件
- index.ts 導(dǎo)出所有組件
- header
- index.tsx
- index.module.less
- User.tsx
- useGetBaseInfo.hooks.ts
- routers 路由文件
- store redux中的數(shù)據(jù)
- utils 這里是以u(píng)tils為后綴
- index.ts
- a.utils.ts
- b.utils.ts
- hooks 這里是以hooks為后綴
- index.ts
- a.hooks.ts
- b.hooks.ts
- styles 靜態(tài)資源文件
- service api請(qǐng)求,這里是以api為后綴
- a.api.ts 按照后端微服務(wù)進(jìn)行劃分
- b.api.ts
- constans 常量
⑩ tests/: 單元測(cè)試目錄。
? tests: 全局的測(cè)試目錄,通常放應(yīng)用的集成測(cè)試或E2E測(cè)試等。
? .env*: 項(xiàng)目中我們通常會(huì)使用環(huán)境變量來(lái)影響應(yīng)用在不同運(yùn)行環(huán)境下的行為??梢酝ㄟ^(guò)dotEnv來(lái)從文件中讀取環(huán)境變量. 通常有三個(gè)文件:
- env 通用的環(huán)境變量;
- env.development 開(kāi)發(fā)環(huán)境的環(huán)境變量;
- env.production 生成環(huán)境的環(huán)境變量。
4.編碼規(guī)范
每一個(gè)程序員心目中對(duì)‘好代碼’都有自己的主見(jiàn),統(tǒng)一的編碼規(guī)范可以避免不必要的論戰(zhàn)和爭(zhēng)議,有利于團(tuán)隊(duì)項(xiàng)目的長(zhǎng)遠(yuǎn)維護(hù)。一致性的代碼規(guī)范可以增強(qiáng)團(tuán)隊(duì)開(kāi)發(fā)協(xié)作效率、提高代碼質(zhì)量、減輕系統(tǒng)維護(hù)的負(fù)擔(dān)。
以下主要從HTML、JS、CSS、代碼格式化這四個(gè)方面談?wù)劸幋a規(guī)范:
① HTML規(guī)范
使用 HTML5 的文檔聲明類(lèi)型 :
DOCTYPE標(biāo)簽是一種標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言的文檔類(lèi)型聲明,它的目的是要告訴標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言解析器,它應(yīng)該使用什么樣的文檔類(lèi)型定義(DTD)來(lái)解析文檔。
使用文檔聲明類(lèi)型的作用是為了防止開(kāi)啟瀏覽器的怪異模式。
沒(méi)有DOCTYPE文檔類(lèi)型聲明會(huì)開(kāi)啟瀏覽器的怪異模式,瀏覽器會(huì)按照自己的解析方式渲染頁(yè)面,在不同的瀏覽器下面會(huì)有不同的樣式。
如果你的頁(yè)面添加了,那么就等同于開(kāi)啟了標(biāo)準(zhǔn)模式。瀏覽器會(huì)按照W3C標(biāo)準(zhǔn)解析渲染頁(yè)面。
詳細(xì)規(guī)范可查看:https://codeguide.co/#html
② JS規(guī)范
函數(shù)變量命名、代碼注釋等。JS/TS主流的大致有這幾種:
- Airbnb JavaScript Style Guide:
??https://github.com/airbnb/javascript??
- Google JavaScript Style Guide:
??https://google.github.io/styleguide/jsguide.html]??
- Idiomatic JavaScript Style Guide:
??https://github.com/rwaldron/idiomatic.js??
- JavaScript Standard Style Guide
③ CSS規(guī)范
ID和class的命名、合理使用ID、css選擇器中避免使用標(biāo)簽名、使用子選擇器、盡量使用縮寫(xiě)屬性等,詳細(xì)可參考以下網(wǎng)站:
- Airbnb CSS / Sass Styleguide:
??https://css-tricks.com/bem-101/??
- Code Guide:
④ 代碼格式化規(guī)范
由于每個(gè)開(kāi)發(fā)者的IDE不同,即使IDE相同也會(huì)因?yàn)槊總€(gè)人的配置不一樣導(dǎo)致格式化的結(jié)果不一樣。如何確保團(tuán)隊(duì)內(nèi)開(kāi)發(fā)人員采用統(tǒng)一的格式化配置呢?
這里給推薦大家使用 prettier,它內(nèi)置了一套格式化的規(guī)則。細(xì)可參考以下網(wǎng)站:https://prettier.io/
5.UI設(shè)計(jì)規(guī)范
UI 規(guī)范的最大好處就是能夠提質(zhì)提效:
① 在開(kāi)發(fā)者的角度,與設(shè)計(jì)規(guī)范同步形成研發(fā)資產(chǎn),避免重復(fù)造輪子;
② 在測(cè)試的角度,能夠避免重復(fù)的無(wú)意義走查;
③ 在UI設(shè)計(jì)師的角度,減少設(shè)計(jì)成本,提高設(shè)計(jì)效率,可以快速承接新需求;
④ 在產(chǎn)品角度,提高產(chǎn)品迭代與優(yōu)化效率,降低試錯(cuò)成本;
⑤ 在用戶(hù)角度,解決用戶(hù)體驗(yàn)一致性。
如果團(tuán)隊(duì)不打算制定自己的UI設(shè)計(jì)規(guī)范,則推薦使用現(xiàn)成的開(kāi)源組件庫(kù):Ant Design、Element UI、iView、WeUI等
6.前后端協(xié)作規(guī)范
前端往往不能脫離后端而存在,和后端協(xié)作的時(shí)間也是比較長(zhǎng)的。
一個(gè)常用的前后端協(xié)作流程:
① 需求分析。參與者一般有前后端、測(cè)試、以及產(chǎn)品。由產(chǎn)品主持,對(duì)需求進(jìn)行講解,接受開(kāi)發(fā)和測(cè)試的反饋,確保大家對(duì)需求有一致的認(rèn)知。
② 前后端開(kāi)發(fā)討論。討論應(yīng)用的一些開(kāi)發(fā)設(shè)計(jì),溝通技術(shù)點(diǎn)、難點(diǎn)、以及分工問(wèn)題。
③ 設(shè)計(jì)接口文檔。可以由前后端一起設(shè)計(jì);或者由后端設(shè)計(jì)、前端確認(rèn)是否符合要求。
④ 并行開(kāi)發(fā)。前后端并行開(kāi)發(fā),在這個(gè)階段,前端可以先實(shí)現(xiàn)靜態(tài)頁(yè)面; 或者根據(jù)接口文檔對(duì)接口進(jìn)行Mock, 來(lái)模擬對(duì)接后端接口。
⑤ 前后端進(jìn)行接口聯(lián)調(diào)。
五、前端開(kāi)發(fā)規(guī)范實(shí)例
1.項(xiàng)目情況
多人開(kāi)發(fā)同一個(gè)項(xiàng)目的不同模塊;由于開(kāi)發(fā)前沒(méi)有制定規(guī)范,導(dǎo)致每個(gè)人的代碼都是一種單獨(dú)的風(fēng)格;當(dāng)其他人去修改代碼時(shí)需要熟悉不同風(fēng)格的代碼,浪費(fèi)了大量時(shí)間在閱讀代碼上;而且由于沒(méi)有全局的樣式規(guī)范,導(dǎo)致每個(gè)人都有一套自己的樣式,在后期如果想要做統(tǒng)一的界面風(fēng)格時(shí)需要每個(gè)人都去修改樣式代碼,增加了大量工作量。
2.制定規(guī)范
根據(jù)項(xiàng)目的實(shí)際情況,由于項(xiàng)目已經(jīng)開(kāi)發(fā)到一定程度,已經(jīng)選好了開(kāi)發(fā)框架,所以可以從編碼和UI設(shè)計(jì)等方面進(jìn)行規(guī)范。
由于項(xiàng)目是一個(gè)管理系統(tǒng),所以對(duì)于前端UI來(lái)說(shuō)可以統(tǒng)一頁(yè)面結(jié)構(gòu);制定一個(gè)統(tǒng)一風(fēng)格的模板,開(kāi)發(fā)的時(shí)候可以直接使用模板代碼去做適應(yīng)性的修改;
由于缺乏統(tǒng)一的樣式標(biāo)準(zhǔn),導(dǎo)致后期統(tǒng)一風(fēng)格時(shí)會(huì)花費(fèi)大量時(shí)間,所以進(jìn)行統(tǒng)一的樣式分離,抽離公共的CSS樣式去引用,方便后期統(tǒng)一修改;
由于一些變量和函數(shù)命名過(guò)于簡(jiǎn)單比如a、b、c等,規(guī)范多使用一些語(yǔ)義化的單詞去命名,方便理解和閱讀;
由于項(xiàng)目開(kāi)發(fā)中前后端是同一個(gè)人開(kāi)發(fā),導(dǎo)致有些可能是后端的工作放到了前端去處理。比如分頁(yè)功能,雖然這個(gè)是前后端都可以做的,但是如果使用前端去分頁(yè),這樣就要需要一次性返回全部數(shù)據(jù),數(shù)據(jù)量大的時(shí)候接口可能會(huì)返回很慢,導(dǎo)致頁(yè)面空白時(shí)間比較長(zhǎng),所以建議有些邏輯功能要根據(jù)實(shí)際情況去決定是前端還是后端處理。
3.最終成果
項(xiàng)目代碼結(jié)構(gòu)基本上有一個(gè)統(tǒng)一的風(fēng)格;各模塊頁(yè)面也有了統(tǒng)一的風(fēng)格;用戶(hù)體驗(yàn)較好;也方便了開(kāi)發(fā)和維護(hù)。
總結(jié):
一個(gè)人走得更快,一群人可以走得更遠(yuǎn)。統(tǒng)一規(guī)范的最根本目的是為了保證團(tuán)隊(duì)成員的一致性,從而減少溝通成本,提高開(kāi)發(fā)效率。學(xué)會(huì)熱愛(ài)標(biāo)準(zhǔn),但要確保它們不是一成不變的。如果制定的規(guī)范不適合您的團(tuán)隊(duì),請(qǐng)確??梢赃m應(yīng)和重寫(xiě)所需要的任何規(guī)則。它并不是要強(qiáng)制執(zhí)行一種工作方式,而是為了幫助促進(jìn)團(tuán)隊(duì)之間的互動(dòng)。