Skip to main content

SSG 工具比較

前面介紹了那麼多先備知識,現在總算來到 SSG 的選擇環節了。網路上這類文章大多都是個人的遷移心得或是 CMS 廠商寫的劣質文章,本文可能是唯一一篇都試過而且告訴你真正的生態系、優缺點、權衡考量的文章,內容包含筆者用過的

沒錯,這些筆者全部用過,絕對找不到第二篇能聊的如此深入的文章。Hugo 和 Docusaurus 因為用最多所以篇幅最長,此外還有一些筆者沒用過但是常見的工具介紹。

決策樹​

文章太長不想看?那看決策樹也夠了,濃縮整篇文章精華。

  • 如果你只是單純的內容創作者/部落客:直接挑一個現成的 Hugo 主題(比如 PaperMod),永遠不自己改程式碼,那 Hugo 的穩定、單一執行檔和快,很讚。

  • 如果你是前端工程師或企業團隊:想要高度客製化、需要靈活的擴充功能,請果斷放棄 Hugo 轉向 Astro 或 11ty。

Astro/Eleventy 會說不使用現成主題是因為現成主題少的可憐;會說 Hugo 用戶無須現代 JS 工具請見下方的受限於 Hugo。

Hugo​

先講結論,綜合以下所有特性 Hugo 最適合的場景其實是個人部落格,尤其適合技術能力不高的一般用戶。

單一執行檔​

筆者認為 Hugo 最大的特色是單一執行檔即可運行無須 JS 生態,因此你可以看到有些主題選擇自行管理 JS library,對比其他基於 JS 的工具你很難看到他們這樣處理 JS 套件,這帶來最大的好處是你的網站獨立於外部工具,即使外部全掛你的網站還是可以正常運行,這讓你在前端這種三年一小改五年一大改的環境中也能單純只依靠 Hugo 的單檔案就能獨立構建。

由於不強制綁定 JS 的關係,Hugo 還有一個特色是很多主題開發者都不是前端開發者,並且 JS 套件使用更少,網站通常都更簡潔輕量且無 JS 環境也能運行,PageSpeed Insights 滿分在 Hugo 是很常見的事情。

速度​

如果你的需求就是要快那 Hugo 確實是一時之選,但是請繼續看完本文再想想是否能承受快的代價。

可規模化​

速度快不見得可規模化,Hugo 的規模化已經經過實戰驗證,可以把美國政府的歷史紙本文件數位化,百萬級別的 V&A Explore The Collections, over 1 million pages generated by Hugo 也有能力構建,其他工具如 Docusaurus 在20000 個頁面的文檔則會失敗。

專案直覺簡單​

Hugo 模板主要基於 HTML,因此不需要學習前端世界換來換去的各種框架,Angular React Vue 都和 Hugo 無關,從一而終就是 HTML/CSS/vanilla JS 搞定。

最重要的是大部分的錯誤都可以自行解決,報錯了就是找報錯檔案,不像現代前端重重依賴要判斷這個錯到底是誰引發的。

模板覆蓋功能​

Hugo 可以在專案根目錄建立同樣路徑的檔案覆蓋主題的同路徑文件,這是很多 SSG 工具都做不到的重要優勢,這個功能讓你能夠輕鬆的覆蓋指定檔案且上游有新版本時仍然可以輕鬆更新。

整合現代前端​

Hugo 的 js.Build 可以讓 assets/js 直接用 import 語句導入 node_modules 套件,然而如果是開發主題而不是自用,這種方式需要下游用戶也自行安裝 node_modules 套件造成麻煩,因此這也促使 Hugo 主題會把 JS 套件打包進主題內部或是直接使用 CDN。

js.Build 也支援 TypeScript 和 ESM 模組。

由於 Hugo 是模板語言因此不可能使用 CSS modules。Hugo 也難以整合 Svelte、React 等框架,如果需要他們獨有的特性那就不該選擇 Hugo。

前後端混雜​

任何專案都應該縮小技術棧,技術棧不是生產力應該越少越好,這對新手、老手、專案初建、專案維護都是正面幫助。

然而這就是 Hugo 最大的問題,明明是在開發前端專案卻要顧及後端語言 Go,這是享受後端語言強大性能的必要妥協,但 Bootstrap 也因此從 Hugo 換到 Astro (ref1, ref2)。

就算不提語言特性單就語法本身,開發 Hugo 所有語法都要重學,舉例來說所有語言執行「一加一」都是 1+1,但是 Hugo 要用 {{ add 1 1 }},這個範例展示了 Hugo 所有語法都要重看文檔,而文檔又是另一個問題。

重要

再次強調 Hugo 所有 API 都要看文檔,所有學過的語言都無法協助判斷同樣功能怎麼在 Hugo 使用,所有東西都要看他的文檔才知道要怎麼用。

文檔糟糕透頂​

文檔又導致學習 Hugo 語法的問題更大,好在現在有社群文檔解決此問題。

行為需要用猜的​

Hugo 運作就是黑箱,你不知道他裡面是怎麼做的,只能去翻 Go 源碼,這對前端開發者是一道門檻。那麼為什麼不看文檔?原因就是前面說的文檔非常爛,搞懂 Hugo 的行為是開發 Hugo 專案最痛苦的地方。

備註

比如說 ToC,Hugo 連檢查有沒有 headings 這種超級簡單的工作都可以變成一個討論串還有多種解法,筆者看過最神奇的方法是判斷 gt (len .TableOfContents) 33,因為沒有標題的目錄會渲染 33 個字符,這個範例同時展示了受限於 Hugo、文檔不明確、開發不線性的問題,這只是冰山一角,實際上 Hugo 開發每天都會遇到類似問題。

成熟度​

Hugo 的大優勢是已經十年了因此足夠成熟,很多開箱即用的方便功能,如 permalinks 設定、render segment、content adapter、UFS override 系統,這些在 Hugo 都是開箱即用,現成主題數量也大幅碾壓其他對手。

受限於 Hugo​

Hugo 內建整合非常多東西,但是不支援的就麻煩了,Hugo 完全是黑箱沒有任何插件功能,而且是 go 語言前端人員也難以做到自己 fork 修改。

此外,Hugo 沒有金主基本上是用愛發電,因此即使你的 PR 合理簡單維護者也有自己的想法決定要不要 merge。

碎片化的開發​

比如建立一個包含 JS 功能的頁面組件,你要這樣做:

  1. layouts 目錄新增 HTML partial
  2. assets/css 新增他的 CSS 設定
  3. assets/js 新增他的 JS 功能
  4. layouts/header 載入新增的 CSS/JS,或者是 assets/css/main.css 和 assets/js/main.js 載入這兩份資產

只是一個組件你要改動至少四個檔案,每次維護、除錯就是在多個檔案跳來跳去,而且沒有任何規則完全靠約定俗成。很多現代的 JS 都有單檔案的開發,比如 Vue 有 SFC,Astro 的核心 frontmatter 天生也是模組化設計,同樣身為模板的 11ty 也有 WebC 套件單檔案開發,就 Hugo 要跳來跳去。

開發過程跳來跳去很躁,維護你也只能純靠經驗跟記憶自己找引用,很脆弱。

生態系​

生態系的重要性不言而喻,然而 Hugo 即使已經十年還是有很多不足,例如 prettier 處理 Markdown shortcode 的方式錯誤,好在 Markdownlint 可以正確處理;但是對於包含 Go template 的 HTML,prettier-plugin-go-template 作者已經不再維護,對 Hugo 開發是致命問題1。

相反的,因為 Hugo 多數功能都只是 HTML 模板因此很少會有模組不能用的問題,會碰到過時模組通常也只是用了 Hugo 淘汰的 API 只要照 error message 提示就可簡單修復。相較之下 Hexo 專案修復過時模組就因為 JS 互相依賴變的非常複雜。

插件系統​

Hugo 完全不支援插件,因為很重要所以是獨立段落。

穩定性​

作為單一 binary 無依賴的執行檔,他很穩定;在不同版本之間頻繁 deprecation,非常不穩定。

十年了還不是正式版,永遠無預警、無路線圖的發出 breaking changes,最好笑的是 Cloudflare 根本不管 Hugo 是 0.x.x 直接把 Hugo 歸類到不遵守 semantic versioning 的那類,更諷刺的是所有 Hugo 主題實際上都不遵守 semantic versioning 因為上游不斷 breaking change。

專案狀態​

Hugo 最大的隱患是維護者只有兩人,加上前面說的前端開發人員難以貢獻 Hugo 專案,這是極度不健康的專案狀態。

請注意筆者絕對沒有要否定維護者的貢獻,他們已經穩定持續無償付出多年,這裡只是陳述事實。

企業環境運行​

Hugo 沒有應用程式簽章,綜合專案狀態、語言特性、維護成本、人員招募問題,筆者也不覺得企業使用 Hugo 是明智的決定。

Hexo​

Hexo 基於 JS 因此和 JS 生態使用更為融洽,適合有前端經驗的用戶,也意味著你需要處理 node_modules 的各種問題。

Hexo 構建效能已經不再是劣勢,然而專案維護狀態和他的生態系在 2025 的今天已經不忍卒睹,上網搜尋 Hexo vs Astro 全都是從 Hexo 遷移到 Astro 的文章,不過由於筆者沒親自用過 Astro 所以沒有把他寫成一個獨立段落。

Docusaurus​

Docusaurus 是文檔 SSG,專門用於生成三欄佈局的文檔網站。如果 Markdown 文件數量不超過兩萬234 那你沒有任何理由選擇 Hugo,因為 Docusaurus 幾乎所有東西都做好了而且構建時間也不慢,相較 Hugo 所有文檔主題 Docusaurus 可以說是爆殺級別的存在:

  • 完美的 SPA 導覽,同時又有 MPA 的網站架構
  • 官方完美整合 Algolia 搜尋
  • 支援多版本文檔
  • 豐富的插件生態
  • 支援 MDX

此外還有幾個特點:

  • MDX 有自己的獨特語法,又要多學一套語法,不過 JS 世界的 SSG 大多使用 MDX。
  • Docusaurus 從 3.6 發佈 Docusaurus Faster 計畫的第一版本,使用 Rspack 加速,構建速度急起直追。
  • Docusaurus 使用 React 因此學習成本非常高,明明只是要簡單建立一個客製化頁面,卻要學習整個 React + Docusaurus 生態系,比如說在指定文章開頭加上遷移資訊,Hugo 改模板只要 20 行程式碼就可以搞定,Docusaurus 要學他的整套 API 加上 JS 套件的知識,負擔明顯更大。

說實話由於 Docusaurus 有官方出資維護而且用戶數量多,筆者完全不覺得任何文檔用戶應該選擇 Hugo 的文檔主題,如果不需要 versioning 功能,Vitepress/Astro Starlight 都能納入選擇。選擇 Hugo 放棄 Docusaurus 的原因筆者認為只有兩個,第一個是你的文檔數量超多需要 Hugo 的性能,第二是完全不想碰 JS(或是需要高度自定義但是技術能力不夠)。

效能實測請見此文章,Hugo 在這種情況下佔不到優勢,除非渲染時快取左側導航。

Vitepress​

Vitepress 也是文檔 SSG,和 Docusaurus 的差別是兩者分別 Vue/React,以及 Vitepress 是新工具因此更少歷史債,比如說 Vitepress 直接整合 shiki 而 Docusaurus 用的是 PrismJS。反過來說 Vitepress 更不成熟,生態系更小,資源也更少。

比如說不支援自動路由,也不支援自動 sidebar,也不支援 trim filename digit prefix,這些都要自己寫,而 Docusaurus 這些都是開箱即用。Vitepress 也不支援基於元件名稱的 markdown link,這意味著編輯時不支援 IDE link hover/jumping 功能。

其他筆者認為大同小異,主要還是看 Vue 和 React 兩個框架的選擇上。

MkDocs​

MkDocs 是使用 Jinja,基於 Python 的文檔工具,Python 專案可以使用因為有插件支援自動生成 Python 文檔也無須另一個語言的套件包,但是瀏覽體驗還是 Docusaurus/Vitepress 更好,即使用 Material for MkDocs 也一樣。

MkDocs 本地開發的響應速度明顯比上述工具更慢,且文檔更破碎難找,破碎程度跟 Hugo 有得比,筆者不認為 Python 專案以外的文檔應該用他。

MkDocs 正在逐漸消亡

1.x 版本不更新,2.0 版本關閉開源社區意見改為封閉開發,維護者們意見分歧各自分家。

很多 drama 可以看,這裡直接給 Claude 總結 The Slow Collapse of MkDocs 寫的事件:

時間軸背景:MkDocs 專案原作者 @lovelydinosaur(2014年創立)長期不活躍,@oprypin 於2021年接手成為主要維護者,實際推動專案兩年多。但2024年3月,@oprypin 未經討論就把 @squidfunk(Material for MkDocs 作者)踢出組織,導致 @lovelydinosaur 出面恢復 @squidfunk 權限並解除 @oprypin 的擁有者權限。@oprypin 隨後心灰意冷離開專案。

社群重整嘗試失敗:@pawamoy 曾號召約25位外掛/主題作者重振 MkDocs,@squidfunk 當時也表態支持,但 @lovelydinosaur 回歸後對現有程式碼興趣缺缺,反而私下進行不相容的重新設計,社群號召最終不了了之,專案陷入實質停滯。

MkDocs 2.0 爭議:2026年1月 @lovelydinosaur 宣布 MkDocs 2.0,移除外掛系統、原始碼私有、放在不鼓勵社群貢獻的 encode 組織下。社群反應「壓倒性負面」,認為這已經不是 MkDocs 的延續而是全新專案,且不符合開源精神。

PyPI 搶奪事件(2026年3月9日):@oprypin 利用他從未被撤銷的 PyPI 權限,單方面移除包含原作者在內的所有維護者,聲稱是為了防止 MkDocs 2.0 靜默發布破壞使用者專案。@lovelydinosaur 當場飆髒話反擊,6小時後 @oprypin 退讓道歉,權限歸還。

三方分裂結果:

  • ProperDocs(@oprypin 主導):MkDocs 1.x 的直接替代品,但關注度低(一週僅21顆星)
  • MaterialX(@jaywhj 主導):Material for MkDocs 的延續版
  • Zensical(@squidfunk + @pawamoy 團隊):從零重寫,聲稱原生支援 mkdocs.yml、重建速度快5倍、全新搜尋引擎,目前最受歡迎(5,100+ 星),被視為最可能成功接棒的方案

如果想避免 MkDocs 的供應鏈問題可嘗試 Zensical,筆者目前還沒試過。

Sphinx​

Sphinx 是一個文檔建立工具,支援自動生成 Python 專案的文檔,其他功能都很陽春且古老,除了自動生成 Python 文檔以外的任何情況都不應該選擇 Sphinx。

GitBook​

GitBook 原本是一個開源的文檔工具但現在已經完全轉型成商業 SaaS 平台,筆者不認為有任何一種情況需要放棄本文的其他工具去用 GitBook。

docmd​

docmd 特色是一鍵啟用的文檔網站,一般用戶可以單行指令啟用網站,對於進階用戶提供 hook 自定義構建流程。

docmd 是用 node.js 建立原生 HTML/CSS/JS 網站,內建支援 AJAX 流暢換頁(類似 swup/barba.js 這種效果),背後的核心邏輯是 docmd 自己建立的模板工具 lite-template + markdown-it 轉換成 HTML。docmd 的 hook 很實在:

  • markdownSetup: 可自訂 markdown-it,如 custom container (::: new-container-block)
  • onBeforeParse: 可自訂 markdown 在 docmd parse 之前的處理,因此甚至能做到建立 shortcode

docmd 內建離線搜尋,versioning 功能也很棒。

然而也存在問題,docmd 不支援 override 模板,預設的 HTML 結構無法更改,如果他能做到模板 override 功能至少可以吃掉一半的 Hugo 文檔網站用戶,因為 Hugo 網站普遍沒有 SPA-like navigation。然而如果終究是如果,目前來說筆者想不到有什麼理由不用 Docusaurus,你真的想 Docusaurus 也可以完全不管設定檔就照原始設定檔用,那也等於一鍵啟用。

其他​

其餘的 SSG 工具們。

試用過的​

  • Astro: 最熱門的新框架,基於 JS 的島嶼架構,不再需要整個頁面 hydration,每個組件可獨立注水,除此之外最重要的是不限定 JS 框架,是目前最新穎最受歡迎的、基於 JS 的 SSG。2K Games, Cloudflare 和 Netlify 官網以前都用 Hugo,2025 的現在都用 Astro,這樣知道他的優勢有多大了吧,不過由於個人網站幾乎用不到 Astro 提供的優勢因此筆者就沒有跳家了
    • Astro Starlight: 無框架的 Astro 文檔主題,構建速度甚至比同佈局的 Hugo 專案更快,最大的優點是無框架,缺點同樣也是無框架。
  • 11ty: 和 Hugo 一樣核心是模板,只有一個維護者,構建速度能和 Hugo 打的有來有回,但是沒有主題概念。此外,我覺得架構設計的不好,專案到處都是 js 檔案,我很討厭把文件和原始碼混在一起,這明顯是設計給開發者用的

沒用過的​

  • zine: 用 Zig 寫的,比 Hugo 還快,但是非常有主觀意見:使用自己的 superHTML 和 superMD,自己是一套生態系
  • Zola: 和 Hugo 一樣核心是模板,只有一個維護者,近兩年已經不再開發,不該使用
  • Gatsby、Jekyll: 非常老,不該使用
  • NextJS/Nuxt: 對於個人網站技術負擔明顯過重了

開發狀態也是重要指標,可以點進該專案的 insights > contributors 頁面查看,兩大重點是提交次數和提交人數,分別代表維護狀態和社群活躍度。

金主​

Astro 有 Cloudflare 全球最大網路供應商支撐,Docusaurus 有 Meta,Vitepress 有 Vue 團隊,Next 有 Vercel,11ty 則是 Build Awesome。

Footnotes​

  1. Hugo 官方後來出了自己的 formatter gotmplfmt,用 AI 寫的我沒差,問題是這是 Go binary,沒有放到 npm 生態系,你又要為了他自己寫一套流程整合到 CI,麻煩,而且還不支援任何設定。 ↩

  2. https://github.com/facebook/docusaurus/discussions/11259 ↩

  3. https://github.com/facebook/docusaurus/discussions/10895#discussioncomment-12053592 ↩

  4. https://github.com/facebook/docusaurus/discussions/11199 ↩