什么是 Hugo 资源管道

Hugo 资源管道是一套强大的资源处理系统,允许对网站资源(如 CSS、JavaScript、图片等)进行转换、优化和打包。通过管道操作符 |,可以将多个处理函数串联起来,形成处理链。

基本语法

      {{ $resource := resources.Get "path/to/resource" }}
{{ $processed := $resource | function1 | function2 | function3 }}
    

项目中的管道使用示例

JavaScript 资源处理

基本构建与优化

      <!-- 获取 JS 资源 -->
{{ $flexSearch := resources.Get "docs/js/flexsearch.bundle.js" }}

<!-- 设置构建参数 -->
{{ $params := dict }}
{{ $sourceMap := cond hugo.IsProduction "" "inline" }}
{{ $opts := dict "sourceMap" $sourceMap "minify" hugo.IsProduction "target" "es2018" "params" $params "treeShaking" true }}

<!-- 构建处理 -->
{{ $flexSearch = $flexSearch | js.Build $opts }}

<!-- 生产环境添加指纹 -->
{{- if not hugo.IsServer }}
    {{ $flexSearch = $flexSearch | fingerprint "sha384" }}
{{ end }}
    

多文件合并处理

      <!-- 获取多个 JS 资源 -->
{{ $navbarJs := resources.Get "js/responsive-navbar.js" }}
{{ $bootstrapJs := resources.Get "docs/js/bootstrap.js" }}

<!-- 合并文件 -->
{{ $combinedJs := slice $navbarJs $bootstrapJs | resources.Concat "docs/js/navbar.js" }}

<!-- 统一构建配置 -->
{{ $params := dict }}
{{ $sourceMap := cond hugo.IsProduction "" "inline" }}
{{ $opts := dict 
  "sourceMap" $sourceMap 
  "minify" hugo.IsProduction 
  "target" "es2018" 
  "params" $params 
}}

<!-- 构建合并后的JS -->
{{ $finalJs := $combinedJs | js.Build $opts }}

<!-- 生产环境添加指纹 -->
{{ if hugo.IsProduction }}
  {{ $finalJs = $finalJs | fingerprint "sha384" }}
{{ end }}
    

动态资源收集与合并

      <!-- 创建资源切片 -->
{{ $slice := slice }}

<!-- 添加多个资源到切片 -->
{{ $imageZoomJS := resources.Get "docs/js/imageZoom.js" }}
{{ $slice = $slice | append $imageZoomJS }}

{{ $darkModeInit := resources.Get "docs/js/darkmode-init.js" }}
{{ $slice = $slice | append $darkModeInit }}

<!-- 合并所有资源 -->
{{ $js := $slice | resources.Concat "docs/js/bundle.js" }}

<!-- 生产环境优化 -->
{{- if not hugo.IsServer }}
    {{- $js := $js | minify | fingerprint "sha384" -}}
    <script type="text/javascript" src="{{ $js.Permalink }}" integrity="{{ $js.Data.Integrity }}" crossorigin="anonymous" defer></script>
{{- else }}
    <script type="text/javascript" src="{{ $js.Permalink }}" defer></script>
{{- end }}
    

CSS 资源处理

SCSS 编译与优化

      <!-- 获取 SCSS 资源 -->
{{- $style := resources.Get "scss/style.scss" }}

<!-- 设置处理选项 -->
{{- $options := dict "enableSourceMap" true }}
{{- if hugo.IsProduction}}
    {{- $options := dict "enableSourceMap" false "outputStyle" "compressed" }}
{{- end }}

<!-- 处理链:执行模板 -> SCSS编译 -> PostCSS处理 -->
{{- $style = $style | resources.ExecuteAsTemplate "scss/style.scss" . | css.Sass $options | css.PostCSS }}

<!-- 生产环境优化 -->
{{- if hugo.IsProduction }}
    {{- $style = $style | minify | fingerprint "sha384" }}
{{- end }}
    

条件处理与环境区分

开发与生产环境区分

      <!-- 根据环境设置不同的处理选项 -->
{{ $sourceMap := cond hugo.IsProduction "" "inline" }}
{{ $opts := dict "sourceMap" $sourceMap "minify" hugo.IsProduction }}

<!-- 仅在生产环境添加指纹 -->
{{- if not hugo.IsServer }}
    {{ $resource = $resource | fingerprint "sha384" }}
    <script src="{{ $resource.Permalink }}" integrity="{{ $resource.Data.Integrity }}" crossorigin="anonymous"></script>
{{- else }}
    <script src="{{ $resource.Permalink }}"></script>
{{- end }}
    

常用管道函数

资源获取与创建

  • resources.Get - 获取资源文件
  • resources.Concat - 合并多个资源
  • resources.ExecuteAsTemplate - 将资源作为模板执行
  • slice - 创建资源切片

JavaScript 处理

  • js.Build - 构建 JavaScript,支持 ES6+ 转换、压缩等
  • minify - 压缩资源
  • fingerprint - 添加内容指纹,用于缓存控制

CSS 处理

  • css.Sass - 编译 SCSS/Sass
  • css.PostCSS - 使用 PostCSS 处理 CSS
  • minify - 压缩 CSS

其他处理

  • resources.FromString - 从字符串创建资源
  • resources.ToCSS - 将资源转换为 CSS
  • resources.Minify - 通用压缩函数

最佳实践

资源组织

将资源文件组织在 assets 目录下,便于管道处理:

      assets/
├── js/
│   ├── main.js
│   └── components/
├── scss/
│   ├── main.scss
│   └── components/
└── images/
    

环境区分

根据不同环境(开发/生产)应用不同的处理策略:

      {{ $isProd := eq hugo.Environment "production" }}
{{ $opts := dict "minify" $isProd "sourceMap" (not $isProd) }}
    

缓存策略

使用指纹控制缓存:

      {{ $resource = $resource | fingerprint "sha384" }}
<link rel="stylesheet" href="{{ $resource.RelPermalink }}" integrity="{{ $resource.Data.Integrity }}">
    

条件加载

根据配置条件加载资源:

      {{ if eq .Site.Params.docs.prism true }}
    {{ $prism := resources.Get "docs/js/prism.js" }}
    {{ $prism = $prism | js.Build $opts }}
    <script src="{{ $prism.RelPermalink }}"></script>
{{ end }}
    

高级用法

动态路径构建

      {{ $resource := resources.Get (printf "/%s/%s" ($.Scratch.Get "pathName") "js/main.js") }}
    

参数传递

      {{ $opts := dict 
    "target" "es2018" 
    "params" (dict "langPath" "/js/components/") 
    "treeShaking" true 
}}
{{ $resource = $resource | js.Build $opts }}
    

资源切片操作

      {{ $resources := slice }}
{{ $resources = $resources | append (resources.Get "js/a.js") }}
{{ $resources = $resources | append (resources.Get "js/b.js") }}
{{ $bundle := $resources | resources.Concat "js/bundle.js" }}
    

性能优化建议

  1. 合并资源:将多个小文件合并成单个文件,减少 HTTP 请求
  2. 压缩资源:在生产环境中启用压缩
  3. 使用指纹:添加内容指纹,优化缓存策略
  4. 按需加载:根据页面需求条件加载资源
  5. Tree Shaking:启用 JavaScript 的 Tree Shaking 功能,移除未使用代码

调试技巧

  1. 检查资源路径:使用 RelPermalink 检查生成的资源路径
  2. 验证指纹:检查 Data.Integrity 值是否正确生成
  3. 环境测试:在不同环境下测试资源处理结果
  4. 构建日志:关注 Hugo 构建时的警告和错误信息

常见问题与解决方案

资源路径问题

确保资源文件位于 assets 目录下,而不是 static 目录。

构建失败

检查 JavaScript/SCSS 语法错误,特别是 ES6+ 特性是否需要转换。

缓存问题

使用 hugo --cleanDestinationDir 清理构建缓存,或更新资源文件触发重新构建。

总结

Hugo 资源管道提供了强大而灵活的资源处理能力,通过合理使用管道函数和最佳实践,可以显著优化网站性能和开发体验。在实际项目中,建议根据具体需求选择合适的处理策略,并在开发与生产环境间做好区分。

声明

作者: liyao

版权:本博客所有文章除特别声明外,均采用CCBY-NC-SA4.O许可协议。转载请注明!

最后更新于 2025-12-26 21:07 history