背景
Shopback 的後端跑在一組微服務上——每個服務各自管理一個領域,透過網路溝通,各自擴縮容。這個架構有清楚的好處,也有顯而易見的成本:閒置的 container 仍然佔用分配的資源,就算當下沒在處理任何流量,機器費照算。
遷移到 monorepo 架構的動機之一就在這裡。TypeScript monorepo 讓多個服務可以共享同一個 process 和資源池,閒置的開銷縮小,機器費也跟著縮小。
我的子任務很具體:兩個服務原本透過網路互相呼叫 API,遷移之後改為在 monorepo 裡直接呼叫函式。聽起來是個重構。實際做起來,變成我實習期間最困難的一件事。
為什麼這件事很難
第一層困難是技術面。Shopback 的 TypeScript monorepo 結構主要是為 library 和共用套件設計的——這是 monorepo 最常見的使用情境。在這個結構裡跑真正的後端服務是另一回事。服務有自己的啟動生命週期、自己的 framework 相依、自己的 runtime 問題。Library 沒有這些。
團隊裡已經有工程師實作了部分 monorepo,但針對的是 library 使用情境。他們的程式碼我看得到,但沒辦法直接套用——他們設計時的假設對 running services 不成立,尤其是不同後端 framework(我們跨服務用了不只一種)在 monorepo 的依賴解析機制下如何互動。
還有版本相容性的問題。TypeScript monorepo 在 workspace 層級管理套件版本,而某些跨服務依賴有寫死的版本假設,合在一起跑就會出現衝突。這不是能用 grep 找到的 bug,而是跑起來才會炸、而且 stack trace 看不出所以然的那種問題。
Mentor 也沒有答案
第二層困難是:我的 mentor 也沒做過這件事。
這不是批評,就是事實。他有自己的工作,能幫的地方他都幫了。但針對我在解的這個遷移問題,他跟我一樣是從零開始。
所以我在一個技術問題上獨立工作,沒有團隊裡的前例,codebase 夠大、搞清楚相關部分要花真正的時間,而 framework 設定在內部也缺乏文件記錄。
兩三個 Sprint,我進度緩慢。我能看出需要做什麼,但真的讓實作跑起來是另一回事。
那條 Slack 訊息
最後我做了一件我一直猶豫要不要做的事:主動傳訊息給另一個團隊的資深工程師,他是我知道曾碰過 codebase 相鄰部分的人。
我也不太清楚自己為什麼等了那麼久。大概是不想打擾一個從沒直接合作過的人,加上一個「我應該自己想辦法」的假設。這兩個理由都不是卡住的好理由。
他回了。他說明了他在處理類似問題時用的方法。我看了他的程式碼,拼圖對上了,下一個 Sprint 裡完成了遷移。
前後加起來三到四個 Sprint。實習的一大段時間。
帶走的東西
技術上的收穫是真實的,但不是最重要的。TypeScript monorepo 跑服務而不只是共用套件時有哪些限制;framework 版本邊界為什麼重要——我都學到了,以後用得到。
更持久的東西是關於卡住的時候怎麼工作。
我把自己的資源範圍框住了。我只看身邊直接的同事、能找到的內部文件、讀得到的程式碼。這些都不夠。答案就在一條 Slack 訊息外面,對象是一個我從沒說過話的人。
現在回頭看——2026 年中,快一年後——我看到自己讓那個問題在腦袋裡多待了不必要的時間,因為我對「求助」的定義框得太窄。那個資深工程師不是我的 mentor,也不是被指定來幫我的人。但他是有我需要的知識的人,而大多數人在你清楚地開口問的時候都願意分享。
別把求助的範圍限制在名義上負責幫你的那些人。對的人可能在公司的另一個地方、另一個團隊,或者,有時候,是某個你主動找到的陌生人。
那個限制在我腦子裡,不在組織架構圖上。
