OGPカードActivity Heatmapで、独自のCSSやJSを追加している。これらファイルの圧縮(Minify)は、Hugoのresources.Minifyを使えば良い。

  1. configファイルに assetDir: "assets" を足す
  2. 圧縮したいファイルを assets ディレクトリに置く
  3. resources.Minify する

例えばCSSファイルを読み込んでいるところを以下のように書き換える。

{{- $embed_css := resources.Get "css/embed.css" | resources.Minify }}
<link rel="stylesheet" href="{{ $embed_css.RelPermalink }}">

サイト生成時、 public/cssembed.min.css が生成されていることを確認できる。

さて、こっからが本題。

HugoのレイアウトHTMLは上記の方法で圧縮できるんだけど、Contentに設置したJSだとこの方法は使えない。Contentから resources.Minify などのコードを呼び出せないから。例えば、先日ベジェ曲線のメモで、制御点をグリグリできるデモを設置した。このJSは content 下に置いている。しかし index.md 内で直接 resources.Minify は使えない。

0621_bezier
├── index.md
└── js
    ├── bezier.js
    ├── code-example.js
    ├── interaction.js
    └── loader.js

そこで、Shortcodes経由で呼び出す。以下のような minify.htmllayouts/shortcodes に置く

{{- $arg_path := printf "%s%s" .Page.File.Dir (.Get 0) -}}
{{- $content := readFile $arg_path -}}

{{- $hash := substr (md5 $content) 0 8 -}}
{{- $filename := printf "js/%s.js" $hash -}}

{{- $minified := resources.FromString $filename $content | resources.Minify -}}
{{- $minified.RelPermalink -}}

何をしているのかざっくり説明すると、

  1. content に置いたファイルパスを引数で受け取る
  2. readFile でファイルの内容を取得
  3. resources.FromStringresources.Minify で圧縮&書き出し

なおこのコードは上記コードは js で固定されていたり、複数回呼び出しの処理をサボっている点に注意。

以下のように呼び出すと、サイト生成時に *.min.js が生成される。

<script src="{{< minify "js/loader.js" >}}" async defer></script>

こうやってフレームワーク化されてて偉い。

Shortcode templates
Shortcode templates
Create custom shortcodes to simplify and standardize content creation.
🔗gohugo.io