iT邦幫忙

2026 iThome 鐵人賽

DAY 5
0
Modern Web

一個活了六年的 Vue 2 後台,升級到 Vue 3 的那兩年系列 第 5

Day 5|「重構要多久?」這個問題有兩個相差三倍的答案

  • 分享至 

  • xImage
  •  

模組一|現況盤點與立案(Day 1–5)

模組一的最後一天,來談那個一定會被問的問題。

我沒有參與當初的排程討論,所以不知道對外報了多久。

但有件事很有意思:一個重構計畫長什麼形狀,會誠實地留在 git 裡。什麼時候衝、什麼時候緩、什麼時候打第一個版本標記,這些都藏不住。

所以今天這篇是我從紀錄反推出來的,講這個計畫實際上被切成什麼樣子。

先講動機,因為這決定了怎麼切

前四天量到的東西,可以收斂成三層動機。我把它們由外而內排,越外層越好懂,越內層越是工程師才有感。

第一層:維護性。同一個需求要在兩個 repo 各做一次,改完驗兩次。而且 Day 3 已經證明,兩邊已經開始長歪了。

第二層:技術棧壽命。主框架停在六年前的版本,生態裡的新東西一個都用不了,安全性更新拿不到。還有很現實的一點:招人的時候,沒有人想接手維護 Vue 2。 技術棧的壽命會傳染到團隊招募上。

第三層:開發體驗。一次建置吃 6GB 記憶體、開發伺服器慢到大家不敢重跑、沒有型別所以 IDE 幫不上忙。這些單看都是小麻煩,但它們每天都在課稅。

那「想用新技術」算不算好理由?

算,但它必須能翻譯成上面三層的其中一層。你可以說「我想用 Vue 3」,但緊接著要能回答「所以呢?」如果答案是「這樣招人比較好招、共用程式碼只要維護一份、開發速度會變快」,那它就是投資。

如果答案只有「因為它比較新」,那在會議室裡撐不過三個追問。

為什麼不砍掉重練

每個工程師看到兩千行的元件,第一個念頭都是「這個應該砍掉重寫」。這個念頭是對的,但執行方式有兩種,差別很大。

有一種做法叫 Big Bang Rewrite(大爆炸式重寫):把舊的整個丟掉,關起門來寫一份新的,寫完再一次換過去。它的名聲很差,因為失敗率極高。

用一個場景就懂為什麼:

你要把一家還在營業的餐廳整修。

做法 A:直接停業三個月,全部打掉重做。裝潢期間零收入、客人跑去隔壁,而且施工一定會延期。延期的時候你沒有任何東西可以交代。

做法 B:先整修一半,開放營業;再整修另一半。速度比較慢、期間兩邊風格不一致、動線也很醜。但你每天都還在賺錢,而且隨時可以喊停。

我們走的是做法 B:開了新 repo、用新底座,但按業務功能一塊一塊搬。先搬訂單、再搬會員、再搬報表。技術上它是重寫,交付上它是漸進的。

做法 A 的三個致命傷,在我們的處境裡都成立:

  1. 舊系統六年份的業務例外規則沒有文件,只存在程式碼裡。你不逐塊搬,就不會發現它們。
  2. 重寫期間舊系統還要繼續出貨,所以你會變成同時維護兩邊。
  3. 沒有中間交付物。老闆連續四個月看到「零新功能」,第五個月就會來問這件事還要做多久。

第三點最致命。因為重構本來就會延期,而延期的時候,你手上有沒有東西可以拿出來,決定了這個專案會不會被砍掉。

所以,到底多久?

這個問題我聽過很多次,而它有兩個都正確、但相差三倍的答案。

答案一:核心重構,每套系統各約六個月

我把兩個新專案的每月開發量攤開來看。為了讓兩個規模不同的專案能對照,我把各自的高峰當成 100,換算成相對指數:

https://ithelp.ithome.com.tw/upload/images/20260810/201834790f6lQtfL6O.png

先看圖裡的兩條新專案線就好(另外兩條舊系統的線是 Day 26 的主題)。要看的形狀是高峰之後那道斷崖:它不是專案失敗,是主體結束——「六個月」這個答案就是從這道斷崖的位置讀出來的。

第一套系統(通路端)

月份 開發量(高峰=100)
第 1 個月 58
第 2 個月 100 ← 高峰
第 3 個月 93
第 4 個月 39 ← 打出第一個版本標記
第 5 個月 37
第 6 個月 35
第 7 個月 10 ← 斷崖

前三個月是真正的衝刺。第四個月就打出了第一個正式版本標記,然後開發量立刻腰斬,因為主體結束了,剩下的是收尾。第七個月直接掉到前一個月的三成。

第二套系統(總控端)

月份 開發量(高峰=100)
第 1 個月 39
第 2 個月 72
第 3 個月 98
第 4 個月 100 ← 高峰
第 5 個月 63
第 6 個月 31 ← 打出第一個版本標記
第 7 個月 59 ← 不但沒斷崖,還回升

第二套系統的規模大得多(頁面數大約多一倍),所以花了六個月才打出第一版。

但這裡有個誠實的地方要講:第二套系統並沒有像第一套那樣出現斷崖。打完第一版之後的那個月,開發量反而回升。

為什麼?因為那是上線後的驗收期。使用者開始真的用了,問題就進來了。

這件事本身就是一課:「做完」和「穩定」不是同一天,而且中間的距離可能比你以為的長。

兩件事是接力進行的

還有一個我覺得很漂亮的發現。

第一套系統的開發量在第三個月還接近高峰,第四個月腰斬。而第二套系統的第一行程式碼,就落在同一個月。

也就是說,第一個專案開始收斂的那個月,正好是第二個專案起步的那個月。

這不是巧合,是資源必然。團隊就那幾個人,第一個專案進入收尾階段、不需要那麼多人之後,主力就轉場了。

這也回答了一個常見的疑問:如果你有兩套系統要重構,要不要同時進行?從這條時間線看,答案是不要。排隊做,讓第一個專案的經驗餵給第二個。第二個專案的起步方式跟第一個完全不同(Day 12 會專門講這件事),而那個差異正是因為它「已經知道答案了」。

答案二:完整落地,約兩年

https://ithelp.ithome.com.tw/upload/images/20260810/20183479gvoUReCpUl.png

核心重構六個月,但整件事花了兩年。剩下的一年半在做:

  • 驗收與修正:使用者真的用了之後回報的問題
  • 共存期維護:新舊兩套同時活著,這段最貴(Day 13 專門講)
  • 舊系統下線:切換前要確保舊系統有的功能新系統都有
  • 持續重構:這部分永遠不會結束,也不該結束

所以下次有人問你「重構要多久」,正確的回應是反問對方在問哪一段:

  • 談排程和預算 → 講六個月(有明確交付物的那段)
  • 談風險和人力 → 講兩年(真正要付出的總成本)

只講一個數字都是在誤導。 只講六個月,一年後你會被追問「不是說半年嗎」;只講兩年,這個案子當場就會被否決。

這個計畫真正聰明的地方:可以隨時停

[圖 3:發文時上傳並改為外連]

我從 git 反推出來,覺得最值得學的不是時程,是切分方式。

每個業務功能搬完,就是一個可以驗收的里程碑。這代表任何一個時間點喊停,你手上都有東西:

  • 停在第 2 個月 → 至少有新的登入、路由、請求層,這些是可以繼續用的地基
  • 停在第 4 個月 → 有一套能用的新系統,涵蓋主要功能
  • 停在第 8 個月 → 新系統已上線,只是舊系統還沒關

對照 Big Bang Rewrite:停在任何一個時間點,你手上都是一個做到一半、不能上線的東西。

這個差別在順利的時候看不出來。它的價值在於,當公司突然要你把人調去做別的事的時候,你不會損失全部。

而這件事後來真的發生了。在某個階段,第一個專案的開發量連續四個月掉到近乎停擺(Day 26 會講那四個月到底發生什麼事,答案跟大部分人猜的不一樣)。如果當初是 Big Bang Rewrite,那四個月足以殺死整個專案。

代價

這個做法不是沒有成本,有兩個很實在的:

一、你會有一段很長的「兩套並行」期。新功能兩邊都要做,bug 兩邊都要修。這段時間團隊的產出效率是下降的,而且下降得很明顯。

二、漸進式會讓「完成」變得模糊。Big Bang Rewrite 至少有個明確的上線日;漸進式重構的終點是「舊系統可以關掉的那天」,而那天會一直往後延。你需要有人不斷地問「我們還差什麼才能關掉舊的」,否則它會永遠關不掉。

帶走什麼

模組一到這裡結束。這五天的方法可以濃縮成四句:

  1. 先量化,再說服。「我覺得很爛」不是論據,「342 個元件、1 個測試檔」才是。(Day 2)
  2. 找出正在流血的地方,不是最醜的地方。最長的檔案不一定要先改,又長又常改的才要。(Day 2)
  3. 重複的代價不是行數,是「它們正在變得不一樣」。(Day 3)
  4. 重構要能被切成「隨時可以停、停了也不虧」的段落,否則它就是一場賭博。(今天)

明天開始模組二,進入技術決策。Day 6 講一個我們刻意違反官方建議的決定:框架文件說主應用要放在 apps/ 底下,而我們把 93% 的程式碼留在根目錄。


上一篇
Day 4|`this.baseUrl` 從哪來?全域魔法與那些沒人敢刪的東西
系列文
一個活了六年的 Vue 2 後台,升級到 Vue 3 的那兩年5
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言