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