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>
こうやってフレームワーク化されてて偉い。