你如果在 AI 快速生成專案,最常見的感覺是這樣:
這篇不是先談「怎麼修」,而是先做一件很務實的事:先知道現況。
第 0 天的專案我故意把節奏放寬(沒有先加任何規矩、檢查),讓 vibe-order 能用即可。結果留下 13 次存檔、可下單,也有測試結果。
今天我做的事很簡單:先畫出誰靠誰地圖,留下第一次量到的對照數字。
這張圖,技術上叫依賴圖。結帳櫃台要問倉庫有沒有貨,這就是靠;把每個櫃台畫成點、誰找誰畫成箭頭,就是這張圖。有了它,後面要加規矩才不會一上來卡住全線。
你可以直接看:
apps/*、packages/* 這種 workspace 裡開發這篇對兩種情況用處不大。一個人自己玩的專案,先不用看。還不必切套件邊界,也先不用看。
先把專案想成一間外帶餐廳:
checkout = 收銀台inventory = 倉庫loyalty = 點數櫃台packages/* 的 index.ts = 前台櫃台正常流程是:收銀台要點數就到 loyalty 的櫃台(index.ts)問,像是 loyalty/src/index.ts。
問題是,若收銀台直接闖進點數櫃台後場(loyalty/src/...)改程式,櫃台改版時收銀台也會一起壞。
這種跨邊界、越界去翻後場的行為,就是我們這篇要抓的重點之一。
舉一個下單後要做三件事的例子:
orders)loyalty)date-fns)比較穩定的寫法,通常是這樣,走每個套件的對外入口。下面的 alias 是示意;vibe-order 實際使用的是 @vibe-order/*:
import { placeOrder } from "@orders"
import { grantPoints } from "@loyalty"
import { formatTwTime } from "@shared/time"
混亂版常常是:
import { placeOrder } from "@orders/src/commands/create.ts"
import { grantPoints } from "@loyalty/src/engine/bonus.ts"
import { DateTime } from "luxon"
import { format } from "date-fns"
你會看到的代價是:
所以 Day 1 不急著修,先量測:到底真的在哪裡繞邊界。
我用 dependency-cruiser 16.10.4 做靜態 import 圖,輸出 reports/ 三個檔(JSON、DOT、Markdown),重點是每個節點的:
Ce:它要找多少別人(出去打電話)Ca:有多少人來找它(被叫進來)I = Ce / (Ce + Ca):比較像總機,還是比較像倉庫窗口是每個櫃台的 index.ts。不走窗口、直接 import packages/B/src/...,就是衝進後場(技術上叫穿層匯入)。
短期比較快,櫃台一改版,結帳櫃台也一起壞。
| 套件 | Ce | Ca | I |
|---|---|---|---|
| apps/web | 7 | 0 | 1.00 |
| checkout | 6 | 1 | 0.86 |
| cart | 1 | 2 | 0.33 |
| inventory | 0 | 2 | 0.00 |
| orders | 0 | 2 | 0.00 |
結帳櫃台很明顯比較像總機:要找 6 個來源,只有 1 個節點會來找它,所以 I 比較高。
這不代表它壞,只代表它依賴的來源比較多;後面我會觀察,這些來源改動時,它是不是也常得跟著改。

圖 1|Day 1 套件依賴圖。箭頭由依賴端指向被依賴套件;橘色為 packages/checkout,藍色為 apps/web。來源:vibe-order 本地實測。
第 0 天第 3 句提示詞本來最容易被我猜中的情境是:
「加忠誠點數功能,結帳完成就加點。」
我原本擔心的是它會直接 import @loyalty/src/...。
實測卻是 fa23997 這次存檔走點數櫃台的窗口 packages/loyalty/src/index.ts,沒有衝進後場。
也就是說:這次最壞猜想沒發生,窗口還算有在走;但結帳櫃台已經要找 6 個別人,仍是盯梢重點。
這份圖不是一次跑就對。這次我跑到第 4 輪才算乾淨:
apps/web/tsconfig.json,TS18003。.next/ 和測試聚合檔一起被掃進去,模組暴增。只排除建置產物與不想量的文件,才得到 20 個模組、11 個節點,當作第一次量到的對照數字。
只看靜態 import,這裡看不到的是:
import()
所以「0 條衝進後場」只代表這次掃到的靜態邊界有走窗口,不能等於系統完全沒有黏在一起的問題。
它的價值是:先把能量、能重跑的對照數字放下來,後面再加會擋下來的規矩(護欄)才有得比。
明天是 Day 2:先用同一組 day0/prompts.md,對照第 1~11 句每次存檔的改動量,看看提示詞越多時,改動是不是越「大包」。
先有 Day 1 的對照數字再做 Day 2,才能知道是專案變複雜,還是 AI 開發方式在偏。
本文的數字與結論都來自本地實測,包含:
npm install --save-dev 'dependency-cruiser@^16'
node scripts/diagnose/dep-graph.mjs
npm run diagnose:deps
腳本雛形由 Claude Code 協作草擬,實際執行與調整由 Codex 與 vibe-order 專案結果對齊。
程式目前只在本機實驗 repo,不直接對外提供連結;發文前我會再做一輪人工複核。