HugoとTailwind CSSで静的サイトの作成準備をする
概要
Hugoで静的サイトを作り始めるため、ざっくりとしたテンプレートを1から作成する。
この記事で行うこと
環境
Hugo v0.77.0
{
"devDependencies": {
"autoprefixer": "^10.0.1",
"css-loader": "^5.0.1",
"postcss": "^8.1.4",
"postcss-loader": "^4.0.4",
"sass": "^1.29.0",
"sass-loader": "^10.0.5",
"style-loader": "^2.0.0",
"tailwindcss": "^1.9.6",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0"
}
}
覚え書き
Hugo
The world’s fastest framework for building websites | Hugo
Go製の静的サイトジェネレータ。コマンドを叩くと処理のいちいちが速い。
氷砂糖はGoのことがほとんど分からないが、Goの知識が分からないことで躓くことはほとんど無かった(Goでの実装を方法を探していたらHugoのサイトにHugoの実装として答えが載っていたことがある)。
既存テーマを使うならともかく、1からテンプレートを作ろうと思うと個人的には読みにくいリファレンス(文字が多くて辞書っぽい作りのためそう感じる?🤔 あと出来ることが多くて量が多い)を全体的に読んでいく必要がある。しかし、Hugoの基本機能で表現したいことの大部分がカバーできたため一度覚えてしまうと使い勝手がよかった。
使う前はなぜかブログに強いイメージがあったが、ブログでもドキュメントでもこなせるし、1ページ1ページが違うデザインのサイトでも無理なく対応可能そうだった。
Tailwind CSS
Tailwind CSS - A Utility-First CSS Framework for Rapidly Building Custom Designs
1からスタイルを付けていくのに便利なCSSライブラリ。例えば「背景色をグレーにしたい」場合はbg-gray-500
のようなクラスを要素に追加する。
好意的に書かれている記事をよく見かけるので使ってみたくなるのだが、Post CSSの知識がないと 「そもそもどうやって導入したらいいのか分からない」 という状態になるかもしれない🙄
テンプレートの準備
スケルトンの作成
任意のディレクトリでhugo new site myblog
を実行し、サイトのスケルトンを作成する(myblog
は好きな名称でよい)。
hugo new site myblog
サーバの起動
先程作成したディレクトリ内に移動し、hugo server -D
でサーバを起動する。
cd myblog
hugo server -D
テスト用コンテンツの作成
作成中のテンプレートが確認がしやすいように、適当な記事を作成する。
hugo new posts/my-first-post.md
hugo new posts/my-second-post.md
hugo new posts/my-third-post.md
テンプレートの作成
ベーステンプレート
各テンプレートのベースとなるテンプレートをlayouts/_default/baseof.html
に作成する。
<!DOCTYPE html>
<html lang="{{ .Site.Language.Lang }}">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ .Site.Title }}</title>
</head>
<body>
<h1>
<a href="{{ .Site.BaseURL }}">{{ .Site.Title }}</a>
</h1>
<div>
{{ block "main" . }}{{ end }}
</div>
</body>
</html>
参考
- Base Templates and Blocks | Hugo
- Site Variables | Hugo(サイト周りの値を持つ変数)
リストテンプレート
記事の一覧用のテンプレートをlayouts/_default/list.html
に作成する。
{{ define "main" }}
<ul>
{{ range .RegularPages }}
<li>
<a href="{{ .Permalink }}">{{ .Title }}</a>
</li>
{{ end }}
</ul>
{{ end }}
参考
シングルページテンプレート
記事の単体表示用のテンプレートをlayouts/_default/single.html
に作成する。
{{ define "main" }}
<article>
<header>
<h1>{{ .Title }}</h1>
<div>{{ .Date.Format "January 2, 2006" }}</div>
</header>
<div>{{ .Content }}</div>
</article>
{{ end }}
参考
- Single Page Templates | Hugo
- .Format | Hugo(日付の表示形式を指定する関数)
- Page Variables | Hugo(ページ周りの値を持つ変数)
ホームページテンプレート
サイトのトップページ(ホームページ)で使用するテンプレートをlayouts/index.html
に作成する。
{{ define "main" }}
<ul>
{{ range (where .Site.RegularPages "Section" "posts") }}
<li>
<a href="{{ .Permalink }}">{{ .Title }}</a>
</li>
{{ end }}
</ul>
{{ end }}
参考
Tailwind CSSの導入
テンプレートのデザイン用にTailwind CSSを導入する。
Hugo自体にもPostCSS等を処理する仕組みがあるが、テンプレートを作るたびにその部分で躓くため、ひとまずWebpackでTailwind CSSのビルドを行う。
パッケージの追加
Tailwind CSSのビルドに必要なパッケージを追加していく。
Webpack
Webpackの使用に必要。
yarn add --dev webpack webpack-cli
css-loaderとstyle-loader
css-loader
は@import
とurl()
を解決し、style-loader
はDOMにCSSを注入する。
yarn add --dev css-loader style-loader
Sass
Sass(SCSS)の使用に必要(Sassを使わないなら不要🤔)。
yarn add --dev sass sass-loader
Post CSS
Post CSSの使用に必要。
yarn add --dev postcss postcss-loader
Autoprefixer
ベンダープリフィックスをよしなにしてくれる。
yarn add --dev autoprefixer
Tailwind CSS
Tailwind CSSの使用に必要。
yarn add --dev tailwindcss
設定ファイルの作成
webpack.config.js
に設定ファイルを作成する。
今回はsrc/index.js
をエントリポイントにし、assets/bundle.js
にビルド結果を書き出している。
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'assets'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.scss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: {
ident: 'postcss',
plugins: [
require('tailwindcss'),
require('autoprefixer')
]
}
}
},
'sass-loader'
]
}
]
}
}
ソースの作成
エントリポイントのコードから作成していく。
src/index.js
import './css/main.scss'
src/css/main.scss
@tailwind base;
@tailwind components;
@tailwind utilities;
ビルド実行
コマンドを実行してビルドを行う。
yarn webpack
ビルド結果ファイルの読込
ビルドしたJavaScriptファイル(assets/bundle.js
)をベーステンプレート(layouts/_default/baseof.html
)等に読み込ませる。
<html>
<!-- ... -->
<body>
<!-- ... -->
{{ $script := resources.Get "bundle.js" }}
<script src="{{ $script.RelPermalink }}"></script>
</body>
</html>
Discussion