影響範圍 —— blueprint deps
blueprint deps 在動任何 unit 之前,先回答一個問題:改這個 unit,會波及誰?
它是唯讀指令,除了 blueprint config 本身不需要任何額外設定,也不會寫入任何檔案。
它與 blueprint inspect 的分工:inspect 負責裁決架構(違規、循環相依、exit code 1),deps 只負責描述 —— 逐 unit 列出被誰引用、引用了誰,不做任何判定。
兩者讀的是同一張圖,而那張圖是從原始碼文字掃出來的,不是解析 AST —— 見 import graph 是怎麼讀出來的。
算出來的 import(path) 不會出現在被引用次數裡,所以影響範圍要當成下限看,不是精確值。deps 的每一種輸出都會以那段說明收尾。
操作方式
npx @kekkai/blueprint deps # 全 unit 排行:依被引用數排序
npx @kekkai/blueprint deps hooks/useCart # 以 unit key 查詢單一 unit
npx @kekkai/blueprint deps src/hooks/useCart/useCart.ts # 以檔案路徑查詢,結果相同三種輸入形式都會解析為相同的 unit key ——
是否帶有 src/ 前綴、是否附上副檔名,均不影響查詢結果。
--json—— 輸出機器可讀格式(供工具或 AI Agent 使用)--framework vue|react—— 專案無 config 且框架無法自動判定時,強制指定 preset
輸出結果
不帶參數 —— 影響範圍排行榜。
所有 unit 依「被多少 unit 匯入」排序,異動風險最高的 unit 列於最上方:
Blast radius (imported-by count):
2 ← hooks/useCart
1 ← services/api
0 ← containers/Cart
0 ← pages/Home
(outside the declared architecture, invisible to deps: legacy/)指定 unit —— 同時呈現上下游兩個方向。imported by 為異動此 unit 的影響範圍;imports 為此 unit 所依賴的對象:
hooks/useCart
imported by (2):
← containers/Cart
← pages/Home
imports (1):
→ services/api加上 --json —— 相同資料的結構化形式。
排行榜的輸出結構為 { units, skipped };單一 unit 查詢則回傳該 unit 物件:
{
"unit": "hooks/useCart",
"importedBy": ["containers/Cart", "pages/Home"],
"imports": ["services/api"]
}查詢不存在的 unit 時,以 exit code 1 結束,並提示可以跑排行榜列出所有 unit;
查詢成功則以 exit code 0 結束。
查詢粒度 —— 由 layer.layout 決定
每個查詢結果的單位是 unit,其界定方式由各 layer 的 layout 決定:
folder佈局 —— 分層之下的每個直屬子項各自成為一個 unit(hooks/useCart、components/HelloWorld)。
直屬檔案的 unit key 不含副檔名,因此deps components/HelloWorld與components/HelloWorld.vue指向同一個 unit。file佈局 —— 保留原 flat 佈局行為,整個分層收斂為單一節點。
此佈局適用於「巢狀資料夾只用來整理檔案,而非宣告 unit」的分層 —— 例如styles/themes/dark.ts仍可歸入同一個 styles 節點。
粒度切換時,deps 會明確標示,不會無聲改變回答的層級:
styles (file-layout layer — answers at layer granularity)相依圖的涵蓋範圍與邊界
- 僅涵蓋已宣告的分層。
layer-first 設定中,architecture.layers以外的資料夾不會納入相依圖;排行榜會將其列為略過項目(如上例的legacy/),避免把「未被掃描」誤讀為「沒有任何 unit 引用」。
module-first 設定則以architecture.modules為外層邊界,且每個 module 的內層資料夾必須位於共用的architecture.layers清單中。外層或內層不在契約裡的資料夾都會列為略過;查詢時會直接說明原因:✗ "legacy/" is outside the declared architecture。 - 測試檔案排除在外(
architecture.testFiles)——
測試對 unit 的匯入不算進影響範圍,跟 lint 側的行為一致。
這件事只成立到 glob 掃得到的範圍 ——
掃到、而且沒有一條 glob 對得上的測試檔,兩邊都算一般原始碼,它的匯入就會被計入。 - 僅有別名匯入與相對路徑匯入會構成相依邊。
套件匯入(axios、vue)不屬於 unit 相依圖 —— 套件的所有權檢核屬於inspect的職責。 - 循環相依僅如實列出,不作裁決。
兩個互相匯入的 unit,會分別出現在彼此的上下游清單中;裁決屬於inspect的職責。
config 驗證
手寫、沒包 defineBlueprint 的 blueprint.config.mjs,載入時一樣會跑完整驗證。
結構性錯誤會立刻以精確訊息回報,而不是在指令跑到一半時炸出一個難以定位的例外:
✗ blueprint.config.mjs: architecture.module is retired in Blueprint 4.0 — move layout and entry onto each layer.