しばらくGitHubブログを放置していました。「いつかまた整理しよう」という思いを繰り返すばかりでしたが、勉強した内容をちゃんと記録して共有する場所が必要だと感じました。そこでブログをゼロから作り直すことにしました。
なぜNext.jsを選んだのか#
当時Svelteが注目を集めていましたが、ブログを素早く完成させるにはNext.jsの方がいいと判断しました。Svelteを新しく学んでSvelteKitを習得しながら適切なライブラリを探していくよりも、Next.js一本で学習しながら進める方がラーニングカーブがずっと短かったのです。
既存のブログはNext.js 12バージョンでしたが、npxでアップグレードを試みたところうまくいきませんでした。結局新しいプロジェクトを作成してshadcnを適用する方式で進めました。今はNext.js 14 + Contentlayerの組み合わせで静的ブログを運用しています。
開発環境のセットアップ#
当時使っていたiMacにはNode.jsがインストールされていなかったので、Next.jsのDocker例を活用しました。パッケージマネージャーはpnpmを使うことにし、Homebrewでインストールすれば簡単です。
pnpm create next-app --example with-docker nextjs-dockerこの一行でDockerベースのNext.jsプロジェクトが生成されます。
ブログに必要な機能#
ブログにどんな機能が必要か整理してみました。Next.js自体の機能と外部ライブラリを組み合わせれば、ほとんど実装できます。
- Routing — Next.js App Routerでページ間の遷移を処理
- 画像レンダリング — マークダウン内の外部画像をdata URIで最適化
- コメント機能 — GitHubベースのコメントシステムを活用
ブログの画面構成#
現在のブログはこのような構成になっています。
| 画面 | 役割 |
|---|---|
| Home | 最新記事の紹介、検索、記事一覧 |
| Books | 読んだ本の一覧と詳細表示 |
| Tags | タグ別に記事を閲覧 |
| About | 自己紹介 |
Homeが記事一覧と検索機能の両方を担っているので、別途Postsページがなくても十分です。Books画面では読んだ本の中で最も感銘を受けた一節を下部に入れることにしました。
マークダウンをHTMLに変換する#
ブログ記事を画面に表示するには、マークダウンファイルをHTMLに変換する必要があります。今はContentlayerがこの役割を担っていますが、最初は自前で変換パイプラインを構築していました。
generateStaticParamsでpostsフォルダのすべての記事を取得して一つずつ読み込み、unifiedでマークダウンをHTMLに変換し、frontmatterからメタデータを抽出してPostオブジェクトを作るという方式でした。
マークダウン変換によく使われるツールを比較してみました。
| ライブラリ | 特徴 |
|---|---|
| gray-matter | frontmatterのパースに特化 |
| marked | GitHubスターが多く10年以上の実績あるライブラリ |
| unified | プラグインエコシステムが豊富で拡張性に優れる |
結局拡張性を優先してunified系を選びました。今でもContentlayer内部でremark/rehypeプラグインを組み合わせて、シンタックスハイライト、数式レンダリング、外部リンク処理などを行っています。
unifiedパッケージを使う際にこの記事(日本語)がとても参考になりました。
マインドマップで学習の軌跡を可視化する#
ブログを作る中でもう一つアイデアが浮かびました。勉強に意味を持たせると記憶に残りやすいという話にインスピレーションを受けたのです。
各タグをマインドマップで見られる画面を作ったらどうだろうと思いました。勉強してブログに載せた内容を点にして、その点を線でつなぐイメージです。
たとえばDockerを勉強したなら、Dockerがどういうものか掴めていく過程で自分はどんな視点でDockerを見るようになったのか、そしてこの次はどんな勉強に進むのかを視覚的に追跡できます。
このつながりを目で見ることができれば、それ自体がモチベーションになります。
振り返って#
ブログを作り直すことは、単に技術スタックを変えるということではありませんでした。勉強したことを整理し、その過程を他の人と共有する一つのシステムを作るということだったのです。
完璧なブログを待つよりも、まず作ってから一つずつ改善していくのが一番良いスタートです。
No man can succeed in a line of endeavor which he does not like.
— Napoleon Hill