実現したいこと

hugo serverでローカル開発サーバーを起動したまま、別のターミナルでhugoを実行してビルドが通るかを確認したい。

しかし何も指定せずにhugoを実行すると、開発サーバーが配信しているファイルが本番用のURLで上書きされてしまう。ブラウザで開いているページのリンクが軒並み本番サイトのURLに変わり、クリックすると本番サイトへ飛ばされる。

-dオプションで出力先を分けると、開発サーバーに影響を与えずにビルドを確認できる。

hugo serverはpublic/に書き出す

Hugo v0.123.0以降、hugo serverは既定でディスクにファイルを書き出す。書き出し先はhugoコマンドと同じpublishDir(既定ではpublic/)である。

hugo serverはビルド時にbaseURLをローカルサーバーのURLへ置き換える。config.tomlに本番URLを設定していても、開発サーバーの出力にはローカルのURLが入る。

baseURL = 'https://example.com/'
$ hugo server -p 1316

開発サーバーを起動したまま別のターミナルでpublic/を確認すると、ローカルサーバーのURLが入っている。

$ grep -c "localhost:1316" public/index.html
40

同じターミナルでhugoを実行すると、開発サーバーの書き出したpublic/が本番のbaseURLで上書きされる。

$ hugo
$ grep -c "localhost:1316" public/index.html
0
$ grep -c "https://example.com" public/index.html
40

hugo serverはディスク上のファイルをそのまま配信するため、開発サーバーへアクセスしても本番URLが返る。

$ curl -s http://localhost:1316/ | grep -c "https://example.com"
40

-dで出力先を分ける

-d(--destination)オプションでビルド結果の出力先を指定する。

$ hugo -d /tmp/hugo-check
$ grep -c "localhost:1316" public/index.html
40

public/には一切書き込まないため、開発サーバーが配信するファイルはローカルのURLのまま保たれる。

生成されたHTMLの中身を確認する必要がなく、ビルドの成否だけを見たい場合は-M(--renderToMemory)を使うとディスクへ書かずに済む。

参考: 【Hugo】-Mオプションでディスクへ書かずにビルドする

相対パスはプロジェクトルート基準

-dに相対パスを渡した場合、カレントディレクトリではなくプロジェクトのルートディレクトリからの相対パスとして解釈される。

$ hugo -d tmp/build

サブディレクトリから実行してもプロジェクトルート直下のtmp/build/に出力される。意図しない場所への出力を避けたい場合は絶対パスを指定する。

publishDirより-dが優先される

出力先は設定ファイルのpublishDirでも変更できる。

publishDir = "docs"

publishDir-dを両方指定した場合はコマンドラインの-dが優先される。GitHub Pages向けにpublishDir = "docs"を常用しているプロジェクトでも、確認用のビルドだけ-dで一時ディレクトリへ逃がせる。

古いファイルを残さない

-dで指定したディレクトリに前回のビルド結果が残っていても、Hugoは削除せずに上書きする。記事のslugを変更した場合など、古いファイルが残ったままになる。

出力先を毎回まっさらにするには--cleanDestinationDirを付ける。

$ hugo -d /tmp/hugo-check --cleanDestinationDir

生成物に含まれないファイルが出力先から削除される。削除対象は指定したディレクトリの中身であるため、既存のファイルが入ったディレクトリを指定しないよう注意する。

参考: hugo | Hugo
参考: hugo server | Hugo