故障排除
本章汇总了 Hugo 使用过程中常见的问题和解决方案。
常见错误
功能不可用错误
错误信息:this feature is not available in this edition of Hugo
原因:Hugo 有三个版本,不同版本支持的功能不同:
| 功能 | 标准版 | 扩展版 | 扩展/部署版 |
|---|---|---|---|
| WebP 图片编码 | ❌ | ✔️ | ✔️ |
| Sass/SCSS 转 CSS(内置 LibSass) | ❌ | ✔️ | ✔️ |
| 部署到云存储(S3、GCS、Azure) | ❌ | ❌ | ✔️ |
解决方案:根据需要安装对应版本。大多数用户应该安装扩展版:
# Windows (Chocolatey)
choco install hugo-extended
# Windows (Scoop)
scoop install hugo-extended
# macOS
brew install hugo
# Linux (Snap)
sudo snap install hugo
首页显示 404
原因:首页内容未发布,可能是以下情况:
content/_index.md中draft = truedate设置在未来publishDate设置在未来expiryDate设置在过去
解决方案:
修改 Front Matter,或使用命令行标志:
# 构建草稿
hugo --buildDrafts
# 构建未来日期内容
hugo --buildFuture
# 构建过期内容
hugo --buildExpired
页面未发布
原因:与首页 404 类似,检查页面的 Front Matter:
draft是否为truedate是否在未来publishDate是否在未来expiryDate是否在过去
解决方案:
# 检查所有草稿
hugo list drafts
# 检查未来内容
hugo list future
# 检查过期内容
hugo list expired
子页面不显示
原因:可能使用了 index.md 而不是 _index.md。
区别:
| 文件名 | 类型 | 说明 |
|---|---|---|
index.md | 叶子包(Leaf Bundle) | 单独的页面,有自己的 URL |
_index.md | 分支包(Branch Bundle) | 列表页面,包含子页面 |
示例:
content/posts/
├── _index.md # 博客列表页(分支包)
├── first-post.md # 单篇文章
└── my-series/
├── index.md # 系列介绍页(叶子包)
├── part-1.md
└── part-2.md
Partial 模板渲染异常
原因:调用 partial 时忘记传递上下文。
错误示例:
{{ partial "pagination.html" }}
正确示例:
{{ partial "pagination.html" . }}
第二个参数 . 是当前上下文,partial 模板内部通过 . 访问。
变量赋值困惑
问题::= 和 = 有什么区别?
解答:
:=初始化变量=为已存在的变量赋值
{{/* 初始化 */}}
{{ $title := .Title }}
{{/* 赋值 */}}
{{ $title = .Site.Title }}
{{/* 错误:变量未初始化 */}}
{{ $name = "test" }} <!-- 报错 -->
{{/* 错误:变量重复初始化 */}}
{{ $x := 1 }}
{{ $x := 2 }} <!-- 报错 -->
分页过滤失效
问题:使用 where 过滤后分页,结果不符合预期。
原因:同一个页面多次调用 Paginate 或 Paginator 方法。
错误示例:
{{ $paginator := .Paginate (where .Pages "Type" "posts") }}
<!-- 其他地方又调用了一次 -->
{{ $paginator2 := .Paginate .Pages }}
正确做法:
每个页面只调用一次 Paginate,将结果存储到变量中复用:
{{ $pages := where .Site.RegularPages "Type" "posts" }}
{{ $paginator := .Paginate $pages }}
{{ range $paginator.Pages }}
<!-- 内容 -->
{{ end }}
短代码语法选择
问题:什么时候用 {{< >}},什么时候用 {{% %}}?
解答:
{{< shortcode >}}:内容不渲染 Markdown{{% shortcode %}}:内容渲染 Markdown
使用 {{< >}} 的场景:
<!-- 代码块不需要 Markdown 渲染 -->
{{< highlight python >}}
def hello():
print("Hello") # **这不会被渲染为粗体**
{{< /highlight >}}
使用 {{% %}} 的场景:
<!-- 内容包含 Markdown -->
{{% note %}}
这是 **粗体** 和 *斜体*,需要被渲染
{{% /note %}}
构建结果不一致
问题:每次构建输出不同。
可能原因:
- 页面冲突:两个页面发布到同一路径
- 并发问题:模板存在竞态条件
排查方法:
# 检查页面路径冲突
hugo --printPathWarnings
文件变更未检测
问题:hugo server 没有检测到文件变化。
常见场景:
- WSL 中运行 Hugo,项目文件在 Windows 分区
- 项目文件在可移动驱动器上
- 项目文件在 NFS/SMB/CIFS 网络存储上
解决方案:
使用 --poll 参数轮询文件变化:
hugo server --poll 700ms
Store 值丢失
问题:在父模板中无法获取 .Store 设置的值。
原因:.Store 的值在页面内容渲染时才确定。如果在渲染前访问,值为空。
解决方案:
触发内容渲染:
{{ $noop := .Content }}
{{ .Store.Get "mykey" }}
触发内容渲染的方法:
| 方法 | 说明 |
|---|---|
.Content | 完整内容 |
.ContentWithoutSummary | 不含摘要的内容 |
.Summary | 摘要 |
.Plain | 纯文本 |
.PlainWords | 纯文本单词 |
.WordCount | 字数 |
.FuzzyWordCount | 模糊字数 |
.ReadingTime | 阅读时间 |
.Len | 内容长度 |
.Truncated | 是否截断 |
模板调试
打印变量内容
使用 debug.Dump 函数:
<pre>{{ debug.Dump .Params }}</pre>
<pre>{{ debug.Dump .Site }}</pre>
检查模板是否存在
{{ if templates.Exists "partials/header.html" }}
<!-- 模板存在 -->
{{ end }}
性能分析
启用模板性能指标:
templateMetrics = true
templateMetricsHints = true
运行 hugo 后,会输出每个模板的执行时间和内存使用情况。
查找未使用的模板
printUnusedTemplates = true
常见警告
翻译缺失警告
警告信息:i18n|MISSING_TRANSLATION
解决方案:
- 确保翻译文件存在:
i18n/zh-cn.toml - 检查翻译键是否正确
- 或启用配置显示占位符:
enableMissingTranslationPlaceholders = true
路径冲突警告
警告信息:多个页面输出到同一路径
排查:
hugo --printPathWarnings
检查输出,找出冲突的页面。
隐藏警告
对于已知的非关键警告,可以隐藏:
ignoreLogs = ['warning-id-1', 'warning-id-2']
使用 warnidf 和 erroridf 函数可以创建可抑制的警告和错误。
构建问题
内存不足
症状:构建时崩溃或变慢
解决方案:
# 清理未使用资源
hugo --gc
# 减少并发(如果内存有限)
HUGO_NUMWORKERMULTIPLIER=1 hugo
构建超时
错误信息:timeout during render
原因:页面渲染耗时过长,可能是复杂的图片处理或远程数据获取。
解决方案:
# 增加超时时间
timeout = '120s'
内容循环依赖
症状:构建卡住不动
原因:内容或模板存在循环引用
排查:
- 检查
.GetPage是否引用自身 - 检查相关内容查询是否造成无限循环
- 使用
hugo --templateMetrics找出问题模板
开发环境问题
热重载不工作
检查项:
- 是否在项目根目录运行
hugo server - 文件是否在正确的
content/、layouts/等目录 - 是否有语法错误导致构建失败
解决方案:
# 强制完全重建
hugo server --disableFastRender
浏览器缓存
症状:修改后浏览器显示旧内容
解决方案:
- 强制刷新:
Ctrl + Shift + R(Windows)或Cmd + Shift + R(macOS) - 清除浏览器缓存
- 使用无痕模式测试
端口被占用
错误信息:bind: address already in use
解决方案:
# 使用其他端口
hugo server --port 1314
# 或找到占用进程并关闭
部署问题
CSS/JS 不加载
原因:baseURL 配置错误
解决方案:
确保 hugo.toml 中的 baseURL 正确:
baseURL = 'https://example.org/' # 注意末尾斜杠
子目录部署问题
场景:部署到 https://example.com/blog/
配置:
baseURL = 'https://example.com/blog/'
相对 URL:在模板中使用 relURL 或 RelPermalink:
<link rel="stylesheet" href="{{ "css/style.css" | relURL }}">
<a href="{{ .RelPermalink }}">{{ .Title }}</a>
资源 404
原因:资源文件位置错误
检查:
- 静态文件放在
static/目录 - 需要处理的资源放在
assets/目录 - 页面资源放在页面目录中
区分:
static/
├── images/logo.png → /images/logo.png
assets/
├── css/main.css → 需要通过 resources.Get 获取
content/posts/my-post/
├── index.md
└── cover.jpg → 页面资源,通过 .Resources.Get 获取
查找帮助
Hugo 论坛
Hugo 论坛 是最活跃的 Hugo 社区,有超过 20,000 个话题。提问前请:
- 搜索是否有类似问题
- 提供完整的错误信息
- 提供最小可复现示例
- 说明 Hugo 版本和操作系统
提供版本信息
提问时提供以下信息:
# 获取版本信息
hugo version
hugo env
# 输出示例
hugo v0.121.1+extended windows/amd64 BuildDate=2024-01-01
GOOS="windows"
GOARCH="amd64"
最小可复现示例
创建一个最小示例帮助他人理解问题:
- 创建新的空站点:
hugo new site test - 添加必要的配置和模板
- 描述问题步骤
- 提供完整的错误信息
小结
本章介绍了 Hugo 常见问题的解决方法:
- 功能不可用:选择正确的 Hugo 版本
- 页面不显示:检查 draft、date 等字段
- 模板问题:注意上下文传递和变量赋值
- 调试技巧:使用 debug.Dump 和性能分析
- 部署问题:确认 baseURL 和资源位置
遇到问题时,优先搜索 Hugo 论坛,大部分问题都有解决方案。