Hugo の Sass トランスパイル機能を使ってみたら便利だった
概要
neko-kaburi は Hugo で実装していて、CSS 周りは node-sass + Gulp の構成で Sass コンパイルして CSS を生成している。
このような構成はよく見かけるが、Sass をコンパイルするためだけに Gulp を使うのは少々オーバースペックな感じもする。
最近の Hugo には Dart Sass トランスパイル機能があり、試す機会があったのでまとめておく。
まえおき
Hugo に Sass トランスパイルが導入されたのはおそらく v0.43。
Dart Sass に対応したのは v0.80.0 (もう5年も前のことだった…
動作確認に使用した環境は以下。
- macOS: 15.1.1
- Hugoバージョン: v0.142.0
Hugo の Sass トランスパイルは、デフォルトで LibSass が使用されるが、LibSass は2020年に廃止されている。
そのたため、今回は Dart Sass を Hugo でトランスパイルする手順についてまとめる。
Transpile Sass to CSS using the LibSass transpiler included in Hugo’s extended and extended/deploy editions, or install Dart Sass to use the latest features of the Sass language. HUGO > css.Sass > Dart Sass
LibSass is an implementation of Sass in C/C++, designed to be easy to integrate into many different languages.
However, as time wore on it ended up lagging behind Dart Sass in features and CSS compatibility.
LibSass is now deprecated—new projects should use Dart Sass instead. LibSass
開発環境 (mac) では、以下の手順で Dart Sass をインストールできる。
brew install sass/sass/sass
任意のバージョンの Dart Sass をインストールしたい場合は、
sass > dart-sass で入手可能。
インストール後、下記コマンドで Hugo と Dart Sass のバージョンを確認できる。
$ hugo env
hugo v0.142.0+extended+withdeploy darwin/amd64 BuildDate=2025-01-22T12:20:52Z VendorInfo=brew
...
github.com/sass/dart-sass/protocol="3.1.0"
github.com/sass/dart-sass/compiler="1.83.4"
github.com/sass/dart-sass/implementation="1.83.4"
CI/CD でデプロイする際は、Installing in a production environment を参考に、デプロイワークフローに Dart Sass インストールのフローを追加する。
Hugo で Sass トランスパイルする設定
まずは、トランスパイル設定用のパーシャルを作成する。 ここでは partials/style.html
を作成した。
公式ドキュメント を参考に、以下のような設定を書く (スタイルシートのファイル名は適宜変更している)。
{{ with resources.Get "sass/style.scss" }}
{{ $opts := dict
"enableSourceMap" (not hugo.IsProduction)
"outputStyle" (cond hugo.IsProduction "compressed" "expanded")
"targetPath" "css/style.css"
"transpiler" "dartsass"
}}
{{ with . | toCSS $opts }}
{{ if hugo.IsProduction }}
{{ with . | fingerprint }}
<link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
{{ end }}
{{ else }}
<link rel="stylesheet" href="{{ .RelPermalink }}">
{{ end }}
{{ end }}
{{ end }}
本番環境ではもろもろ圧縮して最小化しておきたいので、{{ if hugo.IsProduction }}
に minify を追加する。
...
{{ if hugo.IsProduction }}
{{ with . | minify | fingerprint }}
...
トランスパイル設定が書けたら、partials/head.html
内で 上記の partials/style.html
をインクルードする。
<head>html
<meta ...>
...
{{ partial "style.html" . }}
</head>
Let’s ビルド
トランスパイル設定が書けたら hugo server
コマンドで開発サーバーを起動する。
エラーなくトランスパイルできると、public/css
に style.css
と style.css.map
が生成される。public/index.html
には以下の link が追加される。
<link rel="stylesheet" href="/css/style.css">
本番環境向けには fingerprint を設定したので、以下のような link が生成される。
<link rel="stylesheet" href="/css/style.{fingerprint}.css" integrity="{sha256}" crossorigin="anonymous">
おまけ
(あまりないとは思うが) もし、<style>
タグ内に CSS を出力したい場合は以下のようにする。
{{ $sass := resources.Get "scss/style.scss" }}
{{ $css := $sass | css.Sass }}
<style>{{ $css.Content | safeCSS }}</style>
おわり
現状の neko-kaburi では、Sass の監視も Gulp を使っているが、Hugo ならデフォルトでファイルの変更を監視してくれる。 特別な設定は不要で、ファイルに変更があれば自動でリビルドしてくれるのでとても便利。
ちょっと落ち着いたら、neko-kaburi も Hugo の Sass トランスパイルに切り替えよう。