2020年Misskeyの旅 (2020: A Misskey Odyssey)

これは[Misskey Advent Calendar 2020](https://adventar.org/calendars/5026)、5日目の記事です。ここまで、Botの話、AiScriptの話、鯖の話など、盛りだくさんでしたね。私も負けないような記事を書いていきたいです(お手柔らかにお願いします！！！)。ということで改めまして…

こんにちは、Misskeyプロジェクトリーダーの**しゅいろ**です✌
2020年は私が就職したこともあり、Misskey開発に割ける時間がガクッと減ってしまったのですが、それでもMisskeyに大きくコミットすることができました。そのモチベーションはひとえにミスキストの皆様の応援や支援があったからだと思います。ありがとうございます🥰 (Misskeyを普段利用していただいているだけでも、私のやる気につながります)
2021年は安定性の強化や各種機能のブラッシュアップ、ドキュメントの拡充を進める所存ですので引き続き応援よろしくお願いします🤲

さて、2020年の更新内容として具体的には、パッと思いつくものだとUIフレームワークのVue3移行や、UI刷新などがあります。
この記事ではそれらひとつひとつを振り返り、詳しく紹介していく... と思ったのですが、ちょっと時間がギリギリになってしまったのと、**リリースノートが雑で何をしたのか細かく覚えていない**というのがあり、今回は視点を変えてMisskeyを支える各種技術やソフトウェアを、専門的な用語はなるべく避けて誰にでも分かりやすく紹介をしていこうと思います。
ちょっと駆け足気味になりますが、普段目にすることのないMisskeyの裏側について思いを馳せて(？)いただければと思います。
それではどうぞ→

## 全般
Misskeyで全体的に使用している技術の紹介です。

### JavaScript
専門性: ⭐
Webページ上やサーバー上で動くプログラミング言語。Misskeyは、クライアントもサーバーもJavaScriptで動いています。
ただし、これから紹介しますが実際にはTypeScriptという別の言語で書かれた後、それをJavaScriptに変換してから動かしています。
JavaScriptはMisskeyが動作する上で基本となる、いわば心臓のような役割で、ボタンを押してダイアログが出るのも、ノートが投稿できるのも、音が鳴るのも全てJavaScriptでプログラミングされているおかげです。
ちなみに別にJavaという言語がありますが、JavaScriptとは何の関係もないのは有名な話です。

### TypeScript
専門性: ⭐⭐
上記のJavaScriptの「使いにくさ」を克服したプログラミング言語で、JavaScriptの進化系と考えると分かりやすいかもしれません。
何故TypeScriptを使うのかというと、JavaScriptには「型」というプログラミングをする上で便利な概念があまり考慮されておらず、JavaScriptで複雑なプログラムを書くのは開発者の負担になるためです。
MisskeyはクライアントもサーバーもこのTypeScriptでプログラミングされています。ただ、先述したように最終的にはJavaScriptに(自動で)変換されて実行されます。
なぜわざわざJavaScriptに変換するのかというと、サーバーやWebブラウザはJavaScriptにしか対応していないためです。

### AiScript
専門性: ⭐⭐⭐
私とまりはち氏が共同開発したプログラミング言語で、Misskeyに組み込まれています。AiScriptを使うことでステートフルなPageを作ったりすることができます。
Misskey上のAiScriptはJavaScript(TypeScript)で実装されています。そのJavaScriptはC++といった言語で実装されています。つまりAiScriptはプログラミング言語の上で動くプログラミング言語の上で動くプログラミング言語です。
なぜ新しい言語を作ったのかというと、例えばユーザーが書いたJavaScriptコードをそのまま実行できるようにしてしまうと、様々なセキュリティ上の問題が発生するためです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81958/da98cdde-03f1-2d0a-23d8-b4ad2282e542.png)
イラスト: みなしま氏

### Websocket
専門性: ⭐⭐
サーバーとクライアント間のリアルタイムな情報のやり取りに利用している技術。
例えば、ノートがリアルタイムでタイムラインに流れたり、リアルタイムでリアクションが付いたりというのはWebsocketのおかげです。他にも、リバーシなんかはリアルタイム性をフルに活用していますよね。
もしWebsocketが無かったとすると、非効率な方法で無理やりリアルタイム通信を実現(ポーリング等と呼ばれます)するか、ページを手動でリロードしない限り最新情報が反映されないWebサービスになってしまいます。
ちなみにMisskey v10からこのWebsocket接続をひとつに束ねる仕組みが実装され、複数のタイムラインを表示したりしていてもより効率よく通信できるようになりました。
また、Misskeyを利用している方なら、「サーバーから切断されました」という表示を一度は見たことがあるかと思います。これはこのWebsocket接続が切断されたことを意味しています。切断される原因は様々ですが、主な原因としてはサーバーの再起動があります。

### Git
専門性: ⭐
Misskeyのソースコード(プログラム)を管理するために使用しているソフトウェア。Gitを使うことで、例えば間違った変更をしてしまっても過去の状態に戻すことが出来たり、複数人で開発するときに競合が起きないようにするなど、開発のし易さを上げることができます。
Misskeyをしていると、「コミット」、「ブランチ」、「PR(Pull Request)」などの言葉を目にする機会があるかもしれませんが、これらはこのGitの用語です。

### GitHub
専門性: ⭐
上述のGitをホスティングしてくれるサービス。Misskeyのソースコードはこのサービス上で公開されており、URLは https://github.com/syuilo/misskey です。
Gitのホスティングだけではなく、Issueといった機能も提供されており、日々GitHub上で開発者同士の活発な議論が交わされています。
(もしGitHubのアカウントをお持ちの方は、ぜひStarしていただけると開発の励みになります🤩)

## クライアント
MisskeyのWebブラウザ上で動くクライアントで使用している技術の紹介です。

### HTML
専門性: ⭐
Webページを構築するためのマークアップ言語。コンピューターに命令するための言語という点では、プログラミング言語と似ています。
MisskeyクライアントはHTMLと次に紹介するCSS、そして上述のJavaScriptが組み合わさることで動いています。
HTMLはWebページを作る上で基本となる技術のため、もしかしたら皆さんの中に触ったことのある方もいるかもしれませんね。

### CSS
専門性: ⭐
Webページをデザインするためのマークアップ言語。上述のHTMLでWebページの骨組みを作り、CSSで見た目を定義します。
例えば、HTMLで「ここにボタンを設置するよ」と定義して、CSSでは「このボタンはこんな形でこんな色だよ」と定義することで、ボタンのあるWebページが出来上がります。
CSSは見た目を司るので、デザイナー(≒私)の腕の見せ所でもあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81958/84786b3c-a382-f99c-b7be-96700de503af.png)
イラスト: いらすとや、ほくたか氏

### SCSS
専門性: ⭐⭐️
JavaScriptを書かずにTypeScriptを使うのと同様、CSSには不便な点が多いためSCSSという別の言語で書いた後CSSに変換しています。

### Pug
専門性: ⭐⭐️
CSSを書かずにSCSSを使うのと同様、HTMLには不便な点が多いためPugという別の言語で書いた後HTMLに変換しています。ただし、いろいろな理由によりPugを使っている箇所は他と比べると少ないです。

### Vue
専門性: ⭐⭐️
MisskeyクライアントではVue(ビューと発音)と呼ばれるUIフレームワークを採用しています。UIフレームワークとは、説明が難しいですが上述のHTMLやCSSをデータに応じて自動で組み立ててくれるプログラムです。Misskeyクライアントの中枢であり、クライアントで最も重要な技術です。
Misskeyは最初からフレームワークを使っていたわけではなく、最初は素のJavaScriptのみでクライアントが実装されていました。その後、Riotというフレームワークを採用し、最終的に現在のVueに落ち着きました。
2020年はこのVueのバージョンをアップデートする(大変な)作業を行い、パフォーマンスの向上を実現しました。
ちなみにmisskey.ioに**EvanYouなんとかしろ**(`:evan_you_nantokashiro:`)というカスタム絵文字がありますが、Evan YouはこのVueの作者です。このカスタム絵文字はVueにバグがあったときに、「なんとかしてくれ」という思いを込めて使われることが多いですね。

### Webpack
専門性: ⭐⭐⭐
プログラミングする上では、複数のファイルにプログラムを分けて書いていきます。ただ、Webブラウザは複数に分かれたプログラムを扱えないため、複数のプログラムを一つのファイルにまとめる(バンドルする)ためにWebpackというソフトウェアを使っています。
Webpackはプログラムをまとめる以外にも、不要なコードを削除してくれたり、プログラムを必要になったときにだけ読み込んでくれたりなど、様々な便利な機能を提供しています。
このおかげで、例えばMisskeyではリバーシのゲームが遊べますが、実際にリバーシのページにアクセスしない限りは、リバーシのプログラムコードがダウンロードされることはありません。新機能を追加しても、その機能を実際に使わないユーザーにとっては影響が及ばないようにでき、所謂ｷﾞｶﾞが節約できます💪
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81958/80f3d74a-5e9c-41e0-98be-f5711dbaa3b9.png)
イラスト: みなしま氏

ちなみに、昔はbrowserifyという別のソフトウェアをバンドルのために使用していました。しかし、webpackの方が上述のようにより高機能であり、トレンドになると感じたため移行しました。

## サーバー
Misskeyのサーバーで使用している技術の紹介です。

### Node.js
専門性: ⭐⭐
上述のJavaScriptをサーバー上で動かすために必要なソフトウェア。
JavaScriptが最も使われている用途はWeb上で動的なページを実現するためですが、JavaScript自体は汎用的なプログラミング言語なのでWebブラウザ以外でも動きます。例として、Misskeyのようにサーバー上で動かす場合もあれば、AfterEffects(動画編集ソフト)のように組み込みのマクロとして使えるケースもあります。

### npm
専門性: ⭐⭐
パッケージマネージャーと呼ばれるもの。Misskeyくらいの規模のソフトウェアになると、全てのコードをそのソフトウェアの開発者が書くのは困難です。そこで、他のソフトウェアと共通するような部分は、第三者が書いたプログラム(パッケージや、ライブラリと呼んだりします)を利用して実装することになります。上述のVueもパッケージの一種です。
パッケージマネージャーは、このソフトウェア(ここでいうMisskey)がどんな他のパッケージを利用するかという情報をもとに、実際にそのパッケージをインストールしたりする役目を持ちます。このように、パッケージをマネージすることから、パッケージマネージャーと呼ばれます。
ちなみにこのnpmは最近上述のGitHubに買収されたことで話題になりました。また、そのGitHubは最近マイクロソフトに買収されました。

### PostgreSQL
専門性: ⭐⭐
Misskeyの様々なデータ(ユーザー、ノートなど)を保存するためのデータベース。昔はMongoDBという別のデータベースを使っていました(さらに昔はMySQL)が、最近PostgreSQLに移行しました。
移行した理由についてはこちら: https://www.patreon.com/posts/misskey-v11-soon-25503492
サーバー内部で、このデータベースに対してクエリと呼ばれる命令を送信することで、投稿されたノートを保存したり、ノートを読み込んでタイムラインを取得したりします。
また、Misskeyのシステム上で最も負荷がかかる部分です。
人間で例えるなら、脳... というよりは、記憶を司ると言われている海馬でしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81958/a75d5b69-5968-0b9b-5a06-6b9b45c3ed2e.png)
イラスト: ほくたか氏

### Redis
専門性: ⭐⭐
Redisもデータベース。PostgreSQLと違って一時的なデータ保管やリアルタイムな情報のやりとりに使用しています。

### TypeORM
専門性: ⭐⭐⭐
上述のPostgreSQLをプログラムから扱いやすくするようにするライブラリ。

### Bull
専門性: ⭐⭐⭐
「ジョブキュー」という役目を果たすライブラリ。例えばMisskeyは分散型のシステムなので、ノートを投稿すると複数のサーバーと通信して、ノートを「連合」します。その際、相手のサーバーの状態によっては通信が失敗したり、そもそも数が多すぎて一度に通信するのは負荷がかかりすぎて難しい場合があります。その際、少しずつ通信を行うようにしたり、通信が失敗しても後で再度通信を試みたりなどの処理を担当してくれるのがジョブキューです。

### Koa
専門性: ⭐⭐⭐
上述のNode.js上でWebサーバーを簡単に実装できるようにしてくれるライブラリ。

# おわりに
どの技術も、普段Misskeyを利用していても意識することは無いと思います。そういう意味ではすべて縁の下の力持ち的な存在です。また、他にも紹介しきれなかったソフトウェアや技術もいくつかあります。

この記事を読んで、Misskeyの裏側やそれを支えるこれらの技術について興味を持っていただけたのなら幸いです。
以上、ご清聴ありがとうございました🙏

Happy Misskeying!