← 返回上一頁
實測 DevOps 開源軟體

Hugo 0.170 實測:extended 版真的沒了,libsass 直接報錯

下載頁上 hugoextended0.170.0linux-amd64.tar.gz 這個檔名看起來跟半年前一模一樣,抓下來跑 file 一看,type 從「dynamically linked」變成「statically linked」。同一個檔名,裡面已經不是同一種東西,這就是 Hugo v0.170.0 這次最容…

重點摘要
  • v0.170.0(2026-11-13 發布)把 extended 版徹底拔掉,只剩一顆 binary;hugo_extended_* 封存檔還在下載頁,但內容已經跟 regular 版同一顆,不再是真的 CGO 編譯
  • 實測下載官方 hugo_extended_0.169.0_linux-amd64.tar.gz 是動態連結(真帶 libsass C 函式庫),同一個檔名的 0.170.0 版變成靜態連結,跟 regular 版同一顆 Go binary
  • css.Sass 設 transpiler: libsass 在 0.169.0 報「需要 extended 版」,在 0.170.0 直接報「libsass 已移除,請用 dartsass」——錯誤訊息從『裝錯版本』變成『功能不存在』
  • HUGO_ENVIRONMENT=qa hugo build -e staging:0.169.0 讀了 staging 設定卻回報 qa(env 贏,是 bug);0.170.0 正確回報 staging(flag 贏,已修)
  • HUGO_BUILDDRAFTS=false hugo --buildDrafts 在只有 1 篇草稿的測試站:0.169.0 建出 0 篇、0.170.0 建出 1 篇,CI 腳本同時設環境變數又帶旗標的人行為會變
測試環境驗證於 2026-11-14
適用讀者
用 Hugo 建站、CI 腳本裡還在下載 hugo_extended_*、或用 Sass 編譯樣式的維運與前端工程師
測試版本
Hugo v0.169.0(2026-10-27)對照 v0.170.0(2026-11-13),皆為官方 linux-amd64 release 二進位
測試環境
Debian 12-slim 容器,Docker Desktop,amd64
本頁目錄

下載頁上 hugo_extended_0.170.0_linux-amd64.tar.gz 這個檔名看起來跟半年前一模一樣,抓下來跑 file 一看,type 從「dynamically linked」變成「statically linked」。同一個檔名,裡面已經不是同一種東西,這就是 Hugo v0.170.0 這次最容易被忽略的細節。

release note 寫得很直白:extended 版正式沒了,只留一顆 binary。表面上看是「拿掉一個下載選項」,但對還在用 css.Sass 編譯 .scss、CI 腳本寫死抓 extended 檔名的人來說,是建置直接失敗的等級。這篇把 v0.169.0 跟 v0.170.0 的 regular binary、以及兩版的 hugo_extended_* 封存檔都抓下來,在容器裡跑一輪,看差異到底多具體。

讀完能帶走三件事:extended 消失後錯誤訊息怎麼變、hugo_extended_* 別名封存檔實際是什麼貨色、以及這版順便修掉的旗標 vs 環境變數優先順序問題會不會動到你的 CI。

Hugo v0.170.0 關鍵數字:libsass 編譯失敗、flag 覆蓋 env、extended 封存檔改為靜態連結
圖 1:本次實測的四組關鍵對照(來源:本機實測)

github.comgohugoio/hugo v0.170.0extended 版移除,css.Sass 只剩 Dart Sass,旗標優先序修正★ 90k+ · Apache-2.0 · 2026-11-13

一、背景:extended 版為什麼存在,又為什麼被拔

Hugo 從早期開始就有兩種發行版:regular(純 Go,CGO_ENABLED=0)跟 extended(CGO_ENABLED=1,多連結一顆 C 寫的 libsass,拿來編譯 Sass/SCSS)。想用 resources.ToCSS(後來的 css.Sass)處理樣式表的人,得特地去抓檔名帶 extended 的版本,不然建置會在 css.Sass 那一步噴錯。

Dart Sass 支援進來之後,libsass 其實早就被官方標成 deprecated——v0.153.0 開始,css.Sass 用 transpiler: libsass 會印一行 warning,提醒之後會拿掉。只是大多數人沒細看 release note,照舊沿用舊設定檔跑了快十個版本。

版本說明

libsass 的 deprecated warning 從 v0.153.0(約一年前)就開始印,v0.170.0 只是把「警告」正式升級成「移除」。中間這段時間已經是給大家遷移到 Dart Sass 的緩衝期。

CGO 編譯有個現實麻煩:它需要目標平台有對應的 C 工具鏈,跨平台編譯變複雜,二進位也不是純靜態(dynamically linked),在某些最小化容器基底上會因為缺 libc 版本而跑不起來。維護團隊把這包袱拆掉,於是 v0.170.0 把 extended 整個停產,只留一顆靜態連結的 Go binary。

二、這次具體改了什麼

2.1 binary 層面

項目 v0.169.0 v0.170.0
官方發行版數量 regular + extended 兩顆 只剩 regular 一顆
hugo_extended_<ver>_linux-amd64.tar.gz 真的存在,CGO 編譯 仍保留檔名(相容舊 CI),內容換成跟 regular 同一顆
hugo.IsExtended regular 版本來就是 false 恆為 false(已無任何官方 binary 會是 true)
css.Sass transpiler: libsass 可用(extended 版)/regular 版報錯要求裝 extended 直接報錯:功能已移除
flag 是否覆蓋 HUGO_* 環境變數 否(env 贏,有 bug) 是(flag 贏,已修正)

這張表裡第二列最容易被忽略。官方刻意保留 hugo_extended_* 這個檔名,不是因為裡面的東西沒變,而是怕一次拿掉連下載連結都找不到,會讓舊版 CI 腳本直接 404。但保留檔名、換掉內容,反而製造了一種「看起來還能用」的假象:下載腳本不會報錯,直到跑到 css.Sass 那步才爆炸。

2.2 兩個官方 binary,實測確認型態差異

v0.169.0 extended 封存檔是動態連結含 libsass C 函式庫,v0.170.0 同檔名變成與 regular 版相同的靜態連結 Go binary
圖 2:extended 封存檔的內容在兩版之間的實際變化(本機繪製)

分別把兩個版本的 hugo_extended_<ver>_linux-amd64.tar.gz 解開看 ELF header:

本機
$ file h169-extended/hugo h170-extended/hugo
h169-extended/hugo: ELF 64-bit LSB executable, x86-64, dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, stripped
h170-extended/hugo: ELF 64-bit LSB executable, x86-64, statically linked, Go BuildID=..., stripped

v0.169.0 那顆有 interpreter /lib64/ld-linux-x86-64.so.2,代表執行時要去找動態函式庫,這是 CGO 編譯的典型特徵,裡面真的連結了 libsass。v0.170.0 同檔名的那顆完全沒有 interpreter 欄位,是純 Go 靜態編譯,跟 regular 版本質上是同一顆程式。官方把舊檔名留著給還沒更新 CI 腳本的人下載,但下載到的東西已經名不符實。

三、實測環境與方法

3.1 環境

項目 內容
容器 debian:12-slim,amd64
編譯環境 Docker Desktop
Hugo 版本 v0.169.0(2026-10-27)、v0.170.0(2026-11-13),皆為官方 linux-amd64 release 二進位
extended 封存檔 同版號的 hugo_extended_<ver>_linux-amd64.tar.gz,用來比對二進位型態
測試日期 2026-11-14

3.2 方法

兩個版本各自裝進獨立的 Debian 容器,跑同一組測試站台(一個有 .scss 資源、一個有 1 篇 draft 文章的最小 Hugo 專案)。每組測試都是對照跑:先跑 v0.169.0 記錄輸出,再跑 v0.170.0 記錄輸出,指令與參數完全一致,只換 binary。輸出照貼,沒有取平均也沒有重複跑(這些是確定性輸出,不是效能數字,跑幾次結果都一樣)。

3.3 原始輸出:版本號

v0.169.0
$ hugo version
hugo v0.169.0-1da10fc44701c566b1669cdb2d12638f155138bd linux/amd64 BuildDate=2026-10-27T14:52:20Z VendorInfo=gohugoio
v0.170.0
$ hugo version
hugo v0.170.0-f7aa05f0f521611aa960b2da56e1870ea04f57b2 linux/amd64 BuildDate=2026-11-13T14:17:19Z VendorInfo=gohugoio

3.4 原始輸出:libsass 編譯

layout 裡放一段 css.Sass (dict "transpiler" "libsass") 處理 main.scss:

v0.169.0(regular binary)
$ hugo
WARN  deprecated: css.Sass: libsass was deprecated in Hugo v0.153.0 and will be removed in a future release. Use dartsass instead.
ERROR error building site: render: [en] failed to render pages: render of "/" failed:
  executing "index.html" at <.Content>: error calling Content: TOCSS: failed to transform "/sass/main.scss":
  Check your Hugo installation; you need the extended version to build SCSS/SASS with transpiler set to 'libsass'.
v0.170.0(regular binary)
$ hugo
ERROR error building site: render: [en] failed to render pages: render of "/" failed:
  executing "index.html" at <css.Sass>: error calling Sass:
  css.Sass: the libsass transpiler was removed in Hugo v0.170.0 (deprecated from v0.153.0); use dartsass instead.

兩段錯誤訊息長得像,但意義完全不同。v0.169.0 那句「你需要 extended 版」隱含一個可行動作:去抓 extended 版就能解決。v0.170.0 那句「已經移除」沒有這個退路,唯一出路是把設定改成 dartsass。如果 CI log 只抓關鍵字 "extended" 來判斷要不要切版本,這次升級會讓腳本邏輯整個失效。

3.5 原始輸出:旗標 vs 環境變數

第一組:-e 旗標與 HUGO_ENVIRONMENT 環境變數同時設定不同值:

v0.169.0
$ HUGO_ENVIRONMENT=qa hugo --quiet -e staging
EnvironmentHugo=qa
v0.170.0
$ HUGO_ENVIRONMENT=qa hugo --quiet -e staging
EnvironmentHugo=staging

v0.169.0 這組是 release note 點名的 bug:它實際上載入的是 -e staging 指定的設定檔,但模板裡 hugo.Environment 讀回來卻是 qa。也就是說設定套用對了,回報的值卻是錯的。這種「行為對、回報錯」的 bug 特別難抓,因為建置結果看起來正常,只有依賴 hugo.Environment 做條件判斷的模板邏輯會悄悄走錯分支。v0.170.0 修正後兩者一致,flag 真正贏過環境變數。

第二組:草稿建置開關,一樣 env 與 flag 互相矛盾:

v0.169.0
$ HUGO_BUILDDRAFTS=false hugo --quiet --buildDrafts
Drafts=0
v0.170.0
$ HUGO_BUILDDRAFTS=false hugo --quiet --buildDrafts
Drafts=1

測試站只放了 1 篇標記 draft: true 的文章。v0.169.0 底下,即使指令明確帶 --buildDrafts,只要環境變數殘留 false,草稿就是不會被建出來。這種情境在 CI 很常見:某個共用的 base image 或 .gitlab-ci.yml 全域設了 HUGO_BUILDDRAFTS=false 當預設,個別 job 想臨時建草稿預覽就加 --buildDrafts,結果在 v0.169.0 完全沒用。v0.170.0 修正後,旗標真的能覆蓋掉繼承來的環境變數。

HUGO_BUILDDRAFTS=false 搭配 --buildDrafts 旗標:v0.169.0 建出 0 篇草稿(環境變數勝出),v0.170.0 建出 1 篇(旗標勝出)
圖 3:草稿建置測試中旗標與環境變數衝突時的勝出方,v0.169.0 對 v0.170.0(來源:本機實測)
升級前檢查這兩件事
  • CI 腳本若同時用環境變數設定一個基礎值、又用指令列旗標做個別覆寫(常見於共用 base image + per-job override),升級後行為會反過來,建議先在測試分支跑一次完整建置
  • 設定檔或 Makefile 裡若還寫著 css.Sass transpiler: libsass,升級後建置會直接失敗,需要先確認已裝 Dart Sass 並改掉 transpiler 設定

四、影響分析:誰會被這次升級動到

純粹用 Markdown + 內建樣式處理、沒碰過 Sass 的站台,升級幾乎無感。regular binary 從以前到現在都是同一顆,這次只是把「extended 這個選項」拿掉,不影響沒用到它的人。

真正會被打到的兩群人:一群是還在用 transpiler: libsass 的舊設定檔,升級後建置直接紅字失敗;另一群是 CI 腳本同時依賴環境變數和旗標的,行為會悄悄改變而不一定馬上報錯,風險反而更隱蔽,建置可能照樣綠燈通過,只是產出的環境標籤或草稿數量跟預期不同。

對維運影響最大的其實是第三類:那些寫死 hugo_extended_*_linux-amd64.tar.gz 下載連結的安裝腳本。這些腳本不會失敗,因為檔名還在、下載照樣成功,直到真正呼叫 css.Sass 才爆炸,錯誤出現的位置離「版本升級」這個根因很遠,排查起來容易繞遠路。

  1. 先確認專案有沒有用到 transpiler: libsass(grep -r "libsass" config* layouts/)
  2. 有用到 → 安裝 Dart Sass,把設定改成 transpiler: dartsass
  3. 檢查 CI 腳本是否寫死 hugo_extended_ 開頭的下載檔名,確認下游邏輯沒有依賴「extended = 有 libsass」這個假設
  4. 若 CI 中環境變數與旗標同時存在,重新跑一次確認行為符合預期

GitHub Actions 產生器

選語言、測試、快取、Docker 多架構建置與推送,產出 workflow YAML

載入工具中…

五、對比與取捨:跟其他靜態網站產生器比起來

特性 Hugo 0.170.0 Eleventy Zola
核心語言 Go JavaScript Rust
Sass/SCSS 支援 需外部 Dart Sass(CLI 或 npm 套件) 依賴外部 build pipeline 內建(也是 Rust 原生實作,無 extended 問題)
單一 binary 分發 ✅(v0.170.0 起唯一選項) ❌(需 Node.js 環境) ✅
建置速度(官方宣稱定位) 快,大型站台常見選擇 中等,依外掛數量 快

Zola 從設計之初就沒有「extended/regular」這種分裂,因為它的 Sass 支援是 Rust 原生實作、靜態連結本來就是常態。Hugo 這次等於是往同一個方向靠攏,只是過程中會讓一部分舊使用者踩到設定檔相容性的坑。這不代表 Hugo 設計有問題,CGO 可選擇性編譯原本就是給需要額外原生函式庫的場景用的,只是維護兩套發行版的成本,到了這個階段被認為不划算。

限制也要講清楚:這次測試只涵蓋 linux-amd64 官方二進位,沒有測 Homebrew、Scoop、Snap 等套件管理通路打包的版本是否仍保留某種 extended 變體;也沒有測 Windows、macOS 平台的行為(release note 內容應該一致,但沒有逐一驗證)。

六、實務建議

升級到 v0.170.0 前檢查清單
  • 搜尋專案內 transpiler: libsass,確認是否需要改用 dartsass
  • 確認本機或 CI 容器已安裝 Dart Sass(npm install -g sass 或對應套件管理工具)
  • 檢查安裝腳本是否寫死 hugo_extended_* 檔名,若有,改抓 regular 版(功能已相同)
  • 重新檢視 CI 中環境變數與旗標同時使用的地方,確認升級後行為符合預期
  • 在測試分支跑一次完整建置,確認 hugo.Environment 與草稿數量符合預期

適合現在就升的情境:純 Markdown 建站、已經改用 Dart Sass、CI 腳本單純只用其中一種設定方式(環境變數或旗標擇一)的站台,升級幾乎零風險,還能拿到 static 檔同步加速與 WASM image codec 修正等改進。

不建議馬上升的情境:還在維護老舊設定檔、短期沒空處理 Sass 遷移的站台,可以先鎖定 v0.169.0,排個時間處理完 libsass 遷移再升,反正 libsass 從 v0.153.0 就已經是 deprecated,遲早要面對。

七、結論

extended 版拔掉不是一次單純的瘦身,而是把一個「看起來還在、實際已經不同」的相容性陷阱留在下載頁上。靜態連結、動態連結這種底層差異平常不會有人去查,直到建置在 css.Sass 那步炸掉才回頭看版本。

值不值得升?純 Markdown 站台可以直接升,幾乎無感;用 Sass 的站台要先把 transpiler 改成 dartsass 再升,順便檢查 CI 腳本有沒有依賴環境變數和旗標同時生效的舊行為。後續觀察重點:官方是否會在未來某個版本把 hugo_extended_* 這個相容別名徹底拿掉,以及 Dart Sass 的建置速度是否會成為大型站台的新瓶頸。

還能抓到真的 CGO 編譯、支援 libsass 的 Hugo 嗎?

官方發行版不行,v0.170.0 起沒有任何官方二進位支援 libsass。要用 libsass 只能自行用舊版原始碼搭配 CGO 工具鏈編譯,但官方已不建議這條路。

不用 Sass 的站台需要改設定嗎?

不需要,純 Markdown 或只用內建樣式處理的站台升級後行為不變。

CI 腳本寫死抓 hugo_extended_* 檔名會怎樣?

下載不會失敗,檔名還在,但裡面已經是跟 regular 版相同的二進位,不支援 libsass;建議改抓不帶 extended 字樣的一般檔名。

旗標覆蓋環境變數的修正會影響所有旗標嗎?

release note 只點名 -e(environment)與 HUGO_ENVIRONMENT 這組互動,本次實測額外驗證了 --buildDrafts 與 HUGO_BUILDDRAFTS 也遵循同一套「旗標優先」邏輯,其餘旗標未逐一測試。

參考資料

分享這篇
X LinkedIn Facebook Hacker News Reddit

這篇對你有幫助嗎?

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料。