Hugo 静态网站构建实战手册

Hugo Modules

使用 Hugo Modules 管理主题、组件、内容挂载和大型站点依赖

Hugo Modules

Hugo Modules 是 Hugo 基于 Go Modules 构建的依赖管理系统。它可以用来引入主题、共享组件、复用内容、挂载目录,也能让大型站点从“一个仓库堆所有东西”变成可组合的结构。

小型个人博客可以继续使用 Git submodule;如果项目依赖多个主题组件、公共短代码、共享内容或多站点复用,Hugo Modules 会更合适。

使用前准备

需要安装:

hugo version
go version
git --version

Hugo Modules 依赖 Go Modules,因此本机或 CI 环境需要 Go。

初始化模块

在站点根目录执行:

hugo mod init github.com/yourname/my-blog

这会创建:

go.mod

示例:

module github.com/yourname/my-blog

go 1.22

模块路径一般使用仓库地址,方便远程解析。

引入主题

方式一:使用 theme

theme = 'github.com/theNewDynamic/gohugo-theme-ananke'

方式二:使用 module.imports

[[module.imports]]
  path = 'github.com/theNewDynamic/gohugo-theme-ananke'

执行:

hugo mod get github.com/theNewDynamic/gohugo-theme-ananke
hugo server -D

更新依赖:

hugo mod get -u
hugo mod tidy

go.mod 与 go.sum

启用 Hugo Modules 后,项目通常会出现:

go.mod
go.sum

建议提交到 Git。它们用于固定依赖版本,保证本地和 CI 构建一致。

查看模块信息

hugo mod graph
hugo mod npm pack
hugo env

常用:

  • hugo mod graph 查看依赖关系
  • hugo mod tidy 清理未使用依赖
  • hugo mod clean 清理模块缓存
  • hugo env 查看模块配置和缓存路径

模块挂载 Mounts

Mounts 是 Hugo Modules 最实用的能力之一:把某个目录挂载到 Hugo 识别的目录中。

示例:把外部模块的 assets 挂载到站点 assets/vendor

[[module.imports]]
  path = 'github.com/example/hugo-ui-kit'

  [[module.imports.mounts]]
    source = 'assets'
    target = 'assets/vendor/ui-kit'

这样模板里可以:

{{ resources.Get "vendor/ui-kit/css/buttons.css" }}

本地目录挂载

不只是远程模块,本地目录也可以挂载。

[[module.mounts]]
  source = 'content'
  target = 'content'

[[module.mounts]]
  source = '../shared-docs'
  target = 'content/docs/shared'

适合:

  • 多个站点共享文档
  • 博客和产品官网共用页面
  • 把大内容库拆到独立仓库

注意:一旦自定义 mounts,需要显式声明默认挂载,否则默认目录可能不再自动生效。

常见完整写法:

[[module.mounts]]
  source = 'archetypes'
  target = 'archetypes'

[[module.mounts]]
  source = 'assets'
  target = 'assets'

[[module.mounts]]
  source = 'content'
  target = 'content'

[[module.mounts]]
  source = 'data'
  target = 'data'

[[module.mounts]]
  source = 'i18n'
  target = 'i18n'

[[module.mounts]]
  source = 'layouts'
  target = 'layouts'

[[module.mounts]]
  source = 'static'
  target = 'static'

模块优先级

Hugo 合并多个模块时,越靠前的导入优先级越高。站点自身仍然优先于导入模块。

[[module.imports]]
  path = 'github.com/example/hugo-theme-main'

[[module.imports]]
  path = 'github.com/example/hugo-shortcodes'

如果两个模块都提供同一路径模板,前面的模块优先。

版本固定

获取指定版本:

hugo mod get github.com/example/hugo-theme@v1.2.3

获取指定分支:

hugo mod get github.com/example/hugo-theme@main

建议生产项目使用 tag 版本,不要长期依赖浮动分支。

替换为本地开发版本

开发主题时,可以在 go.mod 中使用 replace:

replace github.com/example/hugo-theme => ../hugo-theme

这样站点引用远程模块路径,但实际使用本地目录,方便主题联调。

调试完成后记得删除或注释 replace,避免 CI 找不到本地路径。

模块代理与私有仓库

如果模块在私有仓库,需要配置 Git 认证。常见方式:

  • SSH key
  • GitHub token
  • CI 平台部署密钥

如果遇到 Go proxy 缓存或私有模块问题,可以设置:

GOPRIVATE=github.com/your-org/*

Windows PowerShell:

$env:GOPRIVATE = "github.com/your-org/*"

什么时候不用 Modules

以下情况 Git submodule 更简单:

  • 只有一个主题
  • 不需要共享内容
  • 不熟悉 Go Modules
  • 部署平台不方便安装 Go

submodule 虽然传统,但对个人博客仍然够用。

什么时候建议用 Modules

以下情况建议使用 Hugo Modules:

  • 一个站点使用多个主题组件
  • 多个站点共享 layoutsassetsshortcodes
  • 需要从外部仓库挂载内容
  • 希望使用版本化依赖管理
  • 主题本身已经要求用 Hugo Modules

常见项目结构

my-blog/
├── config/
│   └── _default/
│       └── hugo.toml
├── content/
├── layouts/
├── assets/
├── go.mod
└── go.sum

配置:

[[module.imports]]
  path = 'github.com/example/hugo-theme'

[[module.imports]]
  path = 'github.com/example/hugo-components'

常见问题

Q: hugo mod init 报错

A: 检查是否安装 Go,并确认当前目录是 Hugo 项目根目录。

Q: 线上构建找不到模块

A: 检查 CI 是否安装 Go,是否能访问 GitHub,私有仓库是否配置认证。

Q: 修改主题后没有生效

A: 如果使用的是远程模块,修改 themes/ 目录当然不会生效。需要用 replace 指向本地主题,或在站点 layouts/ 中覆盖。

Q: 自定义 mounts 后内容消失

A: 自定义 mounts 会改变默认挂载行为。把 contentlayoutsassets 等默认目录显式挂载回来。

下一步

继续阅读 SEO 与性能优化,让站点更容易被搜索引擎理解,也更快加载。

评论

0%