构建选项
介绍页面级 build 选项、无头包、cascade 与站点级构建配置。
页面级构建选项
构建选项存放在前置元数据(front matter)中一个名为 build 的保留对象里(早期版本写作 _build),它的默认值如下:
+++
title = "示例页面"
[build]
list = 'always'
publishResources = true
render = 'always'
+++list 决定页面在何时进入页面集合:
always:进入所有页面集合,例如site.RegularPages、.Pages等。这是默认值。local:只进入本地页面集合,例如.RegularPages、.Pages等。用它可以做出「可正常导航、但不对外列出」的内容区块。never:不进入任何页面集合。
publishResources 只对页面包(page bundle)有效,决定是否发布它关联的页面资源(page resource):
true:总是发布资源。这是默认值。false:只有在模板中调用了资源的Permalink、RelPermalink或Publish方法时,才发布该资源。
render 决定页面在何时渲染:
always:总是把页面渲染到磁盘。这是默认值。link:不渲染到磁盘,但仍为页面分配Permalink与RelPermalink值。never:不渲染到磁盘,并把页面排除在所有页面集合之外。
注意取值的类型:list 与 render 取字符串,publishResources 取布尔值。另外,无论构建选项如何设置,页面都可以通过 .Page.GetPage 或 .Site.GetPage 方法获取。
无头页面(headless page)
无头页面是不发布的页面,它的内容与资源可以被其他页面引用:
content/
├── headless/
│ ├── a.jpg
│ ├── b.jpg
│ └── index.md <-- 叶子包
└── _index.md <-- 首页在前置元数据中设置构建选项:
+++
title = '无头页面'
[build]
list = 'never'
publishResources = false
render = 'never'
+++在首页中包含它的内容与图片:
{{ with .Site.GetPage "/headless" }}
{{ .Content }}
{{ range .Resources.ByType "image" }}
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ end }}
{{ end }}发布后的站点结构如下:
public/
├── headless/
│ ├── a.jpg
│ └── b.jpg
└── index.html注意两点:Hugo 没有为该页面发布 HTML 文件;尽管前置元数据里 publishResources 是 false,Hugo 仍然发布了这些页面资源,因为模板在每个资源上调用了 RelPermalink 方法。这是预期行为。
无头内容区块(headless section)
无头内容区块同样不发布,其下的每个页面都是一个无头包:
content/
├── headless/
│ ├── note-1/
│ │ ├── a.jpg
│ │ ├── b.jpg
│ │ └── index.md <-- 叶子包
│ ├── note-2/
│ │ ├── c.jpg
│ │ ├── d.jpg
│ │ └── index.md <-- 叶子包
│ └── _index.md <-- 分支包
└── _index.md <-- 首页在前置元数据中用 cascade 关键字把取值下发给后代页面:
+++
title = '无头内容区块'
[[cascade]]
[cascade.build]
list = 'local'
publishResources = false
render = 'never'
+++这里把 list 设为 local,是为了让后代页面仍然留在本地页面集合中。在首页中包含它们的内容与图片:
{{ with .Site.GetPage "/headless" }}
{{ range .Pages }}
{{ .Content }}
{{ range .Resources.ByType "image" }}
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ end }}
{{ end }}
{{ end }}发布后的结构与无头页面类似:public/headless/note-1/ 与 public/headless/note-2/ 下只有图片,没有任何 HTML 文件。
只列出、不发布
也可以让内容区块本身正常发布,只把后代页面挡在输出目录之外。例如做一个术语表:
content/
├── glossary/
│ ├── _index.md
│ ├── bar.md
│ ├── baz.md
│ └── foo.md
└── _index.md+++
title = '术语表'
[build]
render = 'always'
[[cascade]]
[cascade.build]
list = 'local'
publishResources = false
render = 'never'
+++区块页自己设成 render = 'always' 而正常输出,后代页面则只留在本地页面集合里,由区块模板把它们的正文直接渲染出来:
<dl>
{{ range .Pages }}
<dt>{{ .Title }}</dt>
<dd>{{ .Content }}</dd>
{{ end }}
</dl>于是输出目录里只有 public/glossary/index.html 与 public/index.html,各术语没有独立页面。
只发布、不列出
反过来,也可以让区块页自己不发布、不进入列表,同时保留后代页面各自生成独立页面:
content/
├── books/
│ ├── _index.md
│ ├── book-1.md
│ └── book-2.md
└── _index.md+++
title = '图书'
[build]
render = 'never'
list = 'never'
+++后代页面沿用默认构建选项,因此输出目录里没有 public/books/index.html,却有 public/books/book-1/index.html 与 public/books/book-2/index.html。
按环境隐藏内容区块
文档站往往有一批只给贡献者看的内部说明。与其另建一套外部文档,不如把它放进一个只在正式环境隐藏的内容区块:仍旧用 cascade 下发构建选项,并用 target 关键字把规则限定在生产环境。
+++
title = '内部资料'
[[cascade]]
[cascade.build]
render = 'never'
list = 'never'
[cascade.target]
environment = 'production'
+++这样本地开发时该区块照常可见,生产构建的输出里则不会出现它。cascade 只作用于后代页面,不作用于声明它的那个页面,所以区块页自身的 build 仍需按需单独设置。
站点级构建配置
站点配置中的 [build] 区段控制全局构建行为。它与页面级的 build 对象是两回事,键名也不相同,常用的有:
buildStats:在项目根目录生成hugo_stats.json,记录已发布站点中每个 HTML 元素的class、id属性与标签名,可作为数据源清理未使用的 CSS(即 pruning、purging、tree shaking)。子键enable默认false;disableIDs、disableTags、disableClasses默认也是false,分别用于排除 id、标签与 class。清理 CSS 通常只在生产构建进行,建议把buildStats放在config/production之下。cachebusters:声明被监视的源文件变化时,让资源缓存中的哪些键失效,从而触发 CSS 等依赖资源重建。每条规则含source(匹配assets/...等虚拟目录下文件的正则)与target(匹配缓存键的正则,可使用source中的捕获组,如$1)。cleanDestinationDir:Hugo 构建前并不清空publishDir,只覆盖同名文件,删除或改名后的旧页面会残留其中。该设置默认关闭,开启后 Hugo 会在渲染前清掉publishDir里没有对应静态文件的文件与目录;keepDirs、keepFiles用 glob 指定要保留的目录与文件,二者在0.167.0中引入,且设置的值会替换默认值而不是追加。noJSConfigInAssets:是否禁止在assets目录写入jsconfig.json(供js.Build的导入映射使用,便于编辑器智能提示);不使用js.Build时本来就不会写入。useResourceCacheWhen:何时使用资源文件缓存,取值为never、fallback、always,适用于把 Sass 转译为 CSS 的场景,默认fallback。