(總結)專案經歷一次更換ui元件庫才知道的事: 共21種問題型別

lulu_up 發表於 2021-10-14

(總結)專案經歷一次更換ui元件庫才知道的事: 共21種問題型別

image.png

介紹

     寫這篇文章的起因是作者不久前經歷了一次專案整體ui元件庫的替換, 本以為更換ui元件庫只是改改樣式並且改幾處寫法就行了, 但真正經歷了才知道這裡面遇到的問題還真是豐富多彩, 全程做下來我一共總結了21種問題型別, 希望哪一天你也有類似'需求'的時候可以找出來這篇文章看一看。

     我經歷的場景是公司內部研發了新的元件庫, 新元件庫大部分的'使用方式'和'設計理念'與舊元件庫是一致的, 並且是公司內部的庫所以不方便直接截圖舉例子, 文章裡我就用antd來類比展示我遇到的問題, 順帶一提ts真香在更換元件庫時立了大功, 很多問題都是開發人員很難直接監測到的只能靠 ts

一: 屬性的變化

屬性被刪除 (ts可標紅)

     比如 button元件之前有一個 textType用來設定按鈕的定製樣式, 但是在新的元件庫中被刪掉了, 這些舊的特殊樣式需要找ui同學確認是否保留。

新增屬性

     彈出框新增autoFocus屬性, 是否預設聚焦第一個可聚焦元素,如果元件庫使用新增屬性是為了替代某個舊屬性的話, 那麼替換時就需要找到屬性間的對應關係。

屬性改名 (ts可標紅)

     比如彈框的確認按鈕, 之前叫onConfirm事件, 現在叫onOk事件。

屬性取值範圍改變 (ts可標紅)

     舊版元件buttonsize屬性取值範圍是 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

     我們有一種輸入框元件是可以插入一個 選擇框元件, 但是新版元件裡面沒有設定為這種插入元件:

舊元件
image.png

新元件
image.png

     這種問題也比較棘手, 因為它並不會報錯, 只是顯示不一樣, 這就導致只有真切的在頁面上看到了這種錯誤才能發現。

六: 元件缺少

     舊版元件庫提供了懶載入元件錯誤提示元件, 但是新版的元件庫沒有這兩個元件, 這時就需要聯絡負責的同學了, 看是否可以加上這兩個元件, 如果不能加上只能自己親手開發一個了, 這個問題也挺坑的, 無端增加了不小的工作量。

七: 兜底屬性的改變

     舊版元件庫的table表格元件會有預設的error錯誤圖empty空值圖, 但是新版的沒有這些圖片, 需要我們手動的去新增。

     比如彈出框元件的onOk事件如果不傳入的話, 預設點選後是 "關閉彈框", 但是新版元件裡面不傳就是沒有任何操作效果, 這就需要之前沒傳onOk事件的彈框每個都加一下。

     這類問題也比較難發現, 因為並不會報錯但是到處都有。

八: css屬性的錯亂 & 樣式的差異

元素css屬性被改變

     比如table表格元件每個td的差異, 舊版元件裡面沒有為td設定特殊的屬性, 但是新版的表格元件為tb設定了display: flex屬性, 這可把一堆樣式都搞亂了, 簡直慘不忍睹。

     彈框元件footer沒有用div之類的標籤包住, 導致被父級的display: flex影響, 比如我單獨定義footer為一個按鈕的話, 這個按鈕會被抻拉。

image.png

     這類問題不好解決, 因為新的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變數, 都需要一套完整的命名規範來設計才行。

十四: 迴圈出來的未知屬性

     上面我講過了, 某些屬性的取值範圍可能變化了, 比如buttonsize屬性的取值範圍從 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一起使用出錯

     當使用彈框元件下拉框元件聯合使用的時候, 如果點選下拉框元件喚出下拉框, 彈框元件內部發生 '滾動',下拉框元件 的下拉框還是停留在原位。

image.png

image.png

     新舊元件庫共同使用是存在風險的, 因為它們有可能根本就無法相互配合, 而且新組建的同學也不願意修復這種 "問題"。

十七: 元件功能的抽離

     比如舊版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

     這次就是這樣, 希望與你一起進步。