WordPressは重い、SSGは敷居が高い
もともとWebディレクターをやっていたので、サイトの管理を色々な人に渡す場面を多く見てきた。 WordPressは定番だが、個人や小規模チームには重い。サーバーの維持、セキュリティアップデート、プラグインの互換性。管理画面も慣れないと何がどこにあるかわからない。クライアントが記事を更新しようとして管理画面で迷子になるのを何度も見た。 Wixやstudioなども課金しないと意外と制約が多く、個人向けや予算が少ない案件ではもどかしく感じることが多かった。
昔、個人的に友人のイラストレータのWebサイトを作ったことがある、駆け出しだったので、できるだけランニングコストが掛からず運用できて、広告が出ず、独自ドメインが使え、さらに簡単に更新できる、そんな条件で探すと驚くほど選択肢がなかった、無理やり作ったが結局うまく運用できず放置になってドメインの更新もやめてしまった経験がある。
静的サイトジェネレーター(SSG)は技術的には正解だと思っている。速い、安い、安全、ホスティングも無料枠で十分。ただSSGで記事を書くにはMarkdown、YAML、ターミナル操作、Gitの知識が前提になる。エンジニア以外には事実上使えない。 SSGの良さを残しつつ、非エンジニアにも渡せるものが作れないか。SSGのポテンシャルを最大限発揮するアプリ、これがFubakoの出発点。
なぜZolaを選んだか
SSGはHugo、Astro、Eleventy、いろいろある。全部対応したら便利だが、最初から複数SSGに対応させるとなると工数がかかるうえに各SSGの仕様を把握する必要もあり、個人ではかなり重い。 Zolaを選んだのは、ビルドが速い、設定がシンプル、テンプレートがWordPressに近くてWordPressを扱っていたような人にはテンプレートが書きやすい。
Electronにした判断
デスクトップアプリのフレームワークはElectronとTauriを比較した。 Tauriの方が新しくて軽量で、今から新しく作るなら選びたくなる気持ちはある。ただFubakoにはNode.js前提の要件がいくつかあった。Zolaの子プロセス管理、js-yamlでのfrontmatterパース、Dugite(GitバイナリのElectronバンドル)。TauriだとこのあたりをRust側で書き直すかサイドカーを使うことになる。 別のプロジェクト(VoicePeel)でWailsというGo製のElectron代替を試していて、非Electronフレームワークの粗さを体感していた。Tauriはもっと成熟しているとはいえ、Electronのエコシステムの安定感は今でも強い。 バンドルサイズが大きくなるのは確かだが、デスクトップCMSでバンドルサイズを気にする人はあまりいない。安定性を取った。
site-config.ymlの設計
Fubakoの核はsite-config.yml。このファイルにコンテンツタイプとフィールド定義を書くと、Fubakoが管理画面のUIを動的に生成する。
この仕組みにした理由は「サイトごとにフィールドが違う」から。ブログならタイトルと本文と日付があればいいが、ポートフォリオならプロジェクト名、ステータス、進捗率、技術タグが要る。フィールド構成をコードに埋め込むと、サイトごとにFubakoを改修することになる。
このあたりはWordPressで辛かった体験とBlogメインではないことからこの設計にしている。
設定ファイルの形式はYAMLにした。最初はZolaのconfig.toml内の[extra]に入れようとしたが、TOMLのネスト記法がフィールド定義のような構造化データには読みにくい。YAMLの方が素直。
フィールドの型はZolaのfrontmatter仕様から逆算して決めた。Zolaのextraセクションに書ける型(文字列、数値、真偽値、日付、配列、マップ)にFubakoのフィールド型を1対1で対応させた。これでFubakoが出力するfrontmatterは常にZolaが解釈できる。
Dugiteにした理由
Git操作は最初simple-gitを使っていた。simple-gitはシステムにインストールされたgitコマンドをラップするライブラリで、開発中は問題ない。 ただFubakoをアプリとして配布するとき、ユーザーの環境にgitが入っている保証がない。非エンジニアに渡すツールなのだから、gitが入っていない環境で動かないのは論外。 Dugiteに切り替えた。GitHub Desktopチームが作ったライブラリで、gitバイナリ本体をElectronにバンドルしてくれる。コマンドの引数を直接組み立てるのでsimple-gitより低レベルだが、必要な操作(add、commit、push、clone、status)は限られているのでそこまで辛くない。
frontmatterの往復変換
js-yamlでfrontmatterをパースして、Vueのフォームに渡して、編集後にYAMLに戻して保存する。この往復で地味にハマった。
Zolaのfrontmatterはextraセクションにカスタムフィールドを入れる。YAMLとしてはネスト構造。Vue側ではextra.thumbnailのようなドット記法のフラットなキーで扱いたい。フラット↔ネストの変換を入れて、往復で情報が落ちないようにする必要がある。
もう1つ厄介だったのがYAMLの日付型。date: 2025-06-20はjs-yamlがJavaScriptのDateオブジェクトに変換するが、Zolaは文字列としてYYYY-MM-DDを期待する。保存時にDateを文字列に戻す処理を入れないとZolaのビルドが壊れる。この手の型の不一致が何箇所かあって、全部潰すのに時間がかかった。
自分のサイトで使ってみて
frogworks404のサイトをFubakoで構築して運用している。自分で使うことで、UIの動線の悪さ、エディタの細かいバグ、プレビューの反映速度が体感でわかる。 たとえば記事を保存した直後にプレビューが更新されないことがあった。Zolaのファイル監視が保存イベントを検知する前にプレビューのリロードが走ってしまうタイミング問題。自分で使っていなかったら気づかなかった類のもの。 site-config.ymlのフィールド定義も、実際に使うと足りないものが見えてくる。tagsフィールドは当初Phase 2で後回しにしていたが、frogworks404のタグフィルタ機能を作るのにPhase 1で必要になった。実運用で優先順位が変わる典型例。 もともとFubakoは「非エンジニアに渡せるCMS」として作り始めたが、自分でドッグフーディングすることでエンジニアの視点からの粗も見えてくる。機能やUX的な部分はまだまだ課題は多いがこのサイトの更新を続けながら、少しずつ改善を続けていこうと思っている。