stack-diagram 是做什麼的?
產生工程圖風格的架構圖表:白色圖塊上的真實標誌、帶標籤的分組方框(如同雲端供應商 VPC 圖表)、使用等寬字型標籤的正交箭頭,並以酷炫的方格紙背景呈現。一個自包含的 HTML 檔案是事實來源;PNG / TSX / artifact 皆由此衍生。
需求
- Python 3.9+(
fetch_icons.py、build.py與share.py僅使用標準函式庫) - 取得圖示時,需要網路連線至圖示來源(svgl.app、raw.githubusercontent.com、cdn.jsdelivr.net、aws.amazon.com 與 d1.awsstatic.com 的 AWS 圖示、services.google.com 的 Google Cloud 圖示、learn.microsoft.com 與 arch-center.azureedge.net 的 Azure 圖示,以及品牌自有網站或倉庫的
name=URL) - 使用
render_png.py需要 Playwright + Chromium:pip install playwright && python3 -m playwright install --with-deps chromium
工作流程
- 確定內容(節點、群組、邊)
- 取得圖示 —
scripts/fetch_icons.py - 規劃座標 — 閱讀
references/geometry.md - 從
assets/template.html建置 HTML —scripts/build.py - 在交付前,先渲染 PNG 並檢視它
- 以要求的格式交付
- 可選擇分享至公開圖庫
步驟 1 — 內容
根據使用者提供的技術/服務清單,決定:
- 節點:每個技術 = 一個節點(名稱 + 簡短的小寫角色,例如
http server、sqlite db) - 群組:將共享執行環境、供應商或倉庫的項目(例如一個雲端供應商的方框包含一個執行環境方框;一個 monorepo 方框包含工具)用方框框起來。巢狀一層是 ok 的;更深會顯得雜亂。群組標籤使用品牌本身的命名方式(
GitHub、npm);範本會以書寫的樣式顯示。 - 邊,分三種:
- 強調色實線 = 主要的請求/資料流程(一條連續路徑最佳)
- 中性色實線 = 次要的內部連線
- 中性色虛線 = 開發/部署時的關係(CI、git hooks、IaC 部署)
如果使用者只提供一個工具清單,則根據工具的性質推斷合理的群組與流程 — 僅在工具模稜兩可,以致無論如何圖表都會錯誤時才提問。
步驟 2 — 圖示
python3 scripts/fetch_icons.py <icons-dir> tanstack hono drizzle "betterauth:better-auth" "orpc=https://orpc.unnoq.com/logo.webp"
python3 scripts/fetch_icons.py <icons-dir> "aws:aws/AWS-Cloud-logo" "vpc:aws/vpc" "fargate:aws/fargate" "s3:aws/s3"
python3 scripts/fetch_icons.py <icons-dir> "gcp:google-cloud" "run:gcp/cloud-run" "lb:gcp/load-balancing" "sql:gcp/cloud-sql"
python3 scripts/fetch_icons.py <icons-dir> "azure:azure/Azure-A" "app:azure/app-service" "vnet:azure/vnet" "sql:azure/sql-database"
python3 scripts/fetch_icons.py <icons-dir> "k8s:kubernetes" "ing:k8s/ingress" "svc:k8s/service" "deploy:k8s/deployment" "pod:k8s/pod"
規格形式:name(用作 slug 的名稱)、name:slug(不同的 slug)、name=URL(明確的 URL)、name:aws/<Name>(官方 AWS 圖示)、name:gcp/<Product>(官方 Google Cloud 圖示)、name:azure/<Name>(官方 Azure 圖示)、name:k8s/<Resource>(官方 Kubernetes 圖示)。腳本的嘗試順序為:svgl → devicon → gilbarbara/logos,會寫入檔案加上 manifest.json,並標記填充顏色為白色的圖示。svgl(svgl.app)是首選,因為它包含現代開發品牌(TanStack、Better Auth、Hono...)的當前官方標誌。當一個標誌有淺色/深色版本時,淺色版本成為 <name>(兩個主題的圖塊都是白色),深色版本則儲存為 <name>_dark 供群組標籤使用。svgl 僅透過精確標題比對,因此若不符則會繼續嘗試。它的 API 也公開 wordmark 變體 — 偶爾對寬群組標籤有用,但從不用於圖塊。
比機制更重要的規則:
- 永遠不要重新著色標誌。 使用者會注意到。如果一個標誌是白色或對白色圖塊來說太淺,請將其放在深色圖塊上(
tile darkclass)而不修改其填充顏色。manifest 的white_fill標記僅供參考 — 白色填充可能是彩色標記上的內部細節(tRPC、Ubuntu),因此在決定使用深色圖塊前,請先查看 SVG。 - 僅使用官方標誌。 simple-icons 故意不作為來源:其字形是單色重繪,使用者一眼就能看出不對。當所有來源都遺漏(
FAIL)時,請找到官方檔案並以name=URL的形式傳入 — 請在專案的倉庫(根目錄logo*.svg、docs/、assets/、public/)及其網站(/logo.svg、/favicon.svg、/images/logo.svg)中尋找。有些標誌只存在於倉庫中(Lefthook 的標誌是evilmartians/lefthook根目錄下的logo_sign.svg)。 - 抽象概念使用象形圖,而不是文字。 像「開發環境」、「cron」、「佇列」、「快取」或「webhook 接收器」這樣的節點沒有品牌 — 請使用
name:lucide/<icon>來取得 Lucide 線條圖示(例如devenv:lucide/terminal、cron:lucide/clock;可瀏覽 lucide.dev/icons)。不要在圖塊中用文字,也不要用 emoji。 - 供應商子產品(Cloudflare D1/R2/KV...)通常沒有獨立的標誌:只需在圖塊上重複使用供應商標誌,並讓節點名稱來承擔區分責任(「Cloudflare D1」/「sqlite db」)。
- AWS 使用 AWS 自己的圖示。 每個服務都有一個:使用
name:aws/<Name>取得,在執行時從 AWS 的官方圖示套件中讀取(例如lambda:aws/lambda、aws:aws/AWS-Cloud-logo、s3:aws/s3)。AWS-/Amazon-前綴是可選的,常見的縮寫有效(s3、sqs、sns、ses、ecs、eks、ecr、elb、alb、nlb、iam、kms、msk、vpc),如果遺漏則會印出所有名稱。slugaws、amazonwebservices與aws-*指向同一個套件,而該套件未提供的會顯示FAIL而不是回退到第三方副本。對於服務,始終寫入aws/前綴:一個裸的dynamodb仍然會通過第三方鏈。將套件和鬆散的圖示檔案排除在倉庫之外:AWS 允許在圖表中使用圖示,但重新分發未經確認。 - AWS 區域遵循 AWS 自身的繪圖規則。 服務圖示自帶其方形,並可在淺色和深色背景上使用,因此使用
tile bare:白色圖塊只會增加邊框。其中的使用者和通用節點則使用 AWS 的一般圖示(user:aws/General-User;還有General-Users、General-Client、General-Internet、General-Server),並搭配範本的lt/dk配對使用tile bare res。群組使用範本的group aws來表示 AWS Cloud(標籤中帶有aws:aws/AWS-Cloud-logo),再加上region、az、vpc、private或public:方形圓角、純外框、標籤用墨水色、無供應商色調,並且在角落有一個 30px 的圖示(而不是 14px)。在 VPC 內部,當你知道或可以安全推斷分隔時,顯示公有與私有子網路(面向網際網路的負載均衡器在公有子網路;應用程式伺服器和資料庫在私有子網路):一個扁平的 VPC 是 AWS 人員首先注意到的。其中的邊使用一種顏色和開放式箭頭:<path class="aws" ... marker-end="url(#open)"/>,開發/部署使用aws dash,一般的.el標籤,並且不為它們建立圖例。節點命名為Amazon S3/AWS Fargate,而不是裸的S3/Fargate;像ALB這樣的簡短形式放在角色行中,在完整名稱(Elastic Load Balancing)之下。名稱可能會佔用兩行,但Amazon/AWS必須保持在第一個單詞行:如果它會在前綴之後立即換行,則加寬該節點(left:<centerX-76>px; width:152px)。 - Google Cloud 使用 Google 自己的圖示。 使用
name:gcp/<Product>取得,在執行時從 Google 的官方套件中讀取(例如run:gcp/cloud-run、lb:gcp/load-balancing、memorystore:gcp/memorystore)。只有核心產品有自己的圖示(Cloud Run、Cloud SQL、Cloud Storage、BigQuery、GKE、Compute Engine、Vertex AI...)。所有其他產品使用其類別的圖示,正如 Google 指南所指定的:Cloud Load Balancing 和 Cloud CDN 都使用 Networking;Memorystore 和 Firestore 都使用 Databases。寫入產品名稱,腳本會選擇圖示。Cloud/Google前綴是可選的,某些簡短形式有效(vpc、iam、kms、iap、gce、gcs),如果遺漏則會印出所有名稱。gcp/storage是 Storage 類別;Cloud Storage 是gcp/cloud-storage。sluggcp-*和google-cloud-*指向同一個套件,而它們未提供的會顯示FAIL而不是回退到第三方副本:那些副本是已退休的六邊形圖示,Google 表示不應使用。對於產品,始終寫入gcp/前綴:一個裸的bigquery仍然會通過第三方鏈。gcp:google-cloud是用於群組標籤的 Google Cloud 標誌。Gemini 和 Firebase 不在套件中:使用裸的gemini和firebase。將套件和鬆散的圖示檔案排除在倉庫之外:Google 提供這些圖示用於圖表和文件,重新分發未經確認。 - Google Cloud 圖表保持正常風格,使用 Google 的群組。 Google 自己的圖表(純藍色面板、水平卡片)故意不複製:圖示放在一般的白色圖塊上,邊和圖例保持不變。群組使用範本的
group gcp來表示 Google Cloud(標籤中帶有gcp:google-cloud),再加上vpc、region、subnet或zone。VPC 是全域的,子網路是區域性的,因此將區域放在 VPC 內部,永遠不要將 VPC 放在區域內部。全域和無伺服器服務(外部負載均衡器、Cloud Storage、Cloud Run)保持在 VPC 外部。由於圖示是共享的,始終寫入產品的完整名稱(Cloud Load Balancing,而不是LB),並加寬名稱會換行的節點(left:<centerX-76>px; width:152px)。 - Azure 使用微軟自己的圖示。 每個服務都有一個:使用
name:azure/<Name>取得,在執行時從微軟的官方套件中讀取(例如app:azure/app-service、azure:azure/Azure-A、vault:azure/key-vault)。Azure-/Microsoft-前綴和複數s是可選的,常見的簡短形式有效(aks、vm、vnet、nsg、waf、blob、cosmos、redis、postgres、functions、front-door、apim、ai-search),如果遺漏則會印出所有名稱。slugazure、microsoft-azure與azure-*指向同一個套件,而該套件未提供的會顯示FAIL而不是回退到第三方副本。對於服務,始終寫入azure/前綴:一個裸的cosmos仍然會通過第三方鏈。Microsoft Entra ID 有個別的圖示集:將其官方檔案以name=URL的形式傳入。微軟僅允許將這些圖示用於架構圖表、培訓材料和文件。切勿裁剪、翻轉、旋轉或重塑任何一個,僅將其用於它所代表的微軟服務,並將套件和鬆散的圖示檔案排除在倉庫之外。 - Azure 圖表保持正常風格,使用微軟的群組顏色。 微軟自己的圖表故意不複製:圖示放在一般的白色圖塊上,邊和圖例保持不變。群組使用範本的
group azure來表示 Azure(標籤中帶有azure:azure/Azure-A),再加上rg、region、vnet、subnet或zone,而vnet或subnet標籤帶有其圖示(vnet:azure/vnet、subnet:azure/subnet)。VNet 屬於一個區域,因此它位於區域內部。像 Front Door 這樣的全域服務則保持在區域外部。App Service 位於 VNet 外部,除非它在 App Service 環境中運行,而透過私有端點訪問的 PaaS 服務可以位於其內部,並以private endpoint作為其角色。微軟要求在每個圖示旁邊標明服務的完整名稱(Azure SQL Database,而不是SQL),因此請加寬名稱會換行的節點(left:<centerX-76>px; width:152px)。 - Kubernetes 使用官方社群圖示。 使用
name:k8s/<Resource>取得,從官方 kubernetes/community 圖示集中讀取(例如pod:k8s/pod、deploy:k8s/deployment、svc:k8s/service、ing:k8s/ingress、cm:k8s/configmap、secret:k8s/secret、node:k8s/node、api:k8s/kube-apiserver)。對於資源和基礎設施,圖示使用無標籤變體,以保持字形在圖表比例下清晰整潔,而控制平面組件則使用帶標籤的變體。常見的簡短名稱和複數形式有效(svc/service/services、deploy/deployment/deployments、po/pod/pods、cm/configmap/configmaps、sts/statefulset、ds/daemonset、node/nodes等)。如果遺漏則會印出可用名稱。slugk8s、kubernetes和k8s/k8s透過鏈提供官方的 Kubernetes 輪子標誌。 - Kubernetes 圖表預設保持正常風格。 圖示位於一般的白色圖塊上,這將它們與技術棧中的其他技術(如 NGINX、cert-manager、外部資料庫或雲端負載均衡器)統一,並在方格紙背景上提供一致的立體感和對比度。對於極簡的獨立字形,也支援
tile bare。群組使用標準群組(cluster、namespace、node、pod)。在圖表頁尾中標註 Kubernetes 圖示集。 - 供應商的規則僅涵蓋其自身的區域。 AWS、Google Cloud、Azure 和 Kubernetes 的規則僅適用於該供應商群組的內部,即使圖表中沒有顯示其他內容。其外部的所有內容,例如旁邊的使用者或進入該群組的邊,都保留正常的圖塊、群組、邊和圖例。
- 非品牌節點(使用者、瀏覽器、網際網路、裝置、裸機伺服器):從
assets/generic/複製一個字形到節點名稱下的圖示目錄中,或使用name:lucide/<icon>— 不要使用 emoji。這些不是品牌標誌,因此可以將它們著色為圖表的墨水色(腳本會自動為 Lucide 執行此操作)。 - 群組標籤圖示以 14px 渲染 — 它們需要一個方形字形標記。文字標記和寬鎖定在這種尺寸下會變得模糊;如果主圖示是文字標記,請分別為標籤取得品牌的方形圖示(svgl 通常有;否則使用專案自己的圖示或 favicon 檔案)。
- 群組標籤位於群組的色調上,而不是白色圖塊上,因此在深色主題中,具有黑色部分的標記會消失在那裡。如果
fetch_icons.py儲存了<name>_dark,則在標籤中使用範本的lt/dk配對;如果沒有深色變體且標記有黑色部分,則在標籤的...中添加 classplate
...
[已截斷以供翻譯]