(總結)專案經歷一次更換ui元件庫才知道的事: 共21種問題型別
介紹
寫這篇文章的起因是作者不久前經歷了一次專案整體ui元件庫的替換, 本以為更換ui元件庫只是改改樣式並且改幾處寫法就行了, 但真正經歷了才知道這裡面遇到的問題還真是豐富多彩, 全程做下來我一共總結了21種問題型別, 希望哪一天你也有類似'需求'的時候可以找出來這篇文章看一看。
我經歷的場景是公司內部研發了新的元件庫, 新元件庫大部分的'使用方式'和'設計理念'與舊元件庫是一致的, 並且是公司內部的庫所以不方便直接截圖舉例子, 文章裡我就用antd來類比展示我遇到的問題, 順帶一提ts真香
在更換元件庫時立了大功, 很多問題都是開發人員很難直接監測到的只能靠 ts
。
一: 屬性的變化
屬性被刪除 (ts可標紅
)
比如 button
元件之前有一個 textType
用來設定按鈕的定製樣式, 但是在新的元件庫中被刪掉了, 這些舊的特殊樣式需要找ui同學確認是否保留。
新增屬性
彈出框新增autoFocus
屬性, 是否預設聚焦第一個可聚焦元素,如果元件庫使用新增屬性是為了替代某個舊屬性的話, 那麼替換時就需要找到屬性間的對應關係。
屬性改名 (ts可標紅
)
比如彈框的確認按鈕, 之前叫onConfirm
事件, 現在叫onOk
事件。
屬性取值範圍改變 (ts可標紅
)
舊版元件button
的size
屬性取值範圍是 big mini small
, 新版元件庫變成了default large
, 出現了三種屬性對應兩種屬性的問題, 這個時候就要找ui同學來決定如何替換了。
二: 返回值的變化
型別變化 (ts可標紅
)
我們的 日期元件
的 onchange
事件舊版返回的引數是被dayjs
處理過的物件, 直接可以針對這個值進行格式化的取值, 但是新版元件返回的是時間戳, 這種元件替換的時候需要我們主動為其轉換一下格式:
舊版
onChange={(_: string[], date: Dayjs[]) => {
const startTime = date[0];
const endTime = date[1];
// ...
}}
新版
onChange={(_: string[], date: number[]) => {
if (date[0] && date[1]) {
const startTime = dayjs(date[0]);
const endTime = dayjs(date[1]);
// ...
}
}}
數量變化 (ts可標紅
)
比如之前返回值是兩個, 但是現在合成了一個物件裡面的兩個key返回給我們, 這時候要做一下結構再使用。
三: 限制條件的變化 (可能是bug)
InputNumber
數字輸入框限制條件變了, 比如設定最小值為 1
, 當我輸入0
的時候輸入框會預設把值轉為1
, 但是新版輸入框竟然在我輸入0
的時候沒有把值轉為1
, 這就導致接下來的所有操作都需要對是否為0進行校驗。
這類問題才是最"要命的"
, 會導致原有變數的變化, 並且不實際操作一遍無法發現問題, 很多元件我們無法一一驗證, 比如很多元件只在特定的情況下才會出現在使用者的介面上, 這時候我們很容易漏測一些地方。
四: 顯示層級的變化
不光是z-index
的問題, 每個元件所處的父級也會導致層級的不同, 比如我們前置有一個新人引導彈框
, 在更換新組建庫後這個新人引導彈框
就被遮擋住了,
當新老元件庫一起使用的時候, 老元件庫的彈出框
元件, 與新元件庫Tooltip提示框
配合使用的時候提示框無法顯示。
這類問題不容易發現, 比如tooltip不顯示這個問題, 對於一個不熟悉業務的人來說根本無法發現原本應該有個提示框
, 需要開發人員對業務很熟才能發現此類問題。
五: 元件聯合使用的bug
我們有一種輸入框
元件是可以插入一個 選擇框
元件, 但是新版元件裡面沒有設定為這種插入元件:
舊元件
新元件
這種問題也比較棘手, 因為它並不會報錯, 只是顯示不一樣, 這就導致只有真切的在頁面上看到了這種錯誤才能發現。
六: 元件缺少
舊版元件庫提供了懶載入元件
和 錯誤提示元件
, 但是新版的元件庫沒有這兩個元件, 這時就需要聯絡負責的同學了, 看是否可以加上這兩個元件, 如果不能加上只能自己親手開發一個了, 這個問題也挺坑的, 無端增加了不小的工作量。
七: 兜底屬性的改變
舊版元件庫的table表格元件
會有預設的error錯誤圖
和empty空值圖
, 但是新版的沒有這些圖片, 需要我們手動的去新增。
比如彈出框
元件的onOk
事件如果不傳入的話, 預設點選後是 "關閉彈框", 但是新版元件裡面不傳就是沒有任何操作效果, 這就需要之前沒傳onOk
事件的彈框每個都加一下。
這類問題也比較難發現, 因為並不會報錯但是到處都有。
八: css屬性的錯亂 & 樣式的差異
元素css屬性被改變
比如table表格
元件每個td
的差異, 舊版元件裡面沒有為td
設定特殊的屬性, 但是新版的表格元件為tb
設定了display: flex
屬性, 這可把一堆樣式都搞亂了, 簡直慘不忍睹。
彈框元件
的footer
沒有用div
之類的標籤包住, 導致被父級的display: flex
影響, 比如我單獨定義footer
為一個按鈕的話, 這個按鈕會被抻拉。
這類問題不好解決, 因為新的ui庫的同學也不願意改這種底層設計,而且新版的ui庫已經有其他團隊在使用了, 此時就需要我們自己寫全域性的css樣式把它頂掉了。
整體樣式未處理
新版元件庫沒有為元件新增box-sizing: border-box;
屬性, 我當前的專案裡也沒有寫*{box-sizing: border-box;}
, 就導致很多地方的樣式都會有2px左右的偏移, 看起來十分別扭, 這類問題只能加css樣式來解決了。
九: style || className 設定無效 (ts可標紅
)
這個問題也是無意間發現的, 新版的ui庫部分元件不接受style
引數了, 導致之前很多樣式都不生效了, 但是我們也沒法通過css的方式把樣式注入進去, 這個挺無解的, 只能找相應的同學擴大一下新版ui元件的接收值範圍。
十: 元件標籤巢狀的改變
比如說彈出框
元件, 原本彈出框元件有兩層div
包裹, 當我想要獲取最外層的div
時就需要當前元素.parentNode?.parentNode
, 但是新版ui元件巢狀關係改了, 並且多巢狀了一層, 導致之前獲取最外層元素的方法全部報錯。
這裡也讓我們意識到, 最好不要寫這種獲取dom
的操作, 規範的模式應該是使用元件提供的方法獲取元件的任何元素, 並且設計元件的時候也要把獲取元素的方法匯出來。
這種問題也不好發現, 只能是真的觸發了獲取父級的方法, 才能報錯出來。
十一: 元件未做國際化
這個問題比較直觀了, 當我們修改使用者的語言時, 元件未根據我們選擇的語言進行語言的變化, 這種功能發現之後讓對應同學加一下就好了。
十二: 單獨寫的元件
有這樣一種特殊情形, 在使用舊元件庫
的時候, 某個元件的功能不能滿足開發的需求, 當時的開發同學自己寫了一個與元件庫裡的元件樣式一模一樣
的元件, 這個元件可能傳參的規則是獨立的, 無法與新的元件庫無縫替換。
全域性替換新元件庫
後, 實際上上述的元件並沒有被替換, 它還是保持舊版ui的樣式, 因為它是單獨編寫的所以也不會報錯, 但就是樣式的改版需要我們單獨為其編寫一下, 也挺累人的。
這個問題也比較棘手, 因為實在是好難發現, 發現了修改起來也不是想象中的那樣容易, 給我的啟示就是以後進行使用元件庫提供的元件進行開發, 自己寫的元件無法進行更好的更迭。
十三: 樣式變數的改變
比如舊元件庫
裡面定義紅色分為red-01, red-02, red-03
幾種型別的class名或者css變數, 分別表示深與淺的紅色, 專案程式碼中也同樣引入了舊元件庫
提供的這些變數。
新元件庫
裡面也有一套自己的css 或者 scss 變數
, 命名與之前的完全不一樣, 這導致比如我之前使用red-01
現在要改成color-obvious
, 像這種css變數
之間的對應關係可能需要寫個函式迴圈比對, 但是不好的是他們的rgba
色值很可能完全不一樣, 這就導致完全無法一一對應, 頭疼不已。
這類問題只能一個一個的和ui對比了, 這裡給我的啟發就是哪怕一個小小的css
變數, 都需要一套完整的命名規範來設計才行。
十四: 迴圈出來的未知屬性
上面我講過了, 某些屬性的取值範圍可能變化了, 比如button
的size
屬性的取值範圍從 big mini small
, 新版元件庫變成了default large
,這個是眼睛可以看到的, 但是有一種情況就慘了。
這裡的舉例寫法:<button size={btSize}>ok</button>
這裡面的btSize
是一個上層元件傳遞過來的變數, 這時ts可能會不報錯但是它仍然會出現取值錯誤的問題。
要為這種情況專門寫一下轉換屬性的方法比如:
let size = 'default';
if(btSize === 'small' ){
size = 'large';
}
這裡用button舉例是因為它比較簡單, 實際情況比這個要難處理。
十五: 用法的拆分
比如彈出框
元件舊版元件庫
匯出一個Modal
, 可以直接<Modal/>
也可以Modal.info()
呼叫彈出框, 新版將它分為 modalFn
方法 與 Modal
元件。
之前的好多寫法都要拆解替換, 每頁都要檢查不能遺漏。
十六: 舊ui 與新ui一起使用出錯
當使用彈框元件
與下拉框元件
聯合使用的時候, 如果點選下拉框元件喚出下拉框, 彈框元件
內部發生 '滾動',下拉框元件
的下拉框還是停留在原位。
新舊元件庫共同使用是存在風險的, 因為它們有可能根本就無法相互配合, 而且新組建的同學也不願意修復這種 "問題"。
十七: 元件功能的抽離
比如舊版input
輸入框元件發生錯誤的時候, 我們會傳一個errortip='不可以為空'
這類的屬性, input
就會出現紅色的提示框與下方的提示資訊, 但是新版元件庫將這個功能完全放在<FormItem></FormItem>
這個標籤裡面, 也就是說如果我們想讓input
框出現錯誤提示就要, 包一層<Form>
再包一層<FormItem>
, 但我們實際有很多地方並不適合這樣做。
這種能力剝離的改版, 一般就是對業務理解的不同導致的, 如果訴求合理的話最好能把這個屬性加回來。
十八: 整體類名的變化
css檔案中, 這是一個必須解決的問題, 因為我們會寫一些全域性的css樣式
, 比如某個元件內的某個元素必須30px
寬, 之類的屬性吧, 但是更換元件庫後元件的類名完全變了, 我們需要改掉這個名字。
js邏輯中, 有可能出現根據某個型別獲取元素的情況, 這種情況最好也全域性改一下。
十九: 程式碼庫質量問題 例如ts報錯
使用一套程式碼庫的時候, 就好拉他的程式碼到本地看一看, 比如他是否邏輯嚴謹, 取值是否做了很多容錯, 比如xxx.vvv.bbb
還是xxx?.vvv?.bbb
, 並且要看他的ts型別
是否完備, 比如寫了一些any
或是在頁面上放了很多/* eslint-disable */ 或者 // @ts-nocheck
那就建議謹慎接入把。
二十: 元件掛載dom不同
這是個挺別緻的bug
, 主角是舊版彈框元件
, 比如在編輯頁面
彈出是否要離開本頁的提示, 使用者頁面路由發生變化這個彈框也就自動銷燬了, 但是新版彈框元件
並不會銷燬, 因為它預設是掛載在body
身上, 這就導致很多彈框關不掉
, 切換了頁面這個彈框還是在螢幕上。
這種情況要不就找對應同學修一下, 要不就每個操作都主動加一個銷燬當前彈框的操作。
二十一: 人力不足
人力是很關鍵的問題尤其是 新元件庫
側同學的人力, 很多問題被發現但又無法2日內解決, 這種情況很容易造成 "開發時間拉鋸戰", 所以建議類似專案需要在新的ui庫
有專門的開發同學專項支援的情況下進行替換, 我們與其配合完成這個艱鉅的工作。
end
這次就是這樣, 希望與你一起進步。