D2 是一種聲明式流程圖的領域特定語言 (DSL),聲明式只需要描述你想要的流程圖即可,它就會自動生成對應的圖像。

例如,在左側提供如下所示的輸入,然後在右側我們就可以得到對應的輸出流程圖。

D2 的設計目標只有一個:把流程圖變成工程師的愉快體驗,很多工具對簡單的圖表可以做到這一點,但是當你接觸到稍微複雜的流程圖的時候就非常困難了。
這是因為今天的大多數流程圖工具都是設計工具,而不是開發工具,他們給你一個空白的畫布和一個可以拖放的工具欄,類似於 Figma 或者 Photoshop 那樣,並且把他們的預期工作流程視為設計過程,但是工程師並不是視覺設計師,缺乏對系統進行空間架構的能力不應該阻礙有價值文檔的創建,每一次拖放都不應該需要計劃,聲明式的流程圖就可以消除這種困難點。
設計決策以下是指導 D2 開發的設計決策,我們盡力避免過去的錯誤,並從成功的現代編程和配置語言中獲取靈感。
設計決策本質上意味着權衡,你可能不同意其中的一些決定。但是,如果你是一名程序員,那麼 D2 就是為你打造的,而且我們相信你會發現這些決定是一種讓你感到自在的語言。
可讀性 > 原型速度可讀性和原型製作速度都很重要,D2 通常更傾向於可讀性。D2 的語法很輕巧,希望你能按順序在易用性、原型製作速度和可讀性之間找到良好的平衡。D2 特別避免的是簡潔、緊湊的語法,它會抑制所有這三者。
例如,這裡有兩種定義圓柱體的方法。
D2
A:Christmas{shape:cylinder}Mermaid
A[(Christmas)]D2 不那麼緊湊,但更具可讀性。
警告 > 錯誤D2 將儘可能地進行編譯,例如,假設你應用了一個不存在的類,或者添加了一個對特定形狀沒有影響的樣式。如果用戶錯誤是 D2 可以忽略的錯誤,它會編譯成功,最多就是發出警告。沒有什麼比在調試時注釋掉一些代碼,然後收到一個停止的錯誤消息更煩人的了。
安裝推薦的安裝方式是運行我們的安裝腳本,它會根據您的機器找出最佳的安裝方式,比如如果 D2 可使用包管理器,那麼它將使用該包管理器進行安裝。1個
#With--dryruntheinstallscriptwillprintthecommandsitwilluse#toinstallwithoutactuallyinstallingsoyouknowwhatit'sgoingtodo.curl-fsSLhttps://d2lang.com/install.sh|sh-s----dry-run#Ifthingslookgood,installforreal.curl-fsSLhttps://d2lang.com/install.sh|sh-s--按照提示進行操作,通過運行 d2 version 來測試你的安裝是否成功。
$d2versionv0.0.13如果你想卸載則可以使用下面的命令:
curl-fsSLhttps://d2lang.com/install.sh|sh-s----uninstall此外我們也可以直接通過源碼進行安裝,只需要執行下面的 go install 命令即可:
goinstalloss.terrastruct.com/d2當然我們也可以直接從 Github release 頁面 https://github.com/terrastruct/d2/releases 下載編譯好的二進制文件。
基本使用安裝完成後我們可以用下面的命令先簡單測試下 d2 的使用:
$echo'x->y'>input.d2$d2-winput.d2out.svg上面的命令會在本地瀏覽器中打開生成的流程圖,當更改 input.d2 內容時該瀏覽器會自動刷新。

比如我們將 input.d2 內容更改為下面的內容:
x->y:helloworld這聲明了兩個形狀 x 和 y 之間的連接,標籤為 hello world。

我們可以像下面的方式來聲明一個形狀:
imAShapeim_a_shapeimashapei'mashape#注意,一個連字符不是連接#而`a--shape`將是一個連接a-shape
還可以使用分號在同一行上定義多個形狀:
SQLite;Cassandra默認情況下,一個形狀的標籤與形狀的鍵相同。但是,如果你希望它有所不同,可以像這樣分配一個新標籤:
pg:PostgreSQL默認情況下,形狀的類型是矩形,要以其他方式指定,請提供 shape 字段:
Cloud:mycloudCloud.shape:cloud比如下面的代碼:
pg:PostgreSQLCloud:mycloudCloud.shape:cloudSQLite;Cassandra會被渲染成如下所示的圖形:

鍵不區分大小寫,因此 postgresql 和 postgreSQL 將引用相同的形狀。
連接連接定義形狀之間的關係。形狀之間的連字符貨箭頭可以用來定義連接。
WriteReplicaCanada<->WriteReplicaAustraliaReadReplica<-MasterWriteReplica->MasterReadReplica1--ReadReplica2如果你在一個連接中引用一個未聲明的形狀,它就會自動創建它,比如上面 hello world 所示示例。
定義連接有 4 種方法:
連接標籤
ReadReplica1--ReadReplica2:Keptinsync連接必須引用形狀的鍵,而不是其標籤
be:Backendfe:Frontend#這會創建新的形狀Backend->Frontend#這將定義現有標籤上的連接be->fe比如我們聲明如下所示的代碼:
WriteReplicaCanada<->WriteReplicaAustraliaReadReplica<-Masterx--ysuperlongshapeidhere--\->superlongshapeidevenlongerhere渲染後的流程圖如下所示:

重複連接
重複連接不會覆蓋現有連接。他們會聲明一個新的。
DB->S3:backupDB->S3:backup
連接鏈
為了可讀性,在一行中定義多個連接可能看起來更自然。
#標籤應用於鏈中的每個連接HighMemInstance->EC2<-HighCPUInstance:HostedBy
循環
StageOne->StageTwo->StageThree->StageFourStageFour->StageOne:repeat
箭頭
要覆蓋默認箭頭形狀或在箭頭旁邊添加標籤,請在名為 source-arrowhead 和或 target-arrowhead 的連接上定義一個特殊形狀。
a:Thebestwaytoavoidresponsibilityistosay,"I'vegotresponsibilities"b:Whetherwearyorunweary,Oman,donotrestc:Istillmaintainthepointthatdesigningamonolithickernelin1991isaa->b:Toerrishuman,tomoobovine{source-arrowhead:1target-arrowhead:*{shape:diamond}}b<->c:"Realityisjustacrutchforpeoplewhocan'thandlesciencefiction"{source-arrowhead.label:1target-arrowhead:*{shape:diamondstyle.filled:true}}d:Ablackcatcrossingyourpathsignifiesthattheanimalisgoingsomewhered->a->c
目前,箭頭形狀選擇有三角形、箭頭(像三角形但更尖)和菱形,其中菱形可以進一步設置樣式為 style.filled: true。默認的箭頭形狀是三角形。
建議箭頭標籤保持簡短,它們不像常規標籤那樣通過自動布局進行最佳定位,因此長箭頭標籤更有可能與周圍的對象發生碰撞。
容器server#Declaresashapeinsideofanothershapeserver.process#Candeclarethecontainerandchildinsamelineimaparent.imachild#Sinceconnectionscanalsodeclarekeys,thisworkstooapartment.Bedroom.Bathroom->office.SpareRoom.Bathroom:Portal
嵌套語法
我們還可以通過創建嵌套 map 來避免重複容器。
clouds:{aws:{load_balancer->apiapi->db}gcloud:{auth->db}gcloud->aws}
容器標籤
有兩種方法可以定義容器標籤。
gcloud:GoogleCloud{...}或者使用一個 label 標籤指定。
gcloud:{label:GoogleCloud...}比如我們聲明如下所示的流程圖代碼:
clouds:{aws:AWS{load_balancer->apiapi->db}gcloud:GoogleCloud{auth->db}gcloud->aws}users->clouds.aws.load_balancerusers->clouds.gcloud.authci.deploys->clouds渲染後的流程圖如下所示:

此外我們還可以使用文本或者代碼對象、圖標或者圖片、SQL 表等等。比如下面的代碼我們使用了圖標對象:
server:{shape:imageicon:https://icons.terrastruct.com/tech/022-server.svg}github:{shape:imageicon:https://icons.terrastruct.com/dev/github.svg}server->github可以渲染成如下所示的流程圖:

除此之外我們還可以自行定製布局、主題、樣式等等。


D2 有一個官方的、創建者維護的 VSCode 擴展 https://github.com/terrastruct/d2-vscode,可以通過 VSCode 市場免費搜索和下載。該插件完全支持自動縮進和語法突出顯示,使用 D2 語言更加愉快。

關於 D2 語言的更多使用可以查看官方文檔 https://d2lang.com/tour/intro/ 以了解更多。
Git 倉庫:https://github.com/terrastruct/d2