Skip to main content

Hugo CLI (hugo mod)

Hugo 連 CLI 都講的不清不楚,我真心覺得要寫一篇文章介紹 CLI 很蠢,但還真的有必要。

hugo mod 就是用 go module 輔助管理專案,主要目的是讓專案管理能更現代而不是使用 git submodule。

對於一般人來說,hugo mod 裡面幾乎所有子命令的旗標都毫無意義,比如說我想不到你到底什麼時候會在 hugo mod clean 裡面傳 --contentDir,這些命令唯一有用的地方就是在複雜的專案中可能目錄會 mount 來 mount 去不在預設位置,這些旗標的意義就是讓專案結構解析成功,沒有第二個目的。

比如說直接貼整個 hugo mod clean 的 options:

Options
--all clean entire module cache
-b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/
--cacheDir string filesystem path to cache directory
-c, --contentDir string filesystem path to content directory
-h, --help help for clean
--pattern string pattern matching module paths to clean (all if not set), e.g. "**hugo*"
--renderSegments strings named segments to render (configured in the segments config)
-t, --theme strings themes to use (located in /themes/THEMENAME/)
Options inherited from parent commands
--clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
--config string config file (default is hugo.yaml|json|toml)
--configDir string config dir (default "config")
-d, --destination string filesystem path to write files to
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--noBuildLock don't create .hugo_build.lock file
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory

你可以看到基本上所有東西對一般人來說都沒用,但是這份文字卻在所有子命令都重複出現,讀者哪會知道這該不該看,結果是看了卻完全沒用,真的會用到的只有 --ignoreVendorPaths 避免 vendor 出來的東西影響結果,其餘參數對讀者來說都是雜訊。

唸完了,來解釋 hugo mod 指令:

  • hugo mod init 建立一個 go module,也就是把你的網站變成 go module 並且能安裝其他 go modules,一個網站只會用一次。只接受唯一一個位置參數,文檔卻完全沒講這件事。其他所有旗標對這個指令都沒用,除非你的專案結構非預設結構。
  • hugo mod graph 列出依賴,等同 npm 的 npm ls --all。其他所有旗標對這個指令都沒用,除非你的專案結構非預設結構。
  • hugo mod verify 驗證依賴。其他所有旗標對這個指令都沒用,除非你的專案結構非預設結構。
  • hugo mod clean 清理依賴的本地快取。--pattern 在這個指令上終於有用。
  • hugo mod npm pack 如果你不會用到他,那你也沒必要看他。
  • hugo mod vendor 把依賴複製(vendor)到 _vendors 目錄,讓你可以自行管理專案源碼,可以做到避免網路問題,確保構建結果一置等等功能。然而這只是一個網站專案,真正有用的其實是「暫時 vendor 出來,直接修改 _vendor 的源碼除錯或是優化」,等同於 git submodule 安裝主題時也可以臨時到 themes 目錄修改源碼。其他所有旗標對這個指令都沒用,除非你的專案結構非預設結構。

對於一般用戶這六個指令你只需要知道 hugo mod init,而且還只會用到一次,其他基本上永遠不會用到,你真正會用到的是

  • hugo mod tidy 根據 hugo.tomlmodule.imports 改寫 go.mod/go.sum 清理無用的項目,需要這個指令的原因是 go modules 和 npm/Python 不一樣,lockfile 不會自動清理,所以才多了一個清理的指令。
  • hugo mod get 下載、更新依賴,這是這些指令裡面「唯一一個直接把旗標直接傳給 go mod 的指令」。
  • 移除依賴:沒有這種指令,要到 modules.imports 移除依賴後手動執行 hugo mod tidy
繼續嘲諷文檔

你說這有很複雜嗎?沒有。你說這難懂嗎?也沒有,但是煩在這篇文章的內容在 Hugo 文檔裡面被拆到 10 個頁面,閱讀時跳來跳去你就把自己跳沒了,你別忘了這篇文章介紹了所有 hugo mod 指令,閱讀時間才差不多兩分鐘,你拆成 10 頁之後有可能在兩分鐘內讀完嗎?顯然不可能。然後有發現我不斷重複「其他所有旗標對這個指令都沒用,除非你的專案結構非預設結構」嗎?這 10 篇文章你點進去看,讀了結果內容又有一半在介紹旗標完全沒用,問題是誰會預設文檔寫的內容不該看,結果就是所有人都讀了沒用的內容,真的是天才編排,論技術文檔還是得看 Hugo 的獨家表演。

從 Docusaurus/uv/react/MkDocs,到老掉牙 Sphinx,到數十億人使用的 ffmpeg 的 CLI 全都是單頁文檔,就 Hugo 最聰明想到可以把 CLI 文檔拆成十幾個頁面,別人都沒想到,就 Hugo 一個人想到這種高招的編排,全世界的 UI/UX 設計沒有 Hugo 高招...你沒想過大家都這樣用是有原因的嗎?還是眾人皆醉我獨醒?

這樣講讀者可能還想說筆者太噴子了吧,有拆分的也很多阿,這又不是什麼絕對的事情,那你看看這些指令是被拆成五個不同頁面,每個頁面都各自列出毫無意義的 flags 就知道這種設計有多蠢:

這到底有啥好拆成五頁的?更蠢的是 hugo completion + hugo mod 加起來就 15/44 個總指令了,你在找清單的時候有 1/3 時間在過濾無用資訊,點進去之後提供的 flags 一樣沒用(但你還是得看,你不看怎麼知道有沒有用?終於看完之後又發現幾乎全部沒用)。清單外觀設計還是 grid 平面卡片,不是垂直文字列表,更難找,這到底是什麼設計。