すしのへや

thumbnail of tech/look-back-2023

2023年を​振り返る

Advent Calendar 遅刻杯 優勝
18 min to read

この記事はUEC2 Advent Calendar 2023の10日目の記事です。

公開日が12/31なのは気のせいです。多分。

こんにちは、すし(@sushi_chan_sub)です。

12/10に記事を投稿するはずが、スケジュール管理不足で完全に崩壊しました。大変ご迷惑をおかけしました。

2023年は、最もたくさん新しいことに挑戦して、たくさん作った年でした。せっかくなので振り返りがてらいろいろ紹介しようと思います。

初TypeScript, 初Contribution

私は原神というオープンワールドゲームが大好きで、2022年の1月に始めて以来ずっとハマり続けています。 そんな原神には、公式コミュニティである「HoyoLab」というサイトがあります。

このWebサイトの特定ページを1日1回見るとログインボーナスが入手できるのですが、毎日わざわざ見るのは面倒ですよね。 世には同じことを考える者がたくさんいるということで、既に毎日特定の時間にそのページを開くためのChrome拡張機能が存在していました。

私も例によってこの拡張機能に助けられていたのですが、日本語に対応していないことが気になっていました。

そして時は2023年1月。近い将来にTypeScriptを書く予定があり、また小さくてもいいから他の方が作ったものにContributionしてみたいと思いがあった私は、思い切って日本語対応をやってみることにしました。

今見返すと、汚い上に、Issueすら出さずにいきなりPR出してて最悪ですね。本当に最悪

これを自分で言うとよくないですが、初めてのことをやると上手くいかないものですね。 そんな半分呪物のようなコードでも、マージされたときは少し嬉しかったのを覚えています。1

Web制作を始めた

2023年3月に公開された調布祭実行委員会の新歓Webサイトを作ったことがきっかけでWeb系の制作を始めました。 最初はHTMLの属性や最低限のCSSすらよく分からない状態でしたが、根気よく調べていくうちに少しずつ作りたい!を形にできることが増えてきました。

結果的に今年1番制作したジャンルはWebかもしれない。手軽にあらゆるデバイスに向けて自己表現できるというのは自分にとって大きな魅力です。

調布祭実行委員会新歓Webサイト

3月に制作した初めてのWebサイトです。

Next.js(Pages Router) + Tailwind CSSで作りました。 今見ると、コンポーネントの分割が甘かったりUIに統一感がなかったり、表示順の制御が上手くできていなかったり、欠点がたくさん見えますね。

それでも初めてありとあらゆるブラウザから見られるものを作れたことは嬉しかったです。

初代個人サイト

6月頃〜9月頃まで運用していた初代個人サイトです。

Next.js(App Router) + SCSSで作りました。 後に作る調布祭Webサイトの準備として、App Routerに慣れておくために作りました。

最初に公開してから少しずつ機能の追加やリファクタリングを繰り返し、最後に止める頃にはかなり肥大化していまいました。 また、MDXを扱うためのライブラリをフルスクラッチで作ったりもしました。

それなりに便利で、ブログの書き味も良くなったのですが、奇しくも旧サイトの運用停止の決め手になったのもこの自作ライブラリでした。

第73回調布祭Webサイト

9〜11月にかけてNext.js(App Router) + SCSSで作りました。 詳しいことは別のAdvent Calendarで書いたのでこちらを読んでください。

2代目個人サイト

旧個人サイトが肥大化し、またブログメインのサイトにNext.jsは過剰であると感じたので10〜11月頃にかけてゼロから書き直しました。

Astro + TailwindCSSで作りました。一部の複雑なスタイルやグローバルなスタイルはSCSSで書いています。 また、tailwind-variantsを導入しました。おそらく今後TailwindCSSを使う際に頻繁に使用されるのではと思います。

先程初代個人サイトの運用停止の決め手が自作MDXライブラリと書きましたが、これはAstroのContent Collectionが完全な上位互換だったからです。 魔改造を重ねた自作ライブラリには、特定ディレクトリ以下の探索+URL動的生成やフロントマターの検証も実装していましたが、すべてContent Collectionにビルトインされていました。

当然ひよっこが作ったものより完成度が高いので、このMDXブログ機能が大半だった旧サイトを止めて移行することを決めました。 また、Cloudflareなどのエッジ環境での動作をSSRも含めて完全サポートしていたのも魅力的な点でした。

以前よりも簡単にブログを維持できるようになり、書き直してよかったと思います。

また、この頃大学の先輩や後輩、はたまた音楽界隈のエンジニアのフォロワーの方などにリポジトリを見られていることが発覚したので、今までよりもっと気をつけながら書くようになりました。 人に参考として見られるのってなんだか嬉しいですよね。

Discord Botを改善したりライブラリを書いたりした

2年ほど前、私がプログラミングに足を踏み入れるきっかけになったのはDiscordのBot制作です。 2023年も縁あってBot制作を続けており、いくつかの団体で利用していただいています。 そんなBot制作では開発言語としてPythonを利用していますが、今年は基盤の設計を1から見直しました。

モジュールへの分割・統合においてWebフロントフレームワークに近い発想を取り入れたり、Linterの設定の見直しや大幅なリファクタリングを行ったりしました。 また、以前から進めていた型付けも完了し、かなり安全かつ補完の恩恵も受けやすい書き方ができるようになりました。

また、Discord Message Componentsと呼ばれる、ユーザーがBotに対して操作を行えるUIを構築するための機能の導入を進めました。 これにより、従来のテキストベースよりも直感的な操作ができるようになり、UXが向上します。

Discord Message Componentsのボタンなどを用いて構築されたUIの例 Discord Message Componentsを使ったUIの例

実際にBotを実装する際、Pythonではdiscord.pyと呼ばれるWrapper Libraryを利用するのが一般的です。 しかし、このライブラリではUIの処理を手続き的に書く必要があり、ユーザーの操作に伴って変化するUIの実装が苦行になる傾向がありました。

これを克服してユーザーに優しいUI・UXを実現しつつ効率よく実装するために、Reactのような宣言的UIを書けるライブラリを自作したりしました。 まだ差分検知などを実装していないのでやや過剰にAPIを叩いてしまうのが難点ですが、簡素に操作性の高いBotを書けるようになり満足しています。 将来的にはバリデーションなどの追加も視野に入れています。

個人的に一番作ってよかった仕様は、View内で別のViewを送ってユーザーの操作結果を取得する、という処理を非同期関数の呼び出しに帰結できるものです。 これによって、確認用ボタンを別に表示するなどの処理を簡単に書けるようになりました。

実装した​ライブラリの​使用例を​見る

Reactで簡単なカウンターを作成した例

Counter.tsx
const Counter = () => {
const [count, setCount] = useState(0);
return (
<div>
<span>count: {count}</span>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
<button onClick={() => setCount(0)}>reset</button>
</div>
);
};

Python製Discord Botに自作ライブラリを導入し、同じようなカウンターを作成した例

Discord側のメッセージへのUI反映は、Stateが変化すると自動的に行われます。

ただしこの変更などの実装はReactと大きく異なります。そのうちちゃんとReactのコードリーディングをしたいです。

counter.py
class Counter(View):
def __init__(self):
super().__init__()
self.count = State[int](0, self)
async def handle_increment(self, interaction: Interaction):
await interaction.response.defer()
self.count.set_state(lambda x: x + 1)
async def handle_decrement(self, interaction: Interaction):
await interaction.response.defer()
self.count.set_state(lambda x: x - 1)
async def handle_reset(self, interaction: Interaction):
await interaction.response.defer()
self.count.set_state(0)
def render(self) -> ViewObject:
return ViewObject(
content=f"count: {self.count.get_state()}"
components=[
Button(
label="+",
style=ButtonStyle.PRIMARY,
on_click=self.handle_increment,
),
Button(
label="-",
style=ButtonStyle.PRIMARY,
on_click=self.handle_decrement,
),
Button(
label="reset",
style=ButtonStyle.DANGER,
on_click=self.handle_reset,
),
],
)

このライブラリはGitHubで公開しているので、もしdiscord.pyを使ってDiscord Botを作っている方がいらっしゃったらぜひ使ってみてください。 IssueやPRもお待ちしております。

Cloudflareを使い倒す

今年最もお世話になり、また学んだプラットフォームです。

もともと個人でCDNとして利用しており、今年は一部大学団体にもCloudflareを導入しました。 キャッシュ機構が非常に強力で、正しく設定すればWebサイトのキャッシュヒット率が75%を超えることも珍しくありません。 調布祭のWebサイトを運用する際は大変助けられました。

また、TypeScriptがある程度書けるようになったので、Cloudflare WorkersやPages、KV、R2をフル活用できるようになりました。

WorkersやPagesは、CDN上で処理されるサーバーレスなコンピューティングサービスです。 Cloudflareのキャッシュ機構やS3互換ストレージのR2などにアクセスできるAPIも整備されており、 非常に簡素な設定で高機能かつ高速なAPI・Webサイトを構築できます。ちなみにこのサイトもCloudflare Pagesでホスティングしています。

他にも自分専用のAPIをいくつか運用しています。 たとえば定期的にツイートしている#NowPlayingのツイートは、楽曲urlを投げるとその楽曲の情報を返すAPIをCloudflare Workers上に実装しています。

Workersのようなエッジ上で実行できるものは日進月歩で増え続けており、今後もエッジコンピューティングの動向は追っていきたいと思っています。

Docker・GitHub Actionsをはじめる

今年は、去年までサーバーに直接載せていたコードをすべてDocker化し、可能な限りGitHub Actionsで自動デプロイを行うようにしました。 これによって、デプロイ先の変更などがあっても簡単に対応できるようになり、デプロイ時間の短縮にもつながりました。

また、この過程でDockerfileリファレンスとCompose Fileリファレンスをn回くらい穴が開くまで読んだので、Dockerfileを完全に理解※しました。 みなさんもDockerを触る時はリファレンスをよく読みましょう。

調布祭実行委員会のインフラ刷新

第73回調布祭実行委員会において、Webサイトの制作と技術インフラの刷新・管理を行いました。 Webサイトそのものの制作に関しては Web制作を始めた や Advent Calendarの記事に書いたのでここではそれ以外の話をします。

昨年までの調布祭Webサイトは、なんらかのフレームワークをビルドしたものを学内Webサーバーに手動デプロイする形で公開されていました。 今年は、よりヒューマンエラーが起こりにくく、かつ高速な環境の構築を目指してインフラの総入れ替えを行うことを決断しました。

また、2023年度入学の後輩が非常に優秀だったので、彼らが本来苦しまなくてよい部分に苦しまない基盤を整備しようという思いがありました。

分散していた利用サービスの集約と整理、VercelやCloudflareの導入、GitHubの本格利用、GitHub Actionsの導入など行ったことを書き出すとキリがないほどの変更を行いました。 結果として、Webサイトそのものの制作に集中できたり、デプロイの手間が大幅に減ったり、Webサイトの表示速度が向上したりといった成果がありました。

おそらくこの基盤は来年度以降も使われる…はずです。活用してくれると嬉しいな。

おわりに

こうやって書き出してみると、かなりたくさんの学びや結果が出ていて嬉しいですね。自己肯定感アップ。 既に来年に向けた制作や開発もいくつかスタートしており、2024年は今年以上に挑戦をたくさんする年になると思います。

来年も面白いものや役に立つものを作りたいなと思います。それではよいお年を。

脚注
  1. PR自体は2022年12月だったんですが、Chrome Web Store側でアップデートされたのが2023年だったので2023年の話にさせてください。