<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          前端代碼評審?fù)ǔW⒁庑┦裁?/h1>

          共 7790字,需瀏覽 16分鐘

           ·

          2021-10-14 01:51

          作者:_Vin
          來源:SegmentFault 思否社區(qū)

          代碼評審又稱為(Code Review,簡稱CR),關(guān)于CR,開發(fā)同學(xué)其實都不陌生,現(xiàn)在大部分公司的項目開發(fā)流程中,它都是必不可少的一個環(huán)節(jié),CR的好處也都耳熟能詳。不同的公司對于CR的方式、質(zhì)量要求標(biāo)準(zhǔn)都不一樣。這篇文章主要講的是在代碼評審的過程中,會對哪些代碼和方向進(jìn)行評審,給大家在接下來的CR中作為參考

          一、評審節(jié)點

          很多項目一般把CR的時間節(jié)點放在上線前,如果項目越大,CR的節(jié)點越靠前越好,越靠后臨近上線前,開發(fā)同學(xué)越不愿意去修改,因為測試過的代碼只要出現(xiàn)改動,就有發(fā)生問題的風(fēng)險,測試也需要重新回歸,有可能會產(chǎn)生新的缺陷,或者將問題帶到生產(chǎn)。下面是我們項目流程中CR的節(jié)點,一般會在聯(lián)調(diào)前、提測后、上線前各進(jìn)行一次代碼評審。


          二、評審內(nèi)容

          1、設(shè)計方案
          設(shè)計方案一般是開發(fā)前期定好的方案,在擁有一份完美的設(shè)計方案的理想狀態(tài)下,在CR階段只需在閱讀代碼時判斷,是否遵循設(shè)計方案進(jìn)行開發(fā)即可。
          一份相對完整設(shè)計方案通常會包括:

          但是現(xiàn)實情況是,現(xiàn)在很多公司沒有設(shè)計評審環(huán)節(jié),項目開發(fā)前并沒有進(jìn)行方案設(shè)計??赡苡幸韵聨讉€原因:
          第一:項目太小,認(rèn)為沒有必要。
          第二:沒有意識到設(shè)計方案的好處,覺得浪費時間,在方案設(shè)計的過程中,需要調(diào)研、設(shè)計、畫圖、出方案,少則一兩天,多則三四天。在緊張的開發(fā)周期內(nèi),項目都希望越早開發(fā)完成越早上線。
          第三:即使開發(fā)同學(xué)做了設(shè)計方案,也不會進(jìn)行設(shè)計方案的評審。因為每次項目都需要將相關(guān)人員和評審負(fù)責(zé)人拉到一起,進(jìn)行半個小時或者一個小時的方案評估。所以因為各種原因,最終設(shè)計方案都成為了需求文檔的變種。
          一般注釋是什么時候?qū)懀?br style="box-sizing: border-box;">經(jīng)常聽到這樣的回答:注釋應(yīng)該寫于代碼之前,提前捋清楚邏輯和思路,將注釋寫好,這樣也無需反復(fù)修改,代碼能更加整潔清晰。其實設(shè)計方案也像是一個超級大的注釋,提前整理好開發(fā)的思路,這樣也能夠事半功倍。但是提前做好技術(shù)設(shè)計方案不僅僅是為了在開發(fā)的過程中更加順利,同時也是代碼評審過程中的一大助攻。
          很多時候我們拿到需要評審的代碼都是通過文件的順序從上而下進(jìn)行逐行閱讀,這種方式往往每個文件的上下文都無法銜接,理解了第一個文件但是切換到第二個文件依然不知所云,往往需要借助注釋、口述或自行查閱上下文查看代碼等方式進(jìn)行理解。但是通過一份完整的設(shè)計方案我們便可以了解大致的需求、開發(fā)者的設(shè)計思路,并且跟隨者設(shè)計方案的結(jié)構(gòu)和思路對代碼的主線進(jìn)行閱讀。
          在寫了設(shè)計方案并設(shè)計方案已通過評審的項目中,在代碼設(shè)計方面更多的側(cè)重主要在于代碼是否遵循設(shè)計方案進(jìn)行開發(fā),設(shè)計方案的合理性、可行性、可擴(kuò)展性等在設(shè)計方案評審階段已經(jīng)通過了討論有了結(jié)論。而對于沒有設(shè)計方案或沒有進(jìn)行設(shè)計方案評審的項目,在理解代碼的同時,也需要對整體方案的設(shè)計進(jìn)行評估,而,即使方案設(shè)計并不合理,一旦經(jīng)過測試面臨即將上線,也沒有時間和條件去進(jìn)行調(diào)整。
          在設(shè)計上,一般會關(guān)注下面幾個方面:
          • 復(fù)用:功能、組件是否可以提取公共方法?是否重復(fù)造輪子?同一代碼不應(yīng)該重復(fù)兩次以上。

          • 可擴(kuò)展:當(dāng)需求發(fā)生改動,是否能夠使用少量的改動達(dá)到我們的目標(biāo),適應(yīng)未來的變化?

          • 過度設(shè)計:很多時候由于早期為了能夠擁有更好的擴(kuò)展性,進(jìn)行了很多抽象和封裝,使其復(fù)雜化,造成了過度設(shè)計。

          • 依賴倒置:模塊之間的依賴是否合理?一旦模塊發(fā)生修改,影響面是否能得到有效的控制?


          2、可維護(hù)性
          可維護(hù)性這個詞其實意味著很多,比如,符合團(tuán)隊規(guī)范,復(fù)雜度善可、可讀性較高、可擴(kuò)展性也還不錯、結(jié)構(gòu)合理,前面做的很多優(yōu)化設(shè)計其實都在為之后的可維護(hù)做鋪墊。
          每個團(tuán)隊都有自己的一套編碼規(guī)范,在評審的過程中需要注意是否符合團(tuán)隊的編碼規(guī)范。但是大部分的編碼規(guī)范都可以用工具進(jìn)行約束,能夠使用工具約束的內(nèi)容,盡可能不必在評審時花時間去關(guān)注??梢詫㈥P(guān)注點放在工具約束之外的規(guī)范上,比如:
          • 命名:首先格式(中劃線、小駝峰、大駝峰、下劃線)需要符合規(guī)范,不管是文件命名或者變量命名,盡可能符合其功能特性,能夠通過命名知道它的含義,無須增加注釋去特意說明。

          • 注釋:是否在關(guān)鍵代碼內(nèi)增加注釋說明?是否符合正確的規(guī)范?

          • 復(fù)雜度:復(fù)雜度是否在合理范圍閾值,推薦文章前端代碼質(zhì)量-圈復(fù)雜度原理和實踐(https://juejin.cn/post/6844903965792927751)

          • 不合理的代碼:每個項目都有一些難以維護(hù)的舊代碼,在這個基礎(chǔ)上繼續(xù)添加代碼,也許可以很快的解決當(dāng)下問題,但對于日后來說,只會讓它更加難以維護(hù)。及時對不合理的舊代碼進(jìn)行重構(gòu)和優(yōu)化就顯得尤為重要。


          3、健壯性
          代碼是否具備安全性和健壯性,對任何一個團(tuán)隊來說,無疑都是非常重要的。
          • XSS:XSS攻擊詳細(xì)內(nèi)容,推薦文章前端安全系列(一):如何防止XSS攻擊?https://tech.meituan.com/2018/09/27/fe-security.html

          • CSRF:CSRF攻擊詳細(xì)內(nèi)容,推薦文章前端安全系列(二):如何防止CSRF攻擊?https://tech.meituan.com/2018/10/11/fe-security-csrf.html

          • 邏輯邊界處理:是否有考慮到代碼的邊界邏輯?交互邏輯是否全面?

          • 異常錯誤處理:一旦拋出異?;蛘咤e誤,頁面或者運行的代碼是否會崩潰?

          • 資源釋放:定時器是否及時清空?內(nèi)存及時清理?

          • 兼容性:是否有瀏覽器版本兼容?手機機型兼容?歷史數(shù)據(jù)兼容?接口兼容?小程序版本兼容?

          • 數(shù)據(jù)展示:對于資產(chǎn)、購物車金額等關(guān)鍵數(shù)據(jù)的展示,盡可能直接展示后臺返回數(shù)據(jù),前端不做計算。

          • 數(shù)據(jù)校驗:對傳輸/接收的數(shù)據(jù)都進(jìn)行校驗、認(rèn)證,確保數(shù)據(jù)的來源和正確。校驗有效位、計算精度、完整性、一致性、時效性(獲取時機是否正確、緩存是否更新)

          • 數(shù)據(jù)轉(zhuǎn)換:數(shù)據(jù)轉(zhuǎn)換處理一定要經(jīng)過充分的測試驗證,并且盡量選取源數(shù)據(jù)進(jìn)行傳輸,而并非轉(zhuǎn)換后的數(shù)據(jù)。


          4、功能范圍
          很多人認(rèn)為功能特性的范圍是測試應(yīng)該去保障的,代碼評審時不需要去關(guān)注開發(fā)了什么功能。但其實現(xiàn)狀是,我們上線的代碼往往有很多屬于
          夾帶私貨,比如,上個迭代有一個影響不大的小Bug,趁著還沒被發(fā)現(xiàn),偷偷將它帶上線,或者,發(fā)現(xiàn)上一次寫的代碼太蠢了,還有更好的解決思路,于是潔癖發(fā)作,默默地改了,還覺得自己棒呆了。但是測試只知道本次迭代的功能特性,除了回歸主功能之外,并不知道還有其他需要重新測試的地方。如果開發(fā)同學(xué)剛好對自己的代碼非常自信,覺得一定沒問題,沒有通知到測試回歸。根據(jù)墨菲定律,這種往往覺得沒有問題的代碼,最后...都能夠引發(fā)線上故障。
          • 影響范圍:底層架構(gòu)、組件或者方法的修改,是否確認(rèn)影響范圍,每個受影響的依賴都能正常使用。

          • 修改范圍:是否屬于本次迭代正常上線的功能范圍,有沒有對本次范圍進(jìn)行變更,是否通知到測試同學(xué)。


          5、監(jiān)控/埋點覆蓋
          添加監(jiān)控的前提是公司有一套監(jiān)控系統(tǒng),除了定義好的異常監(jiān)控場景以外。通常新增的一些關(guān)鍵功能、頁面等也需要加入監(jiān)控,提前加好監(jiān)控代碼,無需等到要查問題時,才記起來忘記加監(jiān)控了。
          • 監(jiān)控:監(jiān)控一般用于監(jiān)控數(shù)據(jù)的異常的情況,頁面的渲染異常、數(shù)據(jù)的一致性、正確性。比如:在一些關(guān)鍵數(shù)據(jù)的邏輯上,如果接口返回的數(shù)據(jù)與原有約定不一致,添加了監(jiān)控之后,我們就能快速的響應(yīng)、解決問題。不至于等到引發(fā)更多的錯誤之后,才能看到問題。

          • 埋點:埋點一般用于統(tǒng)計用戶操作行為的數(shù)據(jù),大部分場景下需要埋點的數(shù)據(jù)產(chǎn)品經(jīng)理都會提供。


          6、合規(guī)
          合規(guī)這個詞在金融行業(yè)非常普遍,但也因為隨著人們越來越注重隱私和安全,法律法規(guī)日漸完善,對合規(guī)這個詞也不再陌生。如果應(yīng)用不合規(guī),就將面臨被下線的風(fēng)險,而有一部分不合規(guī)的內(nèi)容,可能無法通過測試測出。所以在CR的過程中對合規(guī)性問題的審查,就尤為重要。任何使得用戶隱私泄露的操作都需要禁止。
          • 敏感信息展示:用戶關(guān)鍵敏感信息是否直接展示。

          • 敏感信息明文上報:用戶關(guān)鍵敏感信息是否直接明文傳給后臺,沒有做加密處理等操作。

          • 敏感信息存儲:保證用戶信息的安全,對用戶的敏感信息不存儲在不安全的地方,比如web storage等。


          7、性能
          C端應(yīng)用對前端的性能要求會比較高,代碼評審時也可以關(guān)注一下比較常見的問題。
          前端性能優(yōu)化 24 條建議(2020)https://segmentfault.com/a/1190000022205291
          • 圖片大小:圖片是否有進(jìn)行過壓縮處理,非頁面級的圖片一般不要超過200kb。
          • http請求:頁面初始化請求過多?白屏?xí)r間過長?初始化加載數(shù)據(jù)是否在合理范圍內(nèi)?
          • 懶加載:是否可以通過懶加載或者按需加載進(jìn)行優(yōu)化?
          • 緩存數(shù)據(jù):需要重復(fù)加載數(shù)據(jù)時,可以通過緩存數(shù)據(jù)減少請求。
          8、tips
          • checklist:在review的過程中,可以發(fā)現(xiàn)很多TODO List,比如增加了配置,在上線前需要先發(fā)布配置平臺,比如增加片,要記得發(fā)布CDN,比如測試環(huán)境添加了測試代碼,需要生產(chǎn)重新測試等等,所以在每次CR時,可以生成一份上線前的checklist,每次上線前查看并執(zhí)行,這樣能夠確保不會遺漏。

          • 少吃多餐:經(jīng)過很多次的CR能夠感覺到,每次評審的代碼越多,質(zhì)量就會降低,評審時間過長,都會產(chǎn)生疲勞感,并且一些小細(xì)節(jié)都會更容易忽略。所以每次評審的時間最好控制在30min~60min左右為佳,可發(fā)起多次評審,少吃多餐~

          • 好的代碼:每次CR都在像是找茬,找到不合理的地方。但其實,找到優(yōu)秀合理的代碼也可以促進(jìn)大家的進(jìn)步。大多數(shù)項目CR并不是全員參加,所以將好的代碼整理出來,生成一份最佳實踐,可以供大家學(xué)習(xí)參考,擴(kuò)展一些新思路。

          三、常見問題

          前段時間聽了我司一位資深CR大佬的講座,列了很多平時在CR過程中發(fā)生的一些常見問題,我在此基礎(chǔ)上進(jìn)行了一些新增和擴(kuò)展,供大家參考。
          第三方庫
          第三方庫的新增、刪除、版本號的修改(包括新增小箭頭),都要確認(rèn)好修改范圍,確保了解庫升級所帶來的影響。不得隨意修改版本號,第三方庫哪怕是小版本的升級也不能保證對當(dāng)前項目或者當(dāng)前依賴包沒有影響,為了避免造成線上問題,最好鎖死版本號。
          // package.json

          // before
          {
               "dependencies": {
                  "eslint""7.27.0",
                  "eslint-plugin-vue""7.15.1",
              },
          }
          // after
          {
               "dependencies": {
                  "eslint-plugin-vue""^7.15.1",
                  "typescript""^4.3.2"
              },
          }

          命名
          命名不統(tǒng)一,導(dǎo)致閱讀的成本過高,同表示
          數(shù)量,但是在a文件命名quantity,b文件命名amount,c文件命名count
          // a.js
          const quantity = 1;

          // b.js
          const amount = 1;

          // c.js
          const count = 1;

          循環(huán)引用
          JavaScript 模塊的循環(huán)加載:https://www.ruanyifeng.com/blog/2015/11/circular-dependency.html
          文件的相互引用,可能會導(dǎo)致引用報錯undefined。盡量避免文件之間的相互依賴,可以使用eslint或者webpack進(jìn)行約束。
          // a.js
          import b from b.js'

          // b.js
          import a from '
          a.js'

          復(fù)雜的判斷條件
          一般邏輯判斷非常復(fù)雜一般前期沒有想得很清楚,或者后期的維護(hù)不斷的迭代,持續(xù)往上疊加,在這種情況下,邏輯會變得越來越復(fù)雜,在開發(fā)或CR時可以考慮重新梳理清楚,重點查看,進(jìn)行優(yōu)化。
          if (!somethingA || somethingB && (!somethingC || somethingD)) {
              ...
          }
          or
          if (...) {
              if (...) {
                  ...
              } else if (...) {
                  ...
              } else {
                  ...
              }
          else {
              ...
          }

          邏輯范圍變化
          此問題一般出現(xiàn)在增量代碼上,因為前面的條件判斷的范圍變小了,導(dǎo)致后面的邏輯處理的范圍變大了。此時要注意這種范圍的變化,是否真的符合預(yù)期,還是只想修改一處邏輯,卻不小心影響到了后面的邏輯。
          // before
          if (type === 1) {} else {}
          // after
          if (type === 1 && isShow) {} else {}

          異常處理
          確保所有的邊界邏輯都已經(jīng)處理或者無需處理。
          // else為空,確認(rèn)無需處理
          if (conditionA) {}

          // 報錯catch
          UserService.getList().then()

          // try...catch,未處理catch
          try {...} catch() {}

          ?概率正確 !== 正確
          前面說過的墨菲定律(墨菲定律真好用):凡事只要有可能出錯,那就一定會出錯。下面
          setTimeout的取值方式相信很多人都見過,使用500毫秒的延遲,使偶現(xiàn)的問題,“不再出現(xiàn)”。但其實只是將出現(xiàn)的概率變小了,該出現(xiàn)的問題還是會出現(xiàn)。治標(biāo)不治本。一定要找到出現(xiàn)問題的原因,真正解決它。
          setTimeout(() => {
              ...延時拉取接口 or do something
          }, 500)
          => 正確 !== 小概率出錯

          object鏈?zhǔn)饺≈?/span>
          監(jiān)控平臺總是會出現(xiàn)很多這樣的報錯
          xxx is undefined,大部分的原因主要是因為我們在對象取值時,喜歡直接點點點。建議使用lodashget或者?.??。
          const a = productObj.something.a;
          => productObj.something是否一定有值?

          // lodash
          const a = get(productObj, 'something.a')
          // 或者雙問號操作符
          ?.??

          隱式類型轉(zhuǎn)換
          隱式類型轉(zhuǎn)換容易出現(xiàn)很多問題,
          ==可以使用eslint避免。
          if ( amount  == '22' ) {}

          +new Date()

          css重復(fù)樣式
          很多時候CR時都會忽略css,覺得它翻不出什么浪花,但是在像小程序這種對代碼包的體積有嚴(yán)格要求的項目中,CSS的精簡就顯得非常重要了。很多時候在寫樣式時,都會根據(jù)視覺稿一股腦全部寫完,但其實很多可以繼承的屬性,是不需要重復(fù)書寫的。
          .page {
              font-size: 18px;
              font-family: sans-serif;
              line-height: 18px;
              color: #000;
              ...

              .box {
                  font-size: 18px;
                  font-family: sans-serif;
                  line-height: 18px;
                  color: #000;
                  ...
              }
          }

          每個團(tuán)隊對CR的要求和規(guī)范都不一樣,大家可以選擇適合自己的。如果還有更多建議歡迎留言補充~


          點擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開更多互動和交流,掃描下方”二維碼“或在“公眾號后臺回復(fù)“ 入群 ”即可加入我們的技術(shù)交流群,收獲更多的技術(shù)文章~

          - END -


          瀏覽 175
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報

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

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  熟妇在线观看 | 四虎成人在线影院 | 来操逼网| 成人人妻视频 | 日本本一道久久久久久久 |