WordPress + wpXのサイトをHugo + Cloudflare Pagesに移行した話
きっかけはこの『HANDHELD PHOTOGRAPHY』で利用しているWordPressプラグインが、WordPress本体のバージョンアップに追従できなくてサイトのデザインが崩壊したことだった。今回のことを機に、興味のあったJamstackなサイトに切り替えてみようと一念発起した。
きっかけはこの『HANDHELD PHOTOGRAPHY』で利用しているWordPressプラグインが、WordPress本体のバージョンアップに追従できなくてサイトのデザインが崩壊したことだった。今回のことを機に、興味のあったJamstackなサイトに切り替えてみようと一念発起した。
いまさら説明するまでもないが、WordPressはCMS(=管理画面で記事を作り、アクセスされたときにサイトをレンダリングするシステム)のド定番である。そのせいもありWordPressには攻撃が多く、そのため脆弱性対策のバージョンアップが頻繁にある。その結果、稀にこのように追従できないプラグインが発生してしまう。 一方で、移行先となるJamstackは静的にコンテンツをプリレンダリングしておくアーキテクチャの1つであり、生成物を配信サービス(Headless CMSと呼ばれるものも含む)上にデプロイすることでネットに載せる仕組みとなる。
今回JamstackアーキテクチャはHugoを選択した。以下のような理由だ。
- Goによるシンプルなバイナリ構成(筆者はGoコーダーでもある)
- 高速なビルド
- markdownベースのコンテンツ作成
- テーマを高度にカスタマイズ可能
- マルチリンガルサポート
まずは既存のテーマを使って、とにかく簡単にブログを移行しようと考えていた。気に入ったらテーマは自作しよう、と。ところが、「簡単な移行」が全然簡単ではなくなってきた、というのが、この記事を書き記している理由だ。
本記事では、移行作業のハマりどころから、WordPressとHugoの比較、移行してみての所感を述べる。ちなみに筆者は仕事でもWordPressサイトを運用している。
念の為明記しておくが、比較対象に挙げてはいるが、WordPressホスティングサービスである wpXは何も悪くない。 安くて速い快適なサービスで、長らくお世話になった。しかしWordPressはLAMP構成であるため、どうしても比較にはサーバー側の話が出てきてしまうことをご容赦頂きたい。
WordPressからのエクスポートの苦労
まず、そもそもWordPressからのエクスポートが面倒だった。
画像エクスポートが面倒
WordPress to HugoのExporterという便利なツールも世の中にあるのだが、このブログをホストしてるサービスがメモリが小さいサービス(安い契約)だったせいか、全く動かなかった。
そのため、WordPressの標準Export形式であるXMLファイルをmarkdownに変換するというツールを利用した。しかもこのツール、画像も取得してくれるし、記事のメタデータも生成してくれる。素晴らしい。 変換そのものは実に素晴らしかった。素晴らしかったのだが・・・ 残念なことに、画像ファイルはサムネイルの方しか取得できていなかった。記事にある画像はサムネイルだから仕方ないのだけれど。
したがって、画像は手動で取得し直す必要があった。しかもWordPressは画像を記事ごとではなく日付ごとにフォルダ分けしている。記事ごとに分類するのは、自分でやらなければならない。これはWordPressのサムネイルの仕組みのせいだ、変換ツールは悪くない。でも地味に面倒だった。
せめてもの救いは、このブログはまだまだ記事が少ないことだったw
shortcodeの移植
markdownに変換したは良いが、WordPressのプラグインによって作られたコンテンツ(shortcode)は全くエクスポートできてないことに気がついた。そりゃそうだ、WordPressの機能なんだから。
このブログでは4つのshortcodeを使っていた。
- 地図
- Flickr
- 画像ギャラリー
- 画像比較スライダー
地図のshortcodeの移植はまず先送りにした。というか、捨て去った。移行ができないわけではないのだが、旅行ブログでもないので、地図の重要度は低いからだ。
Flickrのshortcodeも諦めた。米Yahoo!がFlickrを売却して以来、私の気持ちが離れ、ちゃんと更新していないから、という理由もある。
画像ギャラリーはhugo-easy-galleryを利用した。shortcodeがわかりやすく、依存もなく、改造も容易だった。公開しているliwenyipさんに感謝。
私が苦労したのは画像の比較スライダーだ。3枚以上の画像を比較できるという高機能ツールを使っていたがために、代替品を見つけるのに苦労してしまった。Dicsという良さげなものを見つけた上で、適用するのにも苦労した。これについては単に私がJavaScriptに明るくないせいであるが。
長くなるので、実装の説明記事は別にしようと思う。
Hugoのテーマの選択と目論見違い
曲がりなりにもこのブログはフォトブログである。写真を大胆に見せるテーマが使いたい。とはいえ、写真アルバムが作りたいわけではない。あくまでブログである。文字だって書く。それを兼ね揃えたテーマ、というのはなかなか見つからなかった。
「仕方ない、いつか自分で作ろう」「まずはそれなりに見栄えのいいテーマで始めよう」と思ってこの『Future Imperfect Slim』を選んだわけである。
しかしながら、使い始めてみると、汎用的なブログ向きテーマなので気になる場所がどんどん見つかる。写真を魅せる作りになってないのだ。
ってわけでカスタマイズをし始めた。そして気が付くと、これだけ(下図)の数のカスタマイズをしていたわけである。
しかしまさか、Hugoの利点の「テーマを高度にカスタマイズ可能」を早速実践することになるとは思わなかった。
og:descriptionが記事に応じていない
正確には、記事に description
を設定していない場合、先頭のブロックをサマリとするのではなく、サイト全体のdescriptionを利用してしまう。真面目に全部descriptionを書けば良いわけだが、面倒なこともあるよね。ということで、 head.html
を改変。
{{- $desc := .Description -}}
{{- if (not .Description) -}}
{{- $.Scratch.Set "summary" ((delimit (findRE "<p.*?>(.|\n)*?</p>" .Content 1) "") | truncate (default 500 .Site.Params.summary_length) (default "…" .Site.Params.text.truncated ) | replaceRE "</?a[^>]*>" "" | replaceRE "&" "&" | safeHTML) -}}
{{- $desc = $.Scratch.Get "summary" -}}
{{- end -}}
{{- if (eq $desc "") -}}
{{- $desc = .Site.Params.meta.description -}}
{{- end -}}
<head>
<meta property="og:description" content="{{ $desc }}">
<meta property="description" content="{{ $desc }}">
以下略
これで先頭の段落をdescriptionに設定するようになった。
※ 余談だが、HugoはHTML書式で独自記法なので、シンタックスハイライトがうまく効かない。これも直したいところだ。
サムネイルとEXIF対応
このサイトはフォトブログだ。とにかく多くの画像を扱えるようにし、高解像度=大容量のファイルも利用できるようにしたい。でも大容量のファイルはSEOはもちろん、モバイル回線に優しくない。
WordPressはサムネイルの仕組みがあるため、記事を読む時には小さな画像を読ませて高速なロードを実現できる。写真の細部を見たい人のためにはフルサイズの画像にアクセスできるようにしておけばいい。サムネイルによる面倒はあるものの、サイトパフォーマンスという意味ではとても効果的だ。
一方、Hugoはちゃんとコード(shortcode)を書かなければサムネイルは作られない。テーマがその辺考慮してくれてればいいのだが、残念ながら選んだテーマは考慮していなかった。流石に記事ページを読むだけでフルサイズの画像を読み込ませるのは酷である。
これもshortcodeを実装して解決した。長くなるので別記事で。
記事一覧ページのデザイン変更
こうやってどんどんフォトブログ用の準備をしていくと、記事一覧ページ(トップページとか)のデザインが気になり始めてしまった。
興味があれば元のデザインを見てもらいたいが、写真はあくまでおまけというかFeatured/OGP目的というか。白い面積が多くて、テキストを読みやすく仕上げていて、写真を中心に見せることは考えてない感じである。
一方でこのブログは、文章はむしろ雑にしたい気持ちなのである。(この記事は例外)
ということで、がっつり調整を始めてしまった。その結果カスタマイズされたデザインがどんどん増えることになったわけである。
スマホ対応で雑なところがある
このFuture Imperfect Slim、地味にwidthがあってない箇所があった。とはいえ、この手の実装漏れはあるあるなので、地道に直すだけである。
WordPressと比較して、Hugoのメリット
さて、ここまで色々と愚痴のようなことを書いてしまっていたが、移行したメリットについて、当事者だから感じていることを書き記そう。
記事のコード的美しさ
WordPressのときは、リッチエディタが邪魔をして記事にコードのような綺麗さを求めることができなかった。そのため、稀にわけわからない崩れ方をすることがあった。(生HTMLで全部書く技もあるが・・・)
加えて、記事はWordPressの内部構造に頼った記述となっていて、新しいサーバーにコンテンツを移すだけでも一苦労(例えば画像ファイルのパスとか)というところがあった。パスを直すためにDBに一気にUPDATEのSQLを流すやんちゃなプラグインがあるほどだ。
Hugoはmarkdownである。この時点で曖昧性は小さくなり、コード的にはすごくすっきりとしている。markdownという標準に則ってるために、お好みのmarkdownエディタを使って下書きできるのは強い。実際、この記事はNotionで本文を下書きしている。
テキストファイル + git管理なので、SQLに比べればパスやshortcodeの全置換も簡単でリスクも低い。仮にミスっても大抵はHTMLのビルド時に間違いを検出してくれるので、リンク切れコンテンツが発生する可能性も低い。
また、このサイトのように英語と日本語の記事を扱うのにも、ファイルをコピって、ファイル名に言語名を入れて、文章を書き換えて保存するだけだ。構造的にも作業のフロー的にもスッキリしていて嬉しい。
ただ一方でshortcodeというHugo独自の要素に頼ってる部分はある。他のプラットフォームやCMSに移ることを考えると、やっぱその時は面倒だろう。
保守性
サイト全体をgit管理できることで、差分の追跡や保守性が上がった。
WordPressではgit管理がとてもやりにくいのが悩みだった。WordPressではテーマだけをgit管理するケースが多いが、そうするとプラグインのバージョン管理ができず、変なハマり方をしたりする。至極稀にWordPress内のファイルを変更するケースもある。これはもうgit管理が不可能で、READMEなんかでメモしておく程度になって、いつかバグの原因となったりする。
Hugoはコンテンツも含めたサイト全体をgit管理しやすい。何をgitリポジトリに入れて何を入れないのか、なんてことを考える必要がないので、安心して『最新状態』をコード管理していられる。
DBも存在しないので、DB上に何かゴミが残る心配だとか、DBのバージョンの問題だとか、DBが死亡することでデータが失われるような不安もなくなった。
何より脆弱性の心配がかなり少ない。WordPressはとにかく攻撃されやすいシステムだ。バージョンアップが頻繁にあり、プラグインが追従できなくてぶっ壊れたりする。バージョンアップを怠った結果として乗っ取られることもよく聞く。その不安から解消されている。
改造・カスタマイズをするときに、手元で hugo server
コマンドを打てばHTTPサーバーが起動するのもとても便利だ。WordPressでは開発環境=動作確認環境を用意するのが非常に面倒で、DockerコンテナでWordPressを立ち上げ、さらに本番のデータベースからデータをdumpしたものをそのDockerコンテナに入れて開発をしていたりする。仕事ではそのくらい頑張って開発するわけだが、個人サイトだと面倒なので直接本番サイトを弄ってしまったりする。その結果、上述のようにバグの原因を生み出すわけだ。開発環境整備の手間、バグのリスクから解放されている。
スケーラビリティ
WordPressは極端にいえばオリジンサーバーは1台のみが許されたアーキテクチャだ。スケジューラーの仕組みだとか、管理画面の仕組みだとかのせいで、複数台での動作は怪しくなる。私は仕事の方のWordPressにて、パフォーマンスと可用性を両立するのになかなか苦労している。
Jamstack、Hugoは、理論上はいくらでもスケールする。静的コンテンツなのでとにかくCDNに載せてしまえば良いのだ。このブログはCloudflare Pagesにホストしている。つまり、最初からCDNの上に乗っており、スケーラビリティとパフォーマンスの面でWordPressと比較にならない状態になっている。
問題があるとすれば、このブログはそんな心配が必要なほどアクセスがないことだろう。
コスト
スケーラビリティに関係する話だが、オリジンのサーバーが不要になるのはコスト面で有利だ。
私は過去にさまざまなホスティングサービスでWordPressを運用してきたが、月1000円以下の安いところはサービス終了することが多い印象だ。 とある会社は年会費制だったにも関わらず途中でサービス終了して、問い合わせても金を返してくれなくて、数千円損したこともある。そんな会社は置いておくとしても、 低コスト系ホスティングサービスだとパフォーマンス面でも心許ないことが多い。
一方でJamstackのホスティングサービスは、全体的に安くて(というより個人レベルなら無料で)高性能なサービスが多い。将来的にもきっと安いだろう。脆弱になりにくいことの副次的な恩恵と考えられる。とにかくCDNに載せてしまえばスケールするのは強い。
WordPressと比較して、Hugoのデメリット
メリットがあればデメリットもある。
便利なプラグインがない
WordPressはやっぱ偉大だった。ユーザー数がとてつもなく多いので、欲しい機能があれば大体プラグインになっている。何かハマっても、ググれば回答が得られる。
Hugoではshortcodeを駆使して他者の実装を取り込んでいくことになる。取り込みなので、うまく動作しないこともある。いわゆるおま環だ。この辺、対応するにはちと知識が問われる。更にWordPressと違って同じハマり方をしている人の数は圧倒的に少なく、情報は乏しい。
他者の実装をインストールするのではなく、リポジトリのコードに取り込んでいくスタイルは、どことなくGo言語の開発に似ている。
データストアがない
WordPressにおけるDBの存在は、リスクでもあるが、メリットでもあった。HugoというかJamstackでは、コメント欄はおろか絶滅危惧種のアクセスカウンターすら作れない。もし更新の発生するコンテンツを扱いたければ、それ用のサービスを契約してAPI経由で利用することになる。これはインターネット初期にあった「BBSを契約する」ような感覚にも近い。
もっとも、記事上のコメント欄は大抵、自己主張の激しい人かbotに荒らされるものであり、真っ当なコメントはTwitterやらFacebookに流れている時代である。このブログでは割り切って無くしてしまった。
テンプレートの癖は強め
Goのtemplate記法に則っているので、なかなかに癖が強い。特にif文とか。とても多機能ではあるのだが。
ただ、癖は強いが、開発にあたってGo言語のプログラマーである必要はない。雰囲気でなんとかなるし、ググればコミュニティがやりたいことを助けてくれる。
非エンジニアへの説明は厄介そう
Hugoを運用するなら、最低限markdown記法は知っていてほしい。
その上で、TOML、YAML、JSONをそれぞれ読めるようになっていたほうが良い。なぜなら、Hugoはどれも使えるし混在していてもOKだからだ。何か凝ったことをしようとしたときに、ドキュメントや実装例や解説記事で説明されるものは、この3記法どれで書かれているかは筆者の好み次第になっている。しかも時々記法のパースエラーにも引っかかる(ダブルクォートとシングルクォートとかはあるある)ので、最低限の知識は要る。
さらにgitの知識は問われる。最低限、PullとCommitとPush、チーム開発・運用ならPull Requestができないと話にならない。
加えて、Push前に整合性エラーがないことを確認したければ、手元でHugoを動かす知識も問われる。HugoはGo製なので、幸いにもWindowsでも動作できることはありがたいのだが。
まとめ
結論として、このサイトにおいては移行は正解だったように思う。プラグインインストールという仕組みが無いことで、コードを自分で書くことがとにかく多いのだが、それもまた楽しい。ビルドがあることで整合性の担保が保たれてるのも良い。Cloudflareの力で、デプロイしたサイトは異常に速いことにも驚かされる。
一方でWordPressの良さの再認識をしたのも事実だ。インターネットの大半のサイトを作っている技術というのは伊達じゃない。ノーコードでもそれなりのサイトに仕上げられるのは、やっぱWordPressの方だろう。
Jamstack、Hugoを手放しで称賛する気はない。得手不得手を弁えて技術選択するのが良い、というのが、至極あたりまえながら大事なことだと思う。
私の場合は、WordPressのときに感じていた「プラグインの挙動を直したい」→「改造するとアップグレードが不便になる」→「アップグレードを止めると脆弱性が不安」という、もどかしい3連鎖を解決できたことがかなり嬉しい。加えて、改造の途中で動作確認しやすい hugo server
コマンドの存在も大きかった。
本サイトは、ゆっくりとHugoへの移植作業をしていこうと思っていたのだが、開発が楽しくて1週間程度で移植を終えてしまった。おかげでまだwpXの契約がたっぷり残っている。この『作るのが楽しい』という感覚、WordPressではあまり味合わなかった感覚だけに、Hugoの特徴を端的に表していると思う。