快轉到主要內容

Hugo Modules

查看原始碼編輯此頁 (外部連結)

本文專門介紹 Hugo Modules 以及對應的 hugo mod 指令。

什麼是 Module 此標題的連結

Module 是 Hugo 組織內容的基本單位。一個 module 可以是完整的 Hugo 專案,比如安裝的主題,也可以只是提供某一種元件(content、layouts、assets、data、i18n、static、archetypes)的小型可重用套件。

Module 可以任意組合、巢狀引用,也可以掛載外部目錄,甚至是非 Hugo 專案的目錄,最後全部都併入同一個 UFS。

初始化與引用 此標題的連結

專案本身要先變成一個 module 才能引用其他 module:

hugo mod init github.com/user/theme

這會產生 go.mod。如果你不打算讓其他人導入你的模組,那麼具體的名稱並不重要,取個合理的名稱即可。

在 hugo.yaml 宣告要引用的 module:

module:
  imports:
    - path: github.com/user/theme

執行 hugo 構建時,會自動下載 module、寫入快取,並產生 go.sum 記錄版本與校驗碼。

同時引用多個 module 時,同名檔案的合併規則按照 UFS 規則合併。

常用指令 此標題的連結

以下整理常用的 hugo mod 指令:

  • 更新單一 module:

    hugo mod get -u github.com/user/theme
  • 指定版本:

    hugo mod get -u github.com/user/theme@v0.42.0
  • 更新全部 module:

    hugo mod get -u
  • 遞迴更新 module:

    hugo mod get -u ./...
  • 清理 go.mod/go.sum 中未使用的項目:

    hugo mod tidy
  • 清除 module 快取:

    hugo mod clean

Vendor 此標題的連結

hugo mod vendor 用於本地檢視與臨時修改除錯。

此指令會將所有引用的 module 複製到優先權更高的 _vendor 目錄,可以直接在 _vendor 目錄中對 module 修改測試。直接修改 _vendor 內的檔案僅用於快速除錯,再次 vendor 就會被覆蓋,正式的客製化方式仍然是透過 UFS 在專案根目錄用相同路徑覆蓋。

Replace 此標題的連結

Replace 功能用於永久替換依賴,比如改為自己的 fork:

go.mod
require example.com/othermodule v0.1.0

replace example.com/othermodule => example.com/myfork/othermodule v0.1.0

或是指向本地目錄:

go.mod
replace github.com/user/theme => /home/user/projects/theme

replace 寫在 go.mod 裡並隨專案一起發布,因此對所有建置這個專案的人都會生效,包含 CI。

Workspace 此標題的連結

Workspace 用於設定本地開發時的 module 配置,可以將他理解為暫時版的 replace 功能。舉例來說,開發本地 module 時直接套用本機檔案:

exampleSite/hugo.work
go 1.20

use .
use ../theme

以環境變數暫時啟用:

HUGO_MODULE_WORKSPACE=hugo.work hugo server -s exampleSite

或是在 hugo.yaml 設定長期啟用 workspace 模式:

exampleSite/hugo.yaml
workspace: 'hugo.work'

Workspace 和 replace 最大的差異是允許暫時啟用且不會寫進 go.mod,當模組被外部依賴,不會有 replace 設定影響外部用戶的問題。

實際應用範例 此標題的連結

多語言網站 此標題的連結

如同多語言網站說的一樣,可以將指定目錄 mount 到指定位置的指定 site 上,以完成多語言設定。

共用元件庫 此標題的連結

多個網站共用同一組 shortcode、partial 或 CSS,抽成獨立 module 讓所有網站引用:

module:
  imports:
    - path: github.com/your-org/shared-components

exampleSite 此標題的連結

開發主題時常見的做法是在主題 repo 裡放一個 exampleSite/ 目錄,作為主題的範例網站使用,但 exampleSite/ 這個網站依賴的主題是專案根目錄的主題本身。

Workspace 可以輕鬆解決這個問題,設定方式為

exampleSite/hugo.work
go 1.20

use .
use ../
exampleSite/hugo.yaml
workspace = 'hugo.work'

node_modules 此標題的連結

Mounts 功能也可用於 node_modules,讓你直接將 node_modules 內容 mount 到指定目錄,不需手動 vendor 套件。設定方式為:

module:
  mounts:
    - source: assets
      target: assets
    - source: node_modules/foo/
      target: assets/foo

在模板中就能使用該目錄的內容。

內容與源碼分離 此標題的連結

把 content/ assets/ 獨立成一個 module(獨立的 git repo),讓寫手完全不需要碰觸主題原始碼:

module:
  imports:
    - path: github.com/your-org/site-content

寫手只需要對 site-content 這個獨立 repo 有存取權限,不會誤動到 layouts 等程式碼部分。工程師只需要設定 CI 構建時下載這個 module 即可簡單達成權責分離。

本地開發需要即時看到內容變更效果時,可以搭配前面提到的 workspace 方式掛載。

多環境設定分離 此標題的連結

把正式站與預覽站需要的不同 data/ 或 params 依環境切換引用:

config/staging/hugo.yaml
module:
  imports:
    - path: config-staging
config/production/hugo.yaml
module:
  imports:
    - path: config-production

其中 config/staging 和 config/production 目錄會根據 environment variable 自動切換 (外部連結),或是以 hugo -e staging 手動指定,也可搭配 CI/CD 依部署環境切換要引用的設定 module。

無障礙設定

字體大小