不少時候,咱們看見一些不太優雅的代碼、不太整潔的代碼,也很容易能夠推斷出這段代碼是怎麼來的,甚至是能夠推斷出寫這個代碼的人當時的心理狀態和那時候的背景。在前端迅速發展的時代,一份一年多兩年以上的代碼,極可能帶着歷史的色彩地成爲了歷史包袱css
若是某一天,你忽然看見相似下面這些的代碼:html
function f() {
if (a) {
return
}
if (b) {
return
}
if (c) {
return
}
// ...many codes
}
複製代碼
推測當事人心理:需求要作這個功能,須要加一個條件。好的,就在最前面加一下
function f(a, b, c, d, config, isAdmin, isEdit, isAdd) {
// ...many codes
}
複製代碼
推測當事人心理:後面這個函數功能更復雜了,須要加多一個參數作配置。啊,還要再加一些功能,再多一個參數
if (a === 1 || a === 2 || a === 3 || a === 4) {
}
複製代碼
推測當事人心理:狀態4也要走這個邏輯,那我加多一個&&便可
return (
<> { isXXX && <div>abc</div> } {/* 可能中間有不少其餘代碼 */} { !isXXX && <div>123</div> } </> ) 複製代碼
推測當事人心理:兜底狀況展現123,直接加一下,ok
const data = res[0].some_data || {}
if (!data) {
return
}
// other code
// =================================
const SOME_FLAG1 = 'xxxx1'
const SOME_FLAG2 = 'xxxx2'
const SOME_FLAG3 = 'xxxx3'
const arr = [SOME_FLAG1]
if (xxx) {
// arr
}
// 對arr一頓操做
if (!arr) {
// 怕出錯?加了這個
}
複製代碼
推測當事人心理1:可能arr爲假值,防止報錯
推測當事人心理2:只是改了前面,後面!arr壓根沒看見
import { func } from 'prop-types';
function a(){
return 1
}
複製代碼
推測當事人情況:壓根不知道,只是輸入了func按了回車,覺得是function的補全
又好比想要一個request,發現有3個以上的提示。而後一看,團隊統一的request一個,某我的寫了一個緩存版本又一個,另外一我的又本身寫了一個袖珍版,最後還有一我的寫了一個預處理參數的...前端
推測當事人情況1:壓根不知道有團隊統一的request,本身寫還寫得很挫
推測當事人情況2:知道有request,但不敢改,因此本身封裝多一層,但名字仍是取了同樣的
本人屢次代碼優化重構的經驗,一個沒有lint的項目,開了lint後90%的錯誤均可以經過autofix解決。例如9000個錯誤,跑一下便可變成800多個,能夠修復那些換行、縮進、函數單參數無括號的問題。這些修復不須要測試介入。剩下的那些錯誤須要人工解決node
最多見的須要人工解決的lint錯誤合集:
錯誤 | 解決方法 | 緊急程度 | 風險 |
---|---|---|---|
下劃線命名 | 全局搜索,一個我的工修 | 中 | 低 |
解構賦值 | 通常是warning,遇到一個修一個 | 低 | 低 |
無狀態class組件 | 改爲PureComponent或者函數組件 | 高 | 中 |
willreciveprops | 改爲getderivedstatefromprops | 高 | 高 |
componentwillmount/update | 初始state & didmount | 高 | 低 |
== | 肯定類型再轉化,最後=== | 高 | 高 |
做用域下重複命名 | 看見就修,但仍是有必要性 | 中 | 低 |
ts類型報錯 | 不影響代碼的執行,但也不能長期無論 | 低 | 低 |
html標籤缺乏屬性 | 如img的alt、button的type,看見就修 | 低 | 低 |
promise的rejcet不是error | reject(Error(xxx)) | 高 | 低 |
中等風險以上的修復,須要自測或者測試,過一遍主流程。不管哪種人工修復,量達到幾百個,都須要測試介入react
好比上面的多個if-return、很長的相似的判斷,均可以精簡爲||
、&&
,進一步精簡就是數組操做: [1, 2, 3, 4].includes(a)
,在另外一篇文章裏面有講到更多的if簡化git
上面提到的一些狀況,多是最開始的時候設計是沒什麼問題的,但隨着需求迭代,就不同了。好比多個if-return、明顯走不到的邏輯、重複寫了一些常見的工具函數,這些問題都是由於不完整地看上下文致使的json
export default class extend
、export default function() {}
,不然調試工具不顯示名字本人有屢次歷史大項目重構經歷,常見的case和套路已經在上文提過,接下來是操做步驟的總結數組
傳統舊項目,一般沒有lint,須要本身裝。而後找一下團隊如今的lint規範(若是沒有就找業界出名的如airbnb),接着跑一波lint自動修復,此時能夠把縮進換行所有解決,剩下的須要本身手動去修。具體怎麼手動修,前面已經提到了promise
爲何重構?那必然有一個觸發點,或是某個需求,或是發現了不少bug致使沒法正常運行。或是開始有大力維護的計劃。因此先從觸發點開始,在保證功能正常的狀況下,順便把模塊一塊兒重構了,這裏也有幾個要領:緩存
if status === 1
、 type === 0
這種代碼,這個讓人懵逼的數字就是magic number。此時要看上下文,瞭解這個數字是什麼意思,再使用大寫常量來維護(如const NORMAL = 1;
,並加上註釋:// 【xx模塊】狀態正常:1
) 。若是多個文件用到,須要提取到更上層if a == b
,從代碼中沒法知道a、b是什麼類型,且業務路徑很長很差復現,先妥協一下,等有時間再改修改範圍怎麼肯定?
有一個這樣的文件目錄:
- components
utils.ts
constant.ts
-- Home
index.tsx
Header.tsx
Footer.tsx
...
-- Input
index.tsx
index.scss
...
複製代碼
Header.tsx
,Home目錄不大,須要所有一塊兒重構;若是Home目錄很大,那就只改Header.tsx
和他的父組件index.tsx
功能已經作好了,也順便重構了一波,此時還沒完。考慮到將來繼續維護和重構,因此如今要開始鋪路,方便下次,讓本身和其餘同事更舒服
{ ...data }
,經歷過的人天然懂這個痛雖然平時你們老是自黑,講段子,發自黑、調侃的表情包,吐槽垃圾代碼、歷史代碼、知道沒用但不敢動.jpg。但我相信若是真的擱在頭上了,你們都不會慫的,也不會輕易妥協,會認真的修好,完美完成重構
關注公衆號《不同的前端》,以不同的視角學習前端,快速成長,一塊兒把玩最新的技術、探索各類黑科技