如果要挑一件事最適合丟給 AI「自動化處理」,依賴升級大概最常被提名——反正就是把版本號改一改、跑一次測試,能過就合併,看起來完全不需要人腦介入。
但真的照這個邏輯做過一次就會發現,「升級依賴」從來不是一個動作,是一整組需要判斷的決定:這個大版本升級有沒有 breaking change、哪些套件即使有新版也故意不升(因為新版本身有問題)、升級之後有沒有連帶影響到專案自己的建置設定。AI 能加速的是「把版本號改掉、把測試跑一輪」這個機械動作,但「這個新版本值不值得升、值不值得信任」這個判斷,跟這個系列從 Day 01 就在講的事情一樣——終究要人來扛。
今天用 PHPUnit & Pest Test Explorer 這個真實專案裡一次真實的依賴升級 PR,具體看這套流程長什麼樣。
PHPUnit & Pest Test Explorer 有一次真實的依賴升級 PR,標題是「升級依賴、把 TypeScript 升到第 6 個大版本、補上 Pest 測試框架幾個功能偵測的缺口」。這個 PR 本身就是很好的示範——因為它沒有把所有套件全部升到最新。
PR 描述裡明講:大部分依賴升到最新版,但每個套件的升級路徑其實不一樣——某個 AST 剖析套件雖然照樣升上了新的大版本,但新版本改變了計算節點起始位置的方式,跟專案裡另一套剖析器的慣例不一致,得額外調整程式碼配合,才能升級成功;另外兩個套件則是刻意維持在舊版本,原因是它們的新大版本改成只支援 ESM 模組格式,跟專案裡某個還沒改成 ESM 的部分不相容,直接升上去會讓建置失敗,所以先鎖住舊版本。
這正是「升級依賴」不是單一動作的具體證據:同一個「把套件升到最新」的任務,拆開來看其實是好幾個獨立的判斷——這個套件的新版本相不相容、要不要為了相容性額外改程式碼、還是乾脆先不升。 如果把整個任務丟給 AI、只給一句「幫我升級所有依賴」,AI 很容易用同一套邏輯處理所有套件(全部改成最新版本號、跑測試看過不過),但真正該做的是逐一判斷每個套件的升級是不是安全的。
這次升級裡還有一個容易被忽略的細節:升級 TypeScript 大版本後,專案的建置設定本身也需要跟著調整,不是只有依賴這個套件的程式碼行為改變。
具體發生的狀況包括:新版 TypeScript 一旦設定裡出現了型別宣告清單,就不再自動包含背景型別定義,所以要額外明講需要哪些型別;某個舊寫法在新版被標記為棄用、雖然還能用但會跳出警告,需要明確設定抑制;新版對跨套件邊界的原始碼解析規則變嚴格,導致原本指向原始碼路徑的設定失效,要改成指向建置產出的目錄。
用一組對照來看這個差異:
❌ 只看版本號,一次升級到底:
「所有 package.json 裡的依賴版本號都改成最新,
跑一次測試,通過就合併。」
→ 沒有意識到「套件升級」跟「建置設定要不要跟著調整」
是兩件事,即使測試通過,也可能只是因為測試沒有
觸發到那個因為新版行為改變而壞掉的路徑
✅ 逐一判斷每個套件、追蹤連鎖反應:
「這個套件升級了,查一下 changelog 有沒有 breaking change;
這兩個套件的新版本會讓建置失敗,先保持舊版本;
升完之後,建置設定裡有沒有哪裡因為新版行為改變
而需要跟著調整(型別解析規則、棄用警告、路徑解析方式)?」
→ 把「套件版本」跟「建置設定」當成兩個要分別確認的維度
這正呼應了我在《用 AI Agent 重構一套無框架的 legacy PHP 系統》那個系列反覆講過的一個模式:本機環境跟正式環境版本不一致時,「測試通過」不能直接當成「行為沒有改變」的證據——這裡的變形是「依賴版本升級後,測試通過」也不等於「連帶的建置設定沒有問題」,因為測試套件本身不一定會涵蓋到建置流程的每個環節。
這次升級的過程裡,還修了一個小地方:某支測試檔案裡有一個寫死的測試數量斷言(斷言應該要跑幾個測試案例),因為升級過程中新增了測試案例,這個寫死的數字沒有跟著更新,變成一個過期的斷言。
這個小細節值得記下來:依賴升級這種橫向、影響範圍廣的改動,很容易產生「副作用式」的小修正——不是升級本身直接造成的 bug,而是升級過程中順便補的測試案例,讓一個原本正確、但寫死數字的舊斷言變成了過期資訊。這也是為什麼「升級完只看測試有沒有全部通過」不夠——要留意測試套件本身有沒有因為改動而需要一併調整。
這個真實案例整理出的具體流程是:
第 5 點特別重要:這份「刻意不升的理由」記錄,跟這個系列一直在講的 ADR、feedback 記憶是同一種東西——把「為什麼」留下來,才能讓下一次的判斷不是從零開始。
回想你自己專案裡的依賴清單:有沒有哪個套件是「故意」鎖在舊版本、不跟著升級的?如果有,這個決定的理由被寫下來了嗎,還是只存在某個人的記憶裡?
明天用另一個真實情境把今天的原則往前推一步:升級 TypeScript 大版本這件事本身,AI 在處理相容性問題時容易漏掉什麼——一個具體的版本升級案例。