如何使用 hugo responsive images 模組
Published:Updated:
#2523 提到了圖片自動轉檔,自用隨便改是很簡單沒錯,但是維護了一段時間之後現在看到任何 feature request 都覺得怕,一個 feature 後面可是會接著一堆向前兼容、無數的程式碼除錯、用戶抱怨和無止盡的 enhancement request 的,所以 survey 了一下發現確實有人做了圖片轉檔 module,這樣就不用自己寫了。
hugo-responsive-images 是一個已經迭代三年的 Hugo 圖片自動轉檔工具,看起來幾乎是把所有 Hugo 的影像功能幾乎都用上了,我在 Hugo 文檔看感覺都沒那麼多東西,不過這篇文章的目的不是要稱讚他,因為 hugo-responsive-images 的文檔有寫但不多,具體怎麼用需要靠直覺猜,本文的目的就是簡單記錄如何使用。
安裝
hugo-responsive-images 一定只能使用 Hugo moduless 方式安裝,包含你原本使用的主題也要改用 Hugo moduless 方式安裝,這裡我以 Blowfish 主題為例示範全新安裝的步驟。
步驟
- 請先準備好必要依賴 Hugo + Go
- hugo new site
test_site - cd
test_site - rm
hugo.toml - 到 Blowfish release 頁面 下載 config-default.zip
- 解壓縮到專案根目錄
- 把
config/_default/hugo.toml轉為 yaml,網路上有轉換工具 - 在
config/_default/module.toml貼上主題設定:
# 越上面的優先級越高,不可調整順序
[[imports]]
path = "github.com/future-wd/hugo-responsive-images"
[[imports]]
disable = false
path = "github.com/nunocoracao/blowfish/v2"
- 在
config/_default/hugo.yaml貼上測試用的圖片轉檔設定,之後可以自行調整:
params:
image:
widths: [500, 1000, 1500]
# sizes: "(min-width: 648px) 500px, (min-width: 853px) 1000px, (min-width: 1280px) 1500px, 100vw" # 不知道為何此選項放在 hugo.yaml 沒生效但是放在 front matter 成功運作
formats: [original, webp]
loading: lazy
render_hook: true
- 建立你的 markdown 檔案和圖片,這樣就可以直接使用 markdown 語法載入圖片了。
說明
為何安裝要搞的這麼多步驟?主要是因為 hugo-responsive-images 裡面又引用了其他東西,所以即使使用雙主題方式也無法達成,一定要使用 Hugo modules 才能安裝。
要轉成 yaml 的原因是 Hugo 以 toml 讀取 widths: [500, 1000] 的 toml 版本時把他轉成字串了,我懶的處理這個問題直接把設定檔轉 yaml 比較快。
報錯內容
Invalid config "width in widths slice" value of "600" for picture render-hook image /posts/hello/image-resizing.png on page /posts/hello/. Must be an integer. <-- 被辨識成字串而不是數字
渲染結果
以一張 2400x1350 的 PNG 圖片為例為例,原始大小 99KB,經過 hugo-responsive-images 轉換後的 HTML 如下:
<div class="img-wrapper">
<picture>
<source srcset="/posts/hello/large_hu_9d74e36041e5a93f.webp 500w, /posts/hello/large_hu_edcc46622b3b3d24.webp 1000w, /posts/hello/large_hu_3b1003b726f1704e.webp 1500w" type="image/webp">
<source srcset="/posts/hello/large_hu_a33b4e0c6b6a50ec.jpg 500w, /posts/hello/large_hu_296e5a7b9e6fbb9d.jpg 1000w, /posts/hello/large_hu_92c170a616c8a6e8.jpg 1500w" type="image/jpeg">
<img loading="lazy" src="/posts/hello/large_hu_92c170a616c8a6e8.jpg" height="844" width="1500" class="img-fluid medium-zoom-image" sizes="(min-width: 648px) 500px, (min-width: 853px) 1000px, (min-width: 1280px) 1500px, 100vw" alt="test">
</picture>
</div>
可以看到兩個 source 分別是 webp 和 png 版本,瀏覽器會由上往下找看你的裝置支援哪種就套用,也就是說會先看裝置是否支援 webp,如果不行的話就 fallback 成 png 格式。source 標籤中的 srcset 代表根據你的裝置(不只是參考解析度)選擇載入最適合的圖片,sizes 設定很複雜,請看文檔說明,這裡不多做介紹。
- Using responsive images in HTML:入門教學
- <img>: The Image Embed element:整個 img 標籤的文檔,裡面有說明 sizes / srcset / loading 三個參數的交互
- HTMLImageElement: srcset property :srcset 屬性的文檔
- HTMLImageElement: sizes property:sizes 屬性的文檔