インサイド Misskey Hub
この記事は、Misskey Advent Calendar 2021 1日目の記事です。
こんにちはsyuiloです。いつもMisskeyを利用してくださってありがとうございます。開発の励みになります!
2021年は、misskey.ioのデータベースが破壊されて貴重なノートが多数失われるなどの心を痛めるインシデントもありましたが、Misskeyの開発は順調に進んでいます。また、RSS3がMisskeyのスポンサーになってくださったことや、Patreonでの支援が増えてきたこともあり、おそらく財政的にはMisskey史上最も余裕が出てきていると思います。なので今後もMisskeyの開発は滞りなく進められそうです。:iihanashi:
さて現在、Misskeyの開発と並行して、Misskeyの公式ドキュメントサイトであるMisskey Hub(つまりあなたが今いるここ!!!)の開発も進めています。 なぜMisskey Hubを作ったかというと、色々ありますが主に
- プロジェクトとしての公式サイトが無いのは不便
- Misskeyのドキュメントを見るためには実際に動いている何らかのインスタンスにアクセスしなければならない
- 文字通りHubとなり、インスタンスを跨いで共有されるような情報(インスタンス一覧、プラグインなど)も管理したい
- ドキュメントをレンダリングしたり検索したりする機能をMisskey本体に実装するのが面倒
といった理由です。
今回は、そのMisskey Hubの実装詳細について紹介しようと思うので、少しの間お付き合いください。多少専門的になるかもしれませんが、なるべく分かりやすくなるように心がけます。
Misskey Hubの実装について理解するためには、いくつかの前提知識が必要となるので、まずそれらの説明をします。ひとつめは静的サイトについて、ふたつめはSSGについてです。それでは始めましょう🚀
静的サイト is 何
性的サイトと誤変換しやすいので注意
こういった記事がメインのWebサイトは、一般的にはWordpressなどのソフトウェアを使って管理することが多いですが、Misskey Hubはそうではありません。
Misskey Hubは、Misskey Hub内のMisskey Hub説明ページにもあるように、vuepressを使った静的サイト(Static site)です。
静的サイトとは、トートロジーっぽい表現になりますが動的でないサイトのことです。動的なサイトというのは、例えばユーザー登録が行えてユーザーがコンテンツを投稿できたり、コメントを残せたり、とにかく「ユーザーから何らかのインタラクションを行えて、それがそのサイトを見る他のユーザーにも反映される」ようなサイトのことです。より雑に言うと常に内容が変化するサイトのことです。究極的に雑に言うと動的サイトがワイワイしたサイトで静的サイトがシーンとしたサイトです。
もちろんMisskeyは動的サイトということになります。なぜかというと、例えばそこにはタイムラインがあって、訪れるたびにタイムラインの内容は変わりますし、タイムラインを見るユーザーによっても内容が変わります(フォローしているユーザーが異なるため)。
静的なサイトは逆に、そういったリッチなことは行わず、予め用意したコンテンツをどのユーザーに対しても同じように表示するだけのサイトです。Misskey Hubは(サイト更新を除けば)誰がいつ見ても同じ内容なので、静的サイトです。
技術的な話になりますが、静的と言っても、静的なのは「サーバーから」送られてくる内容だけであって、JavaScriptを使ってブラウザ上で動的にページの内容を変えることは可能です。
例えばMisskey Hubでは、サイドバーに表示されるMisskeyや藍ちゃんの広告はページを訪れるたびにランダムで変わるようになっています。
さらに言うと、静的サイト内に別の動的サイトを埋め込んで表示することも可能です。これを利用して、将来的にはそのページに対するMisskeyのコメントタイムラインをページに表示する、といったことも実装されるかもしれません。
静的サイトだと何が嬉しいのか
ここで、静的サイトには動的サイトには無い、とても嬉しいメリットがあります。もったいぶるようですが、この記事の中でもおそらく一番重要なポイントです。刮目してください。それは...
サーバーを用意する必要がない
ということです。
もちろん静的といえどもウェブサイトなので、実際にはサーバーが存在しています。しかし、静的サイトは予め内容が決まっていて、どのユーザーが見ても内容は同じであることから、サイトを提供する際に動的サイトに比べてサーバーの負荷がほとんどかからないのに加えて、全てのページ内容をキャッシュすることが可能です。
サイトをキャッシュできると、CDN(Content Delivery Network)と呼ばれるインフラストラクチャ上にサイトのコンテンツを載せることができ、そもそも元のサーバーにリクエストが来る必要がなくなります。そう考えるとサーバーの負荷はゼロと言っても過言ではありません。
負荷がほとんどかからないことから、Misskeyや Misskey Hubがソースコードの管理に利用しているGitHubでは静的サイトを提供するための環境を無料で開発者に提供しています(GitHub Pages)。 そのため、Misskey Hubを静的サイトとすることで、「サーバーを用意して、毎月料金を払って維持する」という必要がなくなります。しかも、GitHubの強力なインフラの上にサイトが構築されるので、DDoSといった障害の心配とも無縁です。
動的サイトを運営する際に発生するそのような諸々の心配から解放されるというのは非常に大きなメリットです。つまり、金銭面においても精神面においても、ゼロコストでMisskey Hubを運用できます。
さらに技術的な話(危険)
ここまで言っておいてなんですが、先ほど言った
もちろんMisskeyは動的サイトということになります。
というのは 嘘 です。説明を簡単にするために、また理解してもらいやすくするために嘘をつきました。ここまで読んで混乱してしまった人は、このセクションをスキップしてなかったことにしてください。
実は、厳密に言うとMisskey(のWebクライアント)は静的サイトなんです。
どういうことかというと、Misskey Webは、全てJavaScriptで動いています。そしてそのJavaScriptは不変です。 MisskeyのWebサーバーは、その不変なJavaScriptを送り返すだけで、動的なHTMLをレンダリングしたりはしないので、Misskey Webは静的です。 なので、あなたがMisskey Webを開いた瞬間は、(CDNが設定されている場合)Misskeyサーバーにリクエストはひとつも来ません。 もちろんJavaScriptが動きだしたら、アカウント情報を取得したり、タイムラインを取得したりするのでリクエストは発生します。 静的なJavaScript上で動的なコンテンツが実現されているということです。 実際、インスタンスサーバーがトラブルなどで落ちていても、クライアントにはアクセスすることができますし、テーマの設定などサーバーに依存しない操作は普通に行うことができます。
ちなみに、こういう構成のことをIT界ではサーバーレスと呼んだりするっぽいです。知らんけど。
SSG is 何
ここまでは静的サイトとは何か、について話しました。ここからは、そんな静的サイトを開発するのに便利なSSGについて紹介します。
おそらくほとんどの人は見慣れない言葉だと思いますが、SSGとは、静的サイトジェネレーター(Static Site Generator)の略で、その名の通り静的サイトを生成するソフトウェアです。
静的サイトを作るだけならば、HTMLやCSSを手で書いてアップロードするだけでも良いのですが、コンテンツの量が多くなってくると管理が大変になるのと、そもそもHTMLという非ヒューマンフレンドリーなマークアップでドキュメントを書きたくないというのがあります。
そこでSSGが登場します。SSGを利用することで、Markdownと呼ばれるより人間に書きやすいマークアップでドキュメントを記述できるようになるほか、特に何も書かなくても自動で良い感じ™のデザインでページを表示してくれたりします。さらに、人力では実装が難しいサイト内検索なども提供してくれます。
もちろん実際のサーバー(というよりブラウザ)はHTMLしか解釈できませんので、SSGはサーバーにファイルをアップロードする前にコンパイルという処理を行なって、MarkdownをHTMLに変換します。
SSGは特定のソフトウェアを指すものではなく、概念を表す言葉です。したがって、複数のSSG実装が存在します。Misskey Hubでは、前述のように vuepress というSSGを採用しています。
vuepress is 何
ここまではSSGについて話しました。ここからやっと、Misskey Hubの実装の話に入ることができます。
vuepressは、UIフレームワークにVueを採用したSSGです。Misskey Hubはvuepressのv2(2021年11月現在ベータ版)を使用しています。 Vueについては、vuepressがあまりそれを意識しないでも使える設計になっているためこの記事では割愛します。
Misskey HubがSSGにvuepressを採用した理由は、技術スタックがモダンでMisskeyのそれと一致していることや、使いやすさや拡張性で優れていると思ったためです。 さらに、他のSSGは何かしら欠点があったのに対し、vuepressにはそういった欠点は(SSGの中でもかなり新しい方であるため、まだ後述するプラグインやテーマが少ないというのを除けば)ありませんでした。 ただ、他のSSGを使い込んで吟味はしていないので、拡張性などに関しては比較ではありません。
テーマ
Misskey Hubのデザインは、vuepress標準で用意されているテーマを少しMisskey風にアレンジしたものになっています。ゼロから実装するのは大変ですしメンテナンスするコストも発生してきますが、アレンジなので運用が楽です。もちろんダークモードにも対応しています。 Misskeyと同じく、vuepressもCSS Variablesを使って簡単に配色を変更できるようになっています。
プラグイン
vuepressはプラグイン機能があり、開発者が自由にvuepressを拡張できるようになっています。 プラグインを駆使することで、また時には自分でプラグインを作成することで、静的サイトながら動的サイトに見紛うようなリッチな機能を提供することができたりします。
Misskey Hubもプラグイン機能を使っていて、「関連するページ」「最近更新されたページ」といった独自の機能を持たせています。
「関連するページ」については、各ページで自身と関連するページを手動で指定できるようになっているほか、ページ中で使われたリンクを収集&自身にリンクしている他ページを収集して「関連するページ」にリストアップするようにしています。
また、「最近更新されたページ」についても、Misskey Hubオリジナルの実装で実現していて、コンパイル時に全てのページファイルを収集してそれぞれの更新日時を後述するGitで取得し、新しい順に並べ替え、ページとしてレンダリングするようにしています。
さらに、MFMを実際に書いて試せるプレイグラウンド機能や、APIリファレンスにおけるAPIコンソールなども今後実装予定です。
「関連するページ」「最近更新されたページ」は我ながら便利機能だと思っているので、Misskey Hub以外のvuepressを採用したサイトでも使えるようにnpmで一般公開しようかとも考えています。
多言語対応(i18n)
多言語対応することはi18n(Internationalizationの略)と呼ばれます。vuepressには標準でi18n対応が組み込まれているので、Misskey Hubも簡単にi18nすることができました。
サイト内検索
vuepress標準の機能で、右上にあるやつです。各ページの見出しを対象にして検索されるようです。これをSSGの助けなしに実装するのは厳しいと思います。
目次生成
自動で目次を生成してくれます。(ページ左)
こんな感じでページ内に埋め込むこともできます:
HMR
HMR(Hot Module Replacementの略)は、開発中に使われる機能で、ブラウザをリロードすることなしにページ内容の変更を反映してくれます。エディタで編集し、保存するだけでリアルタイムでページに反映されるので、開発がとても快適になります。
藍モード
もちろん藍モードも搭載しています。藍モードを有効にすることで藍ちゃんをサイト上に召喚することが可能です。スマホだとそれなりに邪魔ですがそれも含めてお楽しみください。藍は地球を救う
→→→Live2D藍ちゃん創造神←←←
ページ
各ページはMarkdown(MFMみたいなもの(いや本来はMFMが「Markdownのようなもの」という立ち位置だけれども))というマークアップ言語で書かれています。Markdownを使うことで、簡単に見出し、リンク、画像、表といった要素を表現できるほか、
こんな
感じの
メッセージ
を表示したりできます。(厳密にはMarkdownの拡張構文)
また、vuepressの機能により、各見出し(ヘッダ)にハッシュリンクが付くようになっています。
このページのMarkdownソースを見たい方はこちら
参考までに、同じ文章をMarkdownとHTMLとで書いた場合の比較を載せます。
## 静的サイト is 何
Misskey Hub内のMisskey Hub説明ページにもあるように、Misskey Hubは[vuepress](https://v2.vuepress.vuejs.org/)を使った**静的サイト**(Static site)です。
<h2>静的サイト is 何</h2>
<p>Misskey Hub内のMisskey Hub説明ページにもあるように、Misskey Hubは<a href="https://v2.vuepress.vuejs.org/" target="_blank">vuepress</a>を使った<strong>静的サイト</strong>(Static site)です。</p>
インスタンス一覧
「プラグイン」のセクションでも触れましたが、vuepressでは、Markdownで書かれたページ以外にも、プログラムで(コンパイル時に)生成するページを用意することができます。
「インスタンス一覧」ページもその一つで、予めインスタンス一覧の情報をJSONという形式で用意しておき、それを基にしてインスタンス一覧ページをレンダリングするようになっています。
各インスタンス紹介は、インスタンス側で用意されたプロフィールレンダリングページをiframeというHTMLの機能で埋め込んで表示するようになっています。したがって、一度Misskey Hubにインスタンスを登録してしまえば、インスタンスの名前、説明、バナー画像といった情報を更新した場合でもリアルタイムでインスタンス一覧に反映されます。
インスタンス一覧へ掲載するインスタンスを募集しています。お気軽にご連絡ください🤗
管理
Misskey HubはMisskeyと同じく、GitHub(Git)上で管理しています。
Gitで管理することで、全ての変更についての履歴がリポジトリに保存され、簡単に過去の版を参照したり、変更を差し戻したりすることができます。
リポジトリに内容の変更(新規ページの作成も含む)を適用することはコミットと呼ばれます。
そのためMisskey Hub内の各Markdownページは、Wordpressなどとは違って、データベースなどではなくそのままファイルとして管理されます。
デプロイについて
サイトの内容を実際のサーバーにアップロードし反映させることをデプロイと呼びます。
Misskey Hubにおいては、GitHub ActionsというGitHubの機能を利用して、サイトの内容に変更を加えると(リポジトリにコミットを行うと)自動でコンパイル & GitHub Pagesデプロイが行われる仕組みになっています。
GitHub Pagesは前述した「静的サイトを提供してくれる機能」です。GitHubのインフラストラクチャ上で動くため、いちどデプロイしてしまえば、あとは何の心配もなくMisskey Hubが提供され続けます。
「何の心配もなく」はちょっと言い過ぎたかもしれません。というのも、(強いていうと)ひとつだけ心配があって、それはドメインです。Misskey Hubはmisskey-hub.netというドメインで提供されていますが、これは私が用意したものです。そのため、もし万が一私がドメインの更新を忘れるとMisskey Hubに繋がらなくなりますが、そこは𝑇𝑟𝑢𝑠𝑡 𝑚𝑒
通常のWebサイトであれば、サーバーにFTPでファイルをアップロードしたり、サーバーにSSHで繋いでファイルをダウンロードしてきたりといった作業が必要になりますが、GitHub Pagesではそのような手間すら要りません。
デプロイを終えると、Misskey Hubがインターネット上に公開されてWebブラウザで見ることができるようになります。めでたし!
さいごに
Misskey Hubは、Misskeyと同じくオープンソースであり、貢献はいつでも歓迎しています。まだまだ不足しているドキュメントも多いので、ぜひドキュメント拡充にご協力お願いします。インスタンスを運営してきた上で得られたナレッジなどをアウトプットする場としてもMisskey Hubを利用していただけると幸いです。また、Misskey Hubもi18nしており、ドキュメントの翻訳も歓迎です。
この記事で、Misskey Hubの実装、ひいては静的サイトとは何か、SSGとは何かを何となくでも理解していただけたなら、また利用するだけではなかなか知ることがない開発の裏側について思いを馳せていただけたなら、幸いです。
SSGはMisskey Hubのようなドキュメントサイトだけでなく、ブログなどにも使えるので、皆さんもぜひ活用してみてください。 実際、この記事のようにMisskey Hubを開発ブログとしても使用しています。 多少知識は要りますが、ゼロコストでブログ運営できるのでチャレンジする価値はあるはずです。(無料でブログ運営できるサービスはあるけど、広告が付いてくる)
さて、ここまで一気呵成に書き上げて:hinata_acid:になってきたので、今回はここら辺で終わりにします。お付き合いいただきありがとうございました。
この記事が参考になったり、面白かったりしたらぜひMisskeyでシェアお願いします!!!
静的サイトはいいぞ。vuepressはいいぞ。Misskey Hubに幸あれ🙏
Webで記事を公開する際に必ず記述しなければならないと法令で定められている言葉
いかがでしたか?
もしMisskeyが少しでもあなたの生活を豊かにしていると感じたら、ぜひ開発に対してPatreonで寄付することをご検討お願いします。喜びます。
P.S.
藍ちゃんとツーショット撮ったので見て!!!! うぇへひひ
P.S. (2)
ニラはいいぞ。
栄養があるし、加熱不要で調理も楽(ハサミで切って味噌に突っ込んでチンするだけで味噌汁できる)
ただし加熱しないと風味が強すぎ、ちょっとしたワサビ食べてるみたいになるので多少訓練が必要