15 ポイント 投稿者 tsboard 2024-12-30 | 12件のコメント | WhatsAppで共有

約7か月前に、初めて TSBOARD プロジェクトをご紹介しました。

そのときはフロントエンドもバックエンドも TypeScript で書かれており、バックエンドの実行には Bun ランタイムを使っていました。

しかしさまざまな事情からバックエンドを新たに作り直すことになり、既存の TSBOARD プロジェクトとは分離した GitHub リポジトリに公開します。この新しいバックエンドは Go 言語で書かれており、TSBOARD 正式版でバイナリ形式として同梱されます。


なぜバックエンドを新しく作ったのか?

  • Bun ランタイムは本当に優れた性能を見せてくれます。しかし、オールインワンツールキットというもう一つの紹介文句とは裏腹に、パッケージ管理はまだ npm に及びません。
  • このため TSBOARD を使うには Node.js と Bun の2つのランタイムが必要でした。煩雑ですし、ユーザーの立場でも不便でした。
  • 今は修正されましたが、初期には仮想 CPU で動作しない問題があり、肝心の開発者である私自身も別のサーバーに載せられない状況だったのは致命的でした。
  • (ほかの方々の指摘のように)オーケストレーションをすればよいとはいえ、シングルスレッドという制約がどうしても本質的にある JS ランタイムの限界を越えて、複数スレッドを活用したかったのです。
  • もっと多くの型が必要でした。TypeScript だけではこの渇きを満たせませんでした。

なぜ Go 言語を選んだのか?

  • 新しいバックエンドは、1) コンパイルされること、2) メモリ管理を自動でやってくれること、3) 別途ランタイムのようなものをインストールする必要がないこと、が必要でした。
  • Rust、Kotlin、Python、PHP、そして Go 言語を候補に悩んだ末、上の3つの条件をすべて満たしつつ、私にとっては初めてとなる Go 言語を選ぶことになりました。(ごめん PHP)
  • Go 言語のシンプルさが最も気に入り、TypeScript との類似点も選択の大きなポイントでした。何より並行性の管理やメモリ管理の面で、ほかの代替案より良い選択だったと思います。

Go 言語、使ってみてどうだったか?

  • この世に長所だけの言語はないという事実を、Go 言語も証明しているのだなと実感しました。if err != nil { } は確かに必要ですが、本当にとても面倒です。try catch finally が恋しくなることがたびたびあります。
  • go-mysql-driver の問題と推定していますが、DB I/O というボトルネックがある実際の開発環境では、それほど速くは動きませんでした。(ここ GeekNews に投稿した記事参照: https://ja.news.hada.io/topic?id=18048
  • 暗黙的なインターフェース適用は、今でも少し違和感があります。implementsextends のようなキーワードを使いたくなかったのでしょうか?
  • ポインタは歓迎でした。特にメモリ解放のタイミングを気にしなくてよい点が!
  • さまざまな型、シンプルながら強力な構造体、スライスは大のお気に入りです。キーワードが少ないので、すぐに学んで使える点が最高です。
  • go キーワードで魔法のように軽量スレッドを使えるなんて...! 幸せです!

バックエンドを JS ランタイムベースから Go に変えた感想...?

  • こんなことは一度で十分です。
  • DB I/O 部分をベンチマークしながらいろいろテストしてみましたが、性能の観点では実際のところ JS ランタイムでも Go バイナリでも大きな差は感じにくいです。たとえば JS でよく使われる画像ライブラリ sharp も同じく libvips ライブラリを使いますし、DB I/O のない Web アプリケーションはありませんから。
  • それでも、私は大変な苦労はしましたが、うまく切り替えられたと思っていますし、今後バックエンドは Go 言語だけを使い続けるつもりです。
    • メモリ使用量が本当に意味のある水準まで下がります。もちろん Rust で開発すればさらに最適化できるでしょうが、GC を使える対価としてこの程度なら十分満足できます。
    • 言語自体のシンプルさが本当にすごいです。覚えるべきキーワードも少なく、使い方のパターンもほとんど決まっているので学びやすいです。(もちろん、うまく使うのはまた別の話ですが)プリミティブ型が多様に用意されている点も本当に気に入りました。
    • 何より満足している点は、コンパイル後はバイナリさえあればとりあえず実行できることです。バックエンドを動かすために追加で何かをインストールし、それでコードを再実行しなければならないのは、もうこれ以上ごめんです。

どうやって使うのか?

  • Windows 環境は残念ながらサポートしていません。Linux/Mac 環境でバイナリを実行してください。
  • 利用するサーバーには libvips ライブラリが事前にインストールされている必要があります。バイナリがそのライブラリの機能を使って画像処理を行うためです。
  • 詳細は README.md ファイルに説明してあります。

まだまだ不足しており、今もほかの開発者の皆さんからのご意見を待っています。GeekNight のイベントのときにおどおどしていた自分自身が恨めしいほどです。バグ報告や改善提案、あるいはひと味違う意見もすべて歓迎します。

今年は12月がとりわけ重く感じられますが、それでも新年にはもう少し良い未来があることを願ってみます。長文を読んでいただきありがとうございました。最後に TSBOARD v1.0.0 リリースノートのリンクを以下に共有します。

https://tsboard.dev/board/free/47

12件のコメント

 
angkr 2025-02-03

ダモアンで見てきました。
期待できるCMSです。ありがとうございます

 
tsboard 2025-02-04

ダモアンでも私のことを覚えていてくださる方がいて、私もびっくりしました。haha ご期待に応えられるよう、もっと努力します! 😊

 
dongho42 2025-01-03

参考になります!

 
tsboard 2025-02-04

遅くなりましたが、コメントありがとうございます! 😃

 
jongyeol 2025-01-02

暗黙的なインターフェース適用は、今でも少し違和感があります。implementsextends のようなキーワードを使いたくなかったのでしょうか。

長所と短所がありますが、長所としては、標準/外部ライブラリのコードを修正せずに、他人が作った実装を使いながら、その一部を自分が作った interface として扱える点は、しばしば利点だと感じます。Java の FunctionalInterface のように、あるいは duck typing をコンパイル言語に適用したようなものですね。逆に、implements/extends を必ず宣言する方式だと、自分が作った interface に結び付けるには、途中で Adapter を 1 つ実装しなければならないのに対して。

短所としては、interface にメソッドを追加/削除/変更したとき、他の静的型付け言語に比べてエラーが表示される位置が異なるので、少し不便ですね.

 
tsboard 2025-01-02

あっ、そうなんですね! 思いもよらなかった利点があったんですね。エラーメッセージは幸い gopls だったかな? VSCode の Go 言語拡張がうまく拾ってくれるので、抜けていたところや実装を誤ったところもすぐに見つけることができました。もう少し慣れたら、私もいつかもっと上手く使えるようになる気がします。笑 コメントで説明してくださってありがとうございます! 新年も良いお年をお迎えください〜!

 
ifmkl 2025-01-02

お疲れさまでした! 私もテストサーバーに上げてみます! 25年の新年もご活躍をお祈りしています!

 
tsboard 2025-01-02

ありがとうございます!ぜひお試しいただき、もしうまく動かなかったりご不明な点がありましたら、いつでもお知らせください!新年もよろしくお願いいたします〜!

 
channprj 2025-01-01

応援しています〜 👍🏻

 
tsboard 2025-01-02

応援ありがとうございます!!! あけましておめでとうございます〜!

 
zihado 2024-12-31

応援しています!

 
tsboard 2025-01-02

ありがとうございます!!! あけましておめでとうございます!!