OGPカードやActivity Heatmapで、独自のCSSやJSを追加している。これらファイルの圧縮(Minify)は、Hugoのresources.Minifyを使えば良い。
- configファイルに
assetDir: "assets"を足す - 圧縮したいファイルを
assetsディレクトリに置く resources.Minifyする
例えばCSSファイルを読み込んでいるところを以下のように書き換える。
{{- $embed_css := resources.Get "css/embed.css" | resources.Minify }}
<link rel="stylesheet" href="{{ $embed_css.RelPermalink }}">
サイト生成時、 public/css に embed.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.html をlayouts/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 -}}
何をしているのかざっくり説明すると、
contentに置いたファイルパスを引数で受け取るreadFileでファイルの内容を取得resources.FromStringとresources.Minifyで圧縮&書き出し
なおこのコードは上記コードは js で固定されていたり、複数回呼び出しの処理をサボっている点に注意。
以下のように呼び出すと、サイト生成時に *.min.js が生成される。
<script src="{{< minify "js/loader.js" >}}" async defer></script>
こうやってフレームワーク化されてて偉い。
