GitHub Pagesにて、ホットクックのレシピについて管理するサイトをホストしてみた

最近、調理器具のホットクックを買いました。
ヘルシオ ホットクック:シャープ

野菜を切って肉を入れ、後は調味料を入れてスイッチを押せば料理が完成するので、便利に使っています。

また、ホットクックには混ぜ技ユニットが付属しており、これを使えばホットクックでの料理の幅が広がります。

とはいえ、混ぜ技ユニットを洗うのすら手間に感じる時があるので、基本的には混ぜ技ユニットを使わない料理を作っています。

 
ただ、混ぜ技ユニットを使わないホットクックのレシピを探すのはなかなか手間なこと、自分で試してみてうまくいったと思ってもそのレシピを忘れてしまうことがあり、レシピを管理したくなりました。

今のところ、よく使うレシピはそんなに多くなく、また、今後もそんなに増えないことから、レシピの管理にデータベースを使ったり、サーバーを建てたりするのは大げさのように感じました。

 
Claudeと壁打ちしてみたところ、GitHub Pagesでホストする形でもレシピの管理や検索ができると分かりました。

そこで、GitHub Pagesでレシピ管理サイトを作った時のメモを残します。

ちなみに、レシピ管理サイトはこちらのURLです。
https://thinkami.github.io/hotcook_recipe/

 
目次

 

環境

  • macOS
  • GitHub Pages
  • Claude Code
  • Node.js 24.19.0
  • js-yaml 5.2.3
  • markdown-it 15.0.0
  • vitest 4.1.10
  • fast-check 4.9.0
  • oxlint 1.77.0
  • oxfmt 0.62.0
  • OpenSpec 1.2.0

 

レシピ登録から公開までのワークフロー全体

今回のワークフローをmermaid図で示すとこんな感じです。

 

Gitブランチ戦略とレシピの保存方法について

GitHub Pagesで公開することになるので、レシピはGit管理すると良さそうでした。

レシピ管理サイト経由でなくてもレシピを把握しやすいと良さそうなことから、レシピはYAML形式のfrontmatterを持つMarkdownで管理することにしました。

また、次の理由により、今回は main ブランチへの直接コミット・pushを許可しました。

  • レシピの誤字脱字など、簡単な修正もありそうで、都度プルリクを作るのは手間そうに見えたため
  • 公開ワークフローがビルド、テスト、LinterやFormatterをパスしてから公開するようになっているため、壊れる可能性は低いと考えられたため
  • main ブランチへの直接pushで仮に壊れたとしても、そこにあるのはホットクックのレシピだけなので、実害はそんなにないと判断したため

 

レシピの検索について

技術選定

最初、全文検索機能を作ることを考えました。しかし、自分が欲しいのは「手元にある食材で何が作れるか」なので、そんなに頑張らなくても良いことに気づきました。

ただ、それであっても自力で作るのは手間なので、何かしらのライブラリを探すことにしました。

今回、GitHub Pagesで公開することを目的としたため、JavaScript/TypeScript製のライブラリを探したところ、Fuse.jsがありました。
https://github.com/krisk/Fuse

しかし、Fuse.jsではtypoへの対応は行えるものの、 味噌 という食材に対し みそ という読み方での検索ができないことから、採用は諦めました。

 
そこで次は、読み方での検索ができそうな、形態素解析による検索を考えました。

よく見かけたのはMeCabやkuromojiだったので、今回はこれらを採用することも考えました。

 
とはいえ、依存関係を増やしたくないと考え、Claudeと壁打ちしてみました。

すると、macOSに付属している日本語エンジンをJXA (JavaScript for Automation) から叩けば、特にライブラリを追加することなく実現できそうと分かりました。

その結果、検索そのものにはライブラリを使わなくてすみました。検索はブラウザ上のJavaScriptで、正規化と部分一致を独自実装すればよくなったためです。

 

macOS組み込み日本語エンジンによる読み方の取得

今回のアプリは

  • ローカルのmacOS環境でレシピを追加する
  • レシピの追加頻度は高くない

という状況だったので、次の3段階へと処理を分けることにしました。

  • ローカル作業時
    • レシピの語を分割し、読みを取得し、 data/yomi.generated.json に書き出す
    • 語の読みが誤っている場合は、手動で訂正ファイル data/yomi.overrides.json に正しい読みを書く
      • 誤読はかなとして妥当な形で出るため、人間が手動で修正する必要があるため
      • なお、訂正は再生成しても消えない
  • ビルド時
    • 取得した読みを付与する
  • ブラウザでの検索時
    • 「ビルド時に付与された読み」を含むデータを読み込み、ブラウザ上のJavaScriptで正規化して、部分一致で検索する

 
そこで、ローカル作業時に、JXAによるmacOS組み込みの日本語エンジンを使うことにしました。

JXAでは、主に3つのAPIを使っています。

  • CFStringTokenizer
    • 日本語の語に分ける
  • CFStringTokenizerCopyCurrentTokenAttribute
    • ローマ字転写の読みを取得する
      • 豚バラなら butabara
  • CFStringTransform
    • ローマ字をひらがなにする

実装についてはClaudeに任せたこともあり、詳しくは scripts/yomi-reader.jxa ファイルを確認してください。

 

YAMLを読むライブラリについて

今回、レシピはMarkdownファイルとして作成しています。ただし、食材やホットクックのメニュー番号を構造的に管理できるよう、YAML形式のfrontmatterを付けています。

そこで、frontmatterを読み取るためにYAMLを読む機能が必要になります。

JavaScriptまわりでYAMLを読むことのできるライブラリを探したところ、

がありました。

yaml のほうが依存は少なそうでしたが、 js-yaml は複数のメンテナーによる開発が続いており、古い3系や4系へもバックポートされていることから、今回は js-yaml を使うことにしました。

なお、独自実装も考えましたが、頑張るところではないと判断し、今回は見送りました。

 

Markdownファイルを読むライブラリについて

GitHub Pagesで公開するにあたり、レシピのMarkdownファイルをHTMLへと変換することにしました。

HTML化できるライブラリとしては次がありました。

実装時点では、依存数はMarkedの方が少なかったです。しかし、レシピのMarkdownに書いた生HTMLを無効化する組み込みのオプションが見当たらず、自分でエスケープする必要がありそうでした。

一方、markdown-itは依存があったものの、生HTMLを無効化するオプションがありました。

自分だけがレシピを書く予定なので、基本的には生HTMLが有効であっても問題ないとは思いますが、念のため安全側に倒すことにしました。

そこで今回はmarkdown-itで生HTMLを無効化してHTMLを生成することとしました。

 

プロパティベーステストについて

せっかくなので、テストコードを充実させることにしました。

通常の事例ベーステストに加え、 fast-check を使ったプロパティベーステストも追加しています。
https://github.com/dubzzz/fast-check/

 
今回は以下のところでプロパティベーステストを導入しました。

  • frontmatterスプリッタが元に戻せる形で分割しているか確認
    • Markdown中のYAMLの部分と本文を分割しても、元に戻るか
  • レンダラーのリグレッションがないことの確認
    • 任意の本文で <script が出ず、生HTMLの無効化がなされている
  • 冪等性の確認
    • 検索語の正規化を2回行っても、1回のときと同じ結果になる
  • 再現性の確認
    • 同じレシピからは、何度ビルドしても同一の検索用データが得られる
  • 手動で作成したファイルが破壊されないことの確認
    • 読みの自動生成処理では、手動で作成した訂正ファイルを変更しない

 
なお、今回のアプリはJavaScriptだけで書いていますが、 fast-check の配布物はJavaScript + 型定義なので、問題なく利用できます。

 

レシピ登録のAIスキルについて

レシピはYAML frontmatterをもつMarkdownで管理しているため、自分でそのファイルを書くことも考えました。

ただ、そんなに大量のレシピを作るわけではないので、レシピファイルのフォーマットに従った書き方を忘れてしまう可能性がありました。

そこで、レシピ登録をAIスキルとして用意し、やり方を忘れてもAIによるサポートで登録できるようにしてみました。

 

スクリーンショット

ページにアクセスすると、レシピタイトルの一覧が表示されます。

 
上の検索窓に使いたい食材や料理名、手順を入力すると、それにマッチした料理が残ります。

 
かなでの検索も行えます。

 
クリックすると、レシピが表示されます。なお、材料は投入順に表示しています。

 
なお、材料の切り方についてはその時の気分で大きさとか形を変えているため、厳密には書いていません。いい感じで作れれば良いと割り切っています。

 

ソースコード

GitHubに上げました。
https://github.com/thinkAmi/hotcook_recipe