1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        我是如何帶領團隊從零到一建立前端規(guī)范的?

        共 11258字,需瀏覽 23分鐘

         ·

        2022-04-24 01:39

        關于本文

        作者:不要禿頭啊

        來自:https://juejin.cn/post/7085257325165936648

        前言

        不以規(guī)矩,不能成方圓。

        本人有幸經(jīng)歷了團隊從缺乏標準到逐漸規(guī)范的一個過程,在此當做記錄供大家參考。

        本文從為什么需要規(guī)范以及建立規(guī)范的重要性出發(fā),逐步引申出如何去建立適合自己團隊的規(guī)范,詳細討論了前端具體涉及到的規(guī)范都有哪些,部分小節(jié)有具體的配置步驟和操作鏈接。

        文中涉及到的所有配置均放在github上的 Demo[1] 中,覺得不錯的點個贊 ??????。

        下面我們開始吧??。

        為什么需要規(guī)范

        規(guī)范能給我們帶來什么好處,如果沒有規(guī)范會造成什么后果?這里主要拿代碼規(guī)范來說。

        統(tǒng)一代碼規(guī)范的好處:

        1. 提高代碼整體的可讀性、可維護性、可復用性、可移植性和可靠性,這會從根本上降低開發(fā)成本,也是最重要的一點。
        2. 保證代碼的一致性:軟件系統(tǒng)中最重要的因素之一就是編碼的一致性。如果編碼風格一致,也更加易于維護,因為團隊內(nèi)任何人都可以快速理解并修改。
        3. 提升團隊整體效率:開發(fā)人員通常需要花費大量的時間來解決代碼質量問題,如果都按照規(guī)范編寫,也有助于團隊盡早發(fā)現(xiàn)問題,甚至完全預防問題,這將提高整個交付過程的效率。
        4. 減少code review期間一系列的爭議,因為缺乏標準,在爭議過程中雙方很難妥協(xié)(沒少因為這事爭論過??)。

        若不統(tǒng)一代碼規(guī)范,可能會造成的后果:

        1. 由于缺乏規(guī)范,導致代碼風格不一,增加團隊成員間的心理負擔,極端情況下,某段代碼只有某個人能修改(俗稱屎山??)。
        2. 團隊間協(xié)作更加困難:因為開發(fā)人員得適應不同的風格,會導致效率低下(閱讀代碼是我們花費時間最多的地方)。
        3. 在code review期間可能經(jīng)常為類似的事情做過多的討論。
        4. 影響團隊的生產(chǎn)力和質量,嚴重的甚至會影響團隊和諧。

        為什么依然有很多團隊缺乏規(guī)范

        在這件事上,很難達成一致是我認為最重要的原因。并且,僅僅只是擁有規(guī)范也是不夠的:

        • 當開發(fā)人員被要求在短時間內(nèi)完成任務時,通常會回避質量標準。
        • 團隊中總是有一些有個性的人不會為了團隊去改變自己的習慣。
        • 有些人在會議上就約定達成了一致,在會下依舊我行我素。
        • ...

        如何保持規(guī)范

        我曾想通過會議討論的方式來制定規(guī)范,但效果卻差強人意。將失敗的原因總結為大致幾點:

        1. 在會議中,思維很容易發(fā)散,經(jīng)常出現(xiàn)的情況是討論了很多,卻很難有實際性的成效,在開發(fā)中依然有不少人選擇無視規(guī)則。
        2. 正式的會議往往很難組織,大家很難一起有空閑的時間來討論,一次/兩周 都很困難。
        3. 會議中對實際案例分析,提出若干點優(yōu)化建議后,沒有對問題的優(yōu)先級和側重點進行劃分,導致實際效果并不好。
        4. 還有一點也是我自己的原因,組織會議的能力有待提升...??

        經(jīng)歷了上述的挫敗之后,經(jīng)過反復復盤總結,決定換一種方式來執(zhí)行:

        1. 對規(guī)范問題進行歸納分析并通過文檔記錄(wiki等),尋找業(yè)內(nèi)最佳解決方案,在團隊內(nèi)進行統(tǒng)一。
        2. 采用小步快跑的方式,有問題就解決問題,按照優(yōu)先級和重要性進行排序劃分,依次將問題納入迭代,每個迭代重點解決其中幾個即好。
        3. 本迭代的規(guī)范問題絕不留到下個迭代,防止堆積(當然,有時候還是得向項目經(jīng)理妥協(xié)?????)。
        4. 在code review過程中嚴格把關,拒絕睜一只眼??閉一只眼??。
        5. 當團隊成員對具體某個規(guī)范有爭議時,及時討論并定出結論。
        6. 沒有規(guī)則只是為了規(guī)則,制定規(guī)范的目的并不是一定要按照某某標準來執(zhí)行,更多的是團隊成員達成一致即可。
        7. 鼓勵大家大膽的質疑規(guī)則,若不能提高代碼的可讀性,可維護性,可復用性,可移植性和可靠性的規(guī)則都應該被受到質疑。
        8. 以身作則,船頭的方向不能偏航。

        經(jīng)過兩個月的迭代后,發(fā)現(xiàn)效果出奇的好??,大家的規(guī)范意識普遍增強,當遇到規(guī)范問題時也不再畏畏縮縮,而是大膽的拋出在群里討論。

        開發(fā)者需要建立和遵守的規(guī)范

        大致可以劃分成這幾個方向:

        • 開發(fā)流程規(guī)范
        • 代碼規(guī)范
        • git commit規(guī)范
        • 項目文件結構規(guī)范
        • UI設計規(guī)范

        1. 開發(fā)流程規(guī)范

        這里可能有小伙伴有疑問了,開發(fā)流程規(guī)范不是項目經(jīng)理定的嗎???,跟我有什么關系?

        這里想告訴大家的是,開發(fā)流程在一定程度上應該是由我們自己來掌控。不管是傳統(tǒng)開發(fā)的模式還是敏捷開發(fā)的模式,對于開發(fā)者來說核心依舊是高質高效的完成用戶提出的需求。

        筆者曾見過不少開發(fā)者在拿到產(chǎn)品經(jīng)理的需求后就開始急匆匆的寫代碼,以此來體現(xiàn)他們的高效,但往往卻因為需求理解不到位和前期代碼欠缺設計導致bug率高和返工。

        如何找到適合自己的開發(fā)流程是需要依靠經(jīng)驗來支撐的,需要反復總結和思考,最終達到高質高效完成的目的。

        說一說筆者自己比較喜歡的開發(fā)流程:

        image.png

        在接收到需求后應第一時間去了解這個需求的背景是什么?這么做到底有沒有解決用戶的痛點?或者說用戶更深層次的需求是什么?如果團隊的產(chǎn)品經(jīng)理經(jīng)驗不豐富,往往可以在這個階段砍掉很多不合理的需求(這一點真的很重要)

        對于復雜大功能往往還需要進行技術方案調(diào)研技術方案設計,并輸出詳細的設計文檔。涉及到細節(jié)上,則需要將數(shù)據(jù)流走向、組件設計等通過腦圖的形式呈現(xiàn)出來。

        2. 代碼規(guī)范之格式化規(guī)范

        由于每個開發(fā)者的IDE不同,即使IDE相同也會因為每個人的配置不一樣導致格式化的結果不一樣。如何確保團隊內(nèi)開發(fā)人員采用統(tǒng)一的格式化配置呢?

        這里給推薦大家使用 prettier[2],它內(nèi)置了一套格式化的規(guī)則,具體配置:

        1). 安裝依賴:

        npm?install?--save-dev?--save-exact?prettier?
        //?or
        yarn?add?--dev?--exact?prettier
        復制代碼

        2). 創(chuàng)建一個空配置文件,讓編輯器和其他工具知道你正在使用 Prettier:

        echo?{}>?.prettierrc.json
        復制代碼

        3). 創(chuàng)建一個.prettierignore[3]文件,讓 Prettier CLI 和編輯器知道哪些文件不能格式化,example:

        #?Ignore?artifacts:
        dist
        build
        coverage
        復制代碼

        4). 配置編輯器(VScode為例)

        IDE中安裝 Prettier-Code Formater[4] 插件:

        image.png

        找到IDE中設置模塊,搜索 format On Save,勾上這個就可以了。

        image.png

        現(xiàn)在當我們 Ctrl + S 保存代碼時,插件就會幫助我們自動格式化了。

        這里有小伙伴要問了,要是有人將沒有格式化的代碼提交上去怎么辦?

        這時候就需要在 git commit 的階段自動將提交的代碼進行格式化,這里我們借助工具 husky[5],它主要可以幫助我們在 git 階段檢查提交消息、運行測試、檢查代碼等。沒接觸過的小伙伴可以去官網(wǎng)[6]了解一下,配置如下:

        • 安裝 husky[7]lint-staged[8]
        npm?install?--save-dev?husky?lint-staged
        npx?husky?install
        npm?set-script?prepare?"husky?install"
        npx?husky?add?.husky/pre-commit?"npx?lint-staged"
        //?or
        yarn?add?--dev?husky?lint-staged
        npx?husky?install
        npm?set-script?prepare?"husky?install"
        npx?husky?add?.husky/pre-commit?"npx?lint-staged"
        復制代碼
        • 然后將以下內(nèi)容添加到package.json中:
        {
        ??"lint-staged":?{
        ????"**/*":?"prettier?--write?--ignore-unknown"
        ??}
        }
        復制代碼

        這段配置的意思是:當執(zhí)行 git commit 階段前,先執(zhí)行lint-stagedlint-staged中的內(nèi)容就是對暫存區(qū)的文件執(zhí)行格式化的命令。

        其他:若使用的是腳手架工具搭建的項目,會自帶eslint配置(eslintConfig)。prettier 和 eslint 會有一些配置上的沖突,這個時候需要安裝eslint-config-prettier[9] 以使 ESLint 和 Prettier 相互配合,安裝完后在.eslintrc中配置(以Create-React-App為例):

        ??"eslintConfig":?{
        ????"extends":?[
        ??????"react-app",
        ??????"react-app/jest",
        ??????"prettier"
        ????]
        ??},
        復制代碼

        這樣就可以用"prettier"的部分規(guī)則覆蓋前面的規(guī)則,讓它們都能正常工作。

        更多詳情見:Prettier[10]。

        3. 代碼規(guī)范之JS/TS規(guī)范

        JS/TS主流的大致有這幾種:

        • Airbnb JavaScript Style Guide[11]
        • Google JavaScript Style Guide[12]
        • Idiomatic JavaScript Style Guide[13]
        • JavaScript Standard Style Guide[14]
        • jQuery JavaScript Style Guide[15]

        比較推薦使用 Airbnb JavaScript Style Guide,它在 Github 上足有 12萬 star,幾乎覆蓋了 JavaScript 的每一項特性。

        具體配置:

        1). 安裝依賴

        npm?install?eslint?--save-dev
        //?or
        yarn?add?eslint?--dev
        復制代碼

        2). 生成配置文件

        npm?init?@eslint/config
        //?or
        yarn?create?@eslint/config
        復制代碼

        跟著終端中的提示,按照自身需求一步步選擇即可。

        有了具體的規(guī)范后,我們同樣需要使用工具去約束:還是通過在git commit階段校驗,若不通過則取消提交。

        配置(還是在 package.json 中的 lint-staged ):

        ??"lint-staged":?{
        ????"**/*":?"prettier?--write?--ignore-unknown",?//格式化
        ????"src/*":?"eslint?--ext?.js,.ts,.tsx"??//進行eslint校驗
        ??},
        復制代碼

        注意:這里如果選用的Typescript,則會默認使用@typescript-eslint/parser解析器,官方為了追求更快的解析速度,并不會對.ts文件中的類型進行檢查,只會做語法檢測。

        如果需要對類型也進行檢測,需要在extends中加上plugin:\@typescript-eslint/recommended-requiring-type-checking[16]。

        但是在筆者的使用中發(fā)現(xiàn)效果并不好,一些基本的類型依然檢測不出來,索性這里換了另一種方式:在pre commit 中執(zhí)行yarn run tsc,這里的意思是對項目中ts文件進行類型檢測,默認會讀取根目錄中的tsconfig.json配置。

        這種方式并不完美,它的弊端就在于全量檢測,如果項目不大還好,若是項目代碼量夠多,檢測10-20s也是常有的事。

        更多詳情查看eslint官網(wǎng):eslint.org/docs/user-g…[17]

        4. 代碼規(guī)范之CSS規(guī)范

        CSS檢查代碼規(guī)范使用?stylelint?插件,規(guī)范則推薦使用 stylelint-config-standard[18]

        1). 安裝

        npm?install?--save-dev?stylelint?stylelint-config-standard
        復制代碼

        2).?在項目的根目錄中創(chuàng)建一個配置文件.stylelintrc.json,內(nèi)容如下:

        {
        ??"extends":?"stylelint-config-standard"
        }
        復制代碼

        3). 解決與prettier配置的沖突:

        npm?install?--save-dev?stylelint-config-prettier
        復制代碼

        4). 將下面配置復制到.stylelintrc.json中:

        {
        ??"extends":?["stylelint-config-standard",?"stylelint-config-prettier"]
        }
        復制代碼

        5). 在 git commitv階段進行檢測:

        ?"lint-staged":?{
        ????"**/*":?"prettier?--write?--ignore-unknown",?//格式化
        ????"src/**.{js,jsx,ts,tsx}":?"eslint?--ext?.js,.jsx,.ts,.tsx",?//對js文件檢測
        ????"**/*.{less,css}":?"stylelint?--fix"?//對css文件進行檢測
        ??},
        復制代碼

        5. 代碼規(guī)范之自定義其他規(guī)范

        下面列一些團隊內(nèi)定的其他規(guī)范:

        (1)命名規(guī)范

        變量的命名中應盡量減少縮寫的情況發(fā)生,做到見名知意。

        //????自我感覺良好的縮寫:
        let?rContent?=?'willen';?

        //????無需對每個變量都寫注釋,從名字上就看懂
        let?firstName?=?'jackie';?

        //????從命名無法知道返回值類型
        function?showFriendsList()?{....}?//?//?無法辨別函數(shù)意圖,返回的是一個數(shù)組,還是一個對象,還是true?or?false?

        //????明確函數(shù)意圖,對于返回true?or?false的函數(shù),最好以should/is/can/has開頭
        function?shouldShowFriendsList()?{...}
        function?isEmpty()?{...}
        function?canCreateDocuments()?{...}
        function?hasLicense()?{...}
        function?sendEmailToUser(user)?{....?}?//動詞開頭,函數(shù)意圖就很明顯
        復制代碼

        (2)寫注釋

        在每個文件的頂部明確說明該組件做什么,有沒有業(yè)務理解難點等等,對業(yè)務特殊函數(shù)/變量也需要寫注釋

        /**
        ?*?導航頁面-右邊區(qū)域
        ?*/

        ?
        const?Content=>()=>xxx
        ?
        const?MAX_INPUT_LENGTH?=?8;?//用于限制密碼輸入框

        function?Component(props)?{
        ??return?(
        ????<>
        ??????{/*?如果用戶沒有訂閱則不展示廣告?*/}
        ??????{user.subscribed???null?:?<SubscriptionPlans?/>}
        ????

        ??)
        }
        ?
        復制代碼

        (3)變量兜底

        //????對于求值獲取的變量,沒有兜底
        const?{?data?}?=?getApiRequest();
        data.map((s)?=>?s.id);?//沒有考慮data異常的情況,代碼一跑就爆炸

        //????對于求值變量,做好兜底
        const?{?data?=?[]?}?=?getApiRequest();
        data.map((s)?=>?s?.id);?//沒有考慮data異常的情況,代碼一跑就爆炸
        復制代碼

        (4)輔助函數(shù)必須是純函數(shù)

        //????不要讓功能函數(shù)的輸出變化無常
        function?plusAbc(a,?b,?c)?{??//?這個函數(shù)的輸出將變化無常,因為api返回的值一旦改變,同樣輸入函數(shù)的a,b,c的值,但函數(shù)返回的結果卻不一定相同。
        ??var?c?=?fetch('../api');
        ??return?a+b+c;
        }

        //????功能函數(shù)使用純函數(shù),輸入一致,輸出結果永遠唯一
        function?plusAbc(a,?b,?c)?{??//?同樣輸入函數(shù)的a,b,c的值,但函數(shù)返回的結果永遠相同。
        ??return?a+b+c;
        }
        復制代碼

        (5)優(yōu)先使用函數(shù)式編程

        //????使用for循環(huán)編程
        for(i?=?1;?i?<=?10;?i++)?{
        ???a[i]?=?a[i]?+1;
        }

        //????使用函數(shù)式編程
        let?b?=?a.map(item?=>?++item)
        復制代碼

        (6)優(yōu)先使用函數(shù)式組件

        除非需要用到錯誤邊界,否則函數(shù)式組件應該是首選方法。

        (7)組件復雜度

        如果一個組件做的事情太多,應適當提取一些邏輯,將其拆分為更小的組件。

        如果提取的組件很復雜,則需要依照一定的規(guī)則和條件一一提取它。

        代碼行數(shù)并不是一個客觀的衡量標準,更多是需要考慮責任劃分和抽象。

        (8)用錯誤邊界

        當需要對大量數(shù)據(jù)進行渲染處理時,需要通過錯誤邊界組件對其進行降級處理。

        更多詳情見之前寫的專題文章:淺析前端異常及降級處理[19] 。

        function?Component()?{
        ??return?(
        ????<Layout>
        ??????<ErrorBoundary>
        ????????<CardWidget?/>
        ??????ErrorBoundary>


        ??????<ErrorBoundary>
        ????????<FiltersWidget?/>
        ??????ErrorBoundary>

        ??????<div>
        ????????<ErrorBoundary>
        ??????????<ProductList?/>
        ????????ErrorBoundary>
        ??????div>
        ????Layout>
        ??)
        }
        復制代碼

        (9)props參數(shù)傳遞

        props一層層傳遞一直是我們很頭疼的一個問題,最核心的問題是不清楚props是從哪個初始組件傳來的,以及props中到底有哪些東西,上下文是什么?

        因此對于傳遞較深的場景我推薦直接使用 context,對于 props 中的內(nèi)容和上下文通過 TS 來解決。

        //?A.tsx
        interface?AProps?{
        ??param:?string;
        }
        const?A?=?({?param?}:?AProps)?=>?{
        ??return?<B?param?=?{param}?/>;
        };

        //????上下文清晰
        //?B.tsx
        const?B?=?({?param?}:?{?param:?AProps['param']?})?=>?{
        ??return?<div>hello?worlddiv>;
        };

        復制代碼

        (10)props傳參數(shù)量

        如果超過 5 個props,就該考慮是否拆分該組件。在某些情況下,這是需要對組件進行重構的標志。

        注意:組件使用的props越多,重新渲染的理由就越多。

        (11)避免嵌套三元運算符

        三元運算符在第一級之后變得難以閱讀,雖然看起來節(jié)省了代碼空間,但最好在代碼中明確意圖,保持良好的閱讀性。

        //????不夠清晰,要是再嵌套一層兩層呢
        isSubscribed???(
        ??<ArticleRecommendations?/>
        )?:?isRegistered???(
        ??<SubscribeCallToAction?/>
        )?:?(
        ??<RegisterCallToAction?/>
        )

        //????將判斷邏輯進行拆分
        function?CallToActionWidget({?subscribed,?registered?})?{
        ??if?(subscribed)?{
        ????return?<ArticleRecommendations?/>
        ??}

        ??if?(registered)?{
        ????return?<SubscribeCallToAction?/>
        ??}

        ??return?<RegisterCallToAction?/>
        }

        function?Component()?{
        ??return?(
        ????<CallToActionWidget
        ??????subscribed={subscribed}
        ??????registered={registered}
        ????/>

        ??)
        }
        復制代碼

        (12)將列表組件封裝成獨立組件

        //????列表渲染和其他邏輯雜糅在一起
        function?Component({?topic,?page,?articles,?onNextPage?})?{
        ??return?(
        ????<div>
        ??????<h1>{topic}h1>

        ??????{articles.map(article?=>?(
        ????????<div>
        ??????????<h3>{article.title}h3>
        ??????????<p>{article.teaser}p>
        ??????????<img?src={article.image}?/>
        ????????div>
        ??????))}
        ??????<div>You?are?on?page?{page}div>
        ??????<button?onClick={onNextPage}>Nextbutton>
        ????div>
        ??)
        }

        //????將列表組件提取出來,一目了然
        function?Component({?topic,?page,?articles,?onNextPage?})?{
        ??return?(
        ????<div>
        ??????<h1>{topic}h1>

        ??????<ArticlesList?articles={articles}?/>
        ??????<div>You?are?on?page?{page}div>
        ??????<button?onClick={onNextPage}>Nextbutton>
        ????div>
        ??)
        }
        復制代碼

        (13)避免嵌套渲染函數(shù)

        //????不要將其定義在渲染函數(shù)組件中
        function?Component()?{
        ??function?renderHeader()?{
        ????return?<header>...header>
        ??}
        ??return?<div>{renderHeader()}div>
        }

        //????將其抽離到獨立的組件中去
        import?Header?from?'@modules/common/components/Header'

        function?Component()?{
        ??return?(
        ????<div>
        ??????<Header?/>
        ????div>

        ??)
        }
        復制代碼

        (14)組件/函數(shù)導入導出

        //????在文件頭部導入,順序依次為:?第三方庫?>?公共組件/方法?>?非公共部分組件/方法
        import?React?from?'react'
        import?_?from?'loadsh'
        import?Header?from?'@components/header'
        import?Content?from?'./Content'

        //????在底部導出
        export?{?Content,?Header?}
        export?default?Component
        復制代碼

        ...

        6. 項目文件結構規(guī)范

        不得不說,在這件事上我們團隊曾經(jīng)花費了大量的經(jīng)歷去思考和實踐,也是信了React官方的鬼話:不要花超過五分鐘在選擇項目文件組織結構上[20]。

        在項目初期若不重視,到了后期就是到處天馬行空,你很難在期望的目錄下找到你想要的文件。

        文件夾名稱全部采用小寫 + "-" 來隔開,index.ts更多是用來做導出作用,要不然最后編輯器中滿屏的index.tsx,很難區(qū)分。

        ???-?src?開發(fā)目錄
        ??????-?pages?視圖
        ??????????-?module-a?模塊A
        ????????????-?components?私有組件
        ??????????????-?ComA.tsx
        ??????????????-?ComB.tsx
        ????????????-?index.module.less
        ????????????-?index.tsx
        ????????????-?Content.tsx
        ??????????-?module-b?模塊B
        ??????-?components?公共組件
        ????????-?index.ts?導出所有組件
        ????????-?header
        ??????????-?index.tsx
        ??????????-?index.module.less
        ??????????-?User.tsx
        ??????????-?useGetBaseInfo.hooks.ts
        ??????-?routers?路由文件
        ??????-?store?redux中的數(shù)據(jù)
        ??????-?utils?這里是以utils為后綴
        ????????-?index.ts
        ????????-?a.utils.ts
        ????????-?b.utils.ts
        ??????-?hooks?這里是以hooks為后綴
        ????????-?index.ts
        ????????-?a.hooks.ts
        ????????-?b.hooks.ts
        ??????-?styles?靜態(tài)資源文件
        ??????-?service?api請求,這里是以api為后綴
        ????????-?a.api.ts?按照后端微服務進行劃分
        ????????-?b.api.ts
        ??????-?constans?常量
        復制代碼

        通過對工具函數(shù)、hooks、api 等加上后綴,更加容易區(qū)分引入的文件。

        7. Git commit規(guī)范

        git commit 規(guī)范主要可以幫助開發(fā)人員在 code review 期間更容易理解提交的內(nèi)容,現(xiàn)在大部分主流 commit 規(guī)范都是基于Angular 團隊的規(guī)范[21]而衍生出來的,它的 message 格式如下:

        ():?




        復制代碼

        每個提交消息都包含一個subject、一個body和一個footer (中間使用空行分割),提交信息的任何一行不能超過 100 個字符。

        ?? type主要有以下幾種類型:

        • feat: 一個新特性
        • fix: 修復bug
        • docs: 文檔修改
        • style: 不影響代碼含義的更改(空格、格式、缺少分號等)
        • refactor: 代碼重構
        • perf: 優(yōu)化性能
        • test: 測試用例修改
        • chore: 對構建過程或輔助工具和庫的更改,例如文檔生成

        ?? scope:可以是影響范圍的任何內(nèi)容。

        ?? subject:包含對更改的簡潔描述,規(guī)則:

        • 使用陳述語句
        • 第一個字母不要大寫
        • 末尾沒有點 (.)

        ?? body:commit 具體修改內(nèi)容, 可以分為多行,應該包括改變的動機,并與以前的行為進行對比。

        ?? footer: 一些備注, 通常是修復的 bug 的鏈接。

        截取一張開源庫的 commit,example[22]

        image.png

        有了規(guī)范后,我們需要通過工具去約束:commitlint[23]。它要做的就是在我們每次提交 git commit 的時候,都會幫我們檢查 commit message 是否符合一定的規(guī)范,如果不符合,就讓這次提交失敗。

        具體配置:

        #?安裝?commitlint?cli?和?conventional?config
        npm?install?--save-dev?@commitlint/{config-conventional,cli}
        #?Windows:
        npm?install?--save-dev?@commitlint/config-conventional?@commitlint/cli

        配置要使用的?commitlint?規(guī)則
        echo?"module.exports?=?{extends:?['@commitlint/config-conventional']}"?>?commitlint.config.js

        加入到husky中:
        npx?husky?add?.husky/commit-msg?'npx?--no?--?commitlint?--edit?"$1"'
        or
        yarn?husky?add?.husky/commit-msg?'yarn?commitlint?--edit?$1'
        復制代碼

        更多詳情見官網(wǎng):github.com/conventiona…[24]

        8. UI設計規(guī)范

        優(yōu)秀的開發(fā)者應該反向推動UI的規(guī)范,并且能夠支撐UI規(guī)范的落地。

        UI 規(guī)范的最大好處就是能夠提質提效:

        • 在開發(fā)者的角度,與設計規(guī)范同步形成研發(fā)資產(chǎn),避免重復造輪子;
        • 在測試的角度,能夠避免重復的無意義走查;
        • 在UI設計師的角度,減少設計成本,提高設計效率,可以快速承接新需求;
        • 站在產(chǎn)品角度,提高產(chǎn)品迭代與優(yōu)化效率,降低試錯成本;
        • 站在用戶角度,解決用戶體驗一致性。

        那到底應該怎么去推動UI規(guī)范?我的做法是先讓設計師去給出一系列的規(guī)范,沒有相關規(guī)范就拉上產(chǎn)品經(jīng)理一起制定規(guī)范。然后前端建立一套自己的組件庫,再將組件庫提供給UI設計師,以此來相互監(jiān)督是否達成了規(guī)范協(xié)議。

        具體參考 Antd設計規(guī)范[25]。

        總結

        統(tǒng)一規(guī)范的最根本目的是為了保證團隊成員的一致性,從而減少溝通成本,提高開發(fā)效率。

        學會熱愛標準,但要確保它們不是一成不變的。如果制定的規(guī)范不適合您的團隊,請確??梢赃m應和重寫所需要的任何規(guī)則。它并不是要強制執(zhí)行一種工作方式,而是為了幫助促進團隊之間的互動 ??????。

        最后

        歡迎關注【前端瓶子君】??ヽ(°▽°)ノ?
        回復「算法」,加入前端編程源碼算法群,每日一道面試題(工作日),第二天瓶子君都會很認真的解答喲!
        回復「交流」,吹吹水、聊聊技術、吐吐槽!
        回復「閱讀」,每日刷刷高質量好文!
        如果這篇文章對你有幫助,在看」是最大的支持
        ?》》面試官也在看的算法資料《《
        “在看和轉發(fā)”就是最大的支持


        瀏覽 30
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            毛片小电影 | 2025成人免费毛片视频 | 女生被c视频 | 国产精品秘 入口久久熟女沈阳 | 大香蕉在线观看福利影院 | 精品午夜视频 | 一级A片巜女人性放纵 | 1000部毛片A片免费视频 免费无码精品久久久嫩青 又大又粗又爽的视频 | 国产精品妇女 | 精品乱子伦一区二区三区 |