Go+Vue2 のOSSデスクトップアプリをRust/tauriに移行した
こんにちは。ふろーです。
主題通り。 Go+Vue2 で作成されたデスクトップアプリ(ただしUIはブラウザ)をRust/tauri に移行した際のノートです。
元プロジェクト
vmix-utility という、配信プロダクション向けスイッチャーソフトウェアである「vMix」のサポートツールです。
vMix自体にHTTP APIが内蔵されており、特定のURLを叩くことで様々なアクションを実施することが出来ます。
localhost:8088/api エンドポイントを叩くと所定の形式のXMLを取得することができ、各種Input(カメラなど映像ソースのようなもの) の一意のGUIDを取得することが可能です。
開発理由(v1)
元々、本プロジェクトは2020年頃に個人で作成したものです。
職場の先輩が上記のXMLを手でコピーし、APIを叩くためのURLを手動で作成していたのを見て、「これは自動化出来るな」と思い、簡単なソフトウェアを作成しました。
(余談ですが、GETリクエストでも実行可能だったため、コピーしたURLはElgato StreamDeckの「Webサイト」アクションで呼び出していました)
実態としてはとてもシンプルであり、バックエンドで取得したXMLを解析し、フロントエンドのVueでURLを生成しコピーするだけのシンプルなソフトウェアです。
シンプルな機能故に、敢えて技術的にかなり枯れており容易にクロスプラットフォーム対応ができ、ドキュメントが多いGo+Vue2を選択しました。
ソフトウェアの肥大化
元々映像配信技術業がメインなので、このソフトウェア自体を自分とその周辺が使っていました。
が、月日が経つと噂が広まったようで、VALORANT CHAMPIONS TOUR JAPANやApexLegends Global Series,ブレイキングダウンなどの大規模なイベントでも採用される事例が増えてきました。
それに併せ、vMix側では使い勝手が悪い機能を追加したりしていた結果フロントエンドが肥大化し、レガシーなVue2のメンテナンスも難しくなってきました。
参考までに、追加した機能の一覧です。
- 特定のHTML/CSS/JS を返す機能(MultiViewer機能)の追加
- 指定のアクション(Shortcut) をスクレイピングしサジェストする機能
- vMixの映像ソースの名前を変更する機能
- 大量のBlankInputを一括で生成する機能
バックエンド・フロントエンドともに機能が肥大化し、またユーザーが増えたことによりGoのコマンドプロンプトを間違えて落としたりする人も増え、UXが悪化しました。
v2移行の決断
2023年頃よりデスクトップアプリへの移行を計画していましたが、RustでのvMixライブラリが存在しなかったこと、自分がRustに明るくなかったことにより難航しており、移植に踏み切れずいました。
しかし、近年Claude CodeやCursorなどAIの機能を活用した開発が盛んになり、別のプロジェクトでも威力を実感していたため、vMixのRustライブラリの作成も含め移植を決断しました。
(ちなみに、v1の時点でもvMixのGoライブラリを自分でメンテナンスしていました)
移植作業
まずはvmix-go で行っていた処理を全てカバーする必要がありました。
が、基本的にはHTTPリクエストとXMLのパーシング処理だけだったため、AIにもあまり頼らず割と簡単に済みました。
次にRust/tauri の実装です。 これまでのプロジェクトとは使用するフレームワークも構成も全く異なったアプリケーションとなるため、最初に要件定義を行いました。
- クロスプラットフォーム対応のデスクトップアプリであること
- 映像プロダクションで間接的に使用するため、なるべく堅牢であること
- DXのため、フロントエンドにReactを採用すること
- デスクトップアプリの機能をフルに生かし、タスクバー常駐、自動アップデートを行えること。
- 複数のvMix接続に対応できること。
- これまでの機能は全てカバーしていること。
- 厳密にはMultiViewer機能のみ、使用ユーザーが少なかったため実装を後回しにしました。
tauriのプロジェクト作成、バックエンド/フロントエンドのコード実装はほぼ全てClaude Codeで行い、若干の修正や機能追加にCursorを使用しました。
Rust移行PR
OSSかつ非営利であるためモチベーションに波があり時間はかかりましたが、無事移行が完了しました。
ほぼ全ての既存機能のカバーに加え、tauriの利点を活用したアプリケーションになっています。
移植して良かったこと
フロントエンド
まずReact最高。Vue2辞めてよかった。
そもそものコードベースが汚かったのもありますが、レガシーな技術かつ採用例が少ないフレームワークだったので、Reactへの移行は正解でした。
また、私自身フロントエンドにはあまり強くないため、AIの力を借りることが出来たのがとても心強かったです。移行時・機能追加時を含めフロントエンドはほぼ全てVibe codingです。
機能追加も容易になり、デザインも大幅に改善しました。
バックエンド
Rustすげーいい。安心感がある。
個人的にはGoの方が得意なのと、AIとRustの相性があまり良くないイメージがありましたが、思ったよりスムーズに実装が完了しました。
tauriのプラグインシステムもかなり良く、タスクバーの常駐や自動アップデート、ダイアログ表示などはほぼ全てプラグインシステム単体で完結します。
tauri自体がホットリロード機構を備えているのも凄くDXがいいです。
その他
これまではフロントエンドをビルド→成果物をGoのembedded packageで読み込み... という形だったので、Vue側で特定のエンドポイントへのアクセスのみリレーサーバーを入れる形で開発していましたが、設定が複雑化したのでDXが悪かったです。
また、Multiview機能は他レポジトリをgit submoduleで追加し運用していたため、メンテナンスするライブラリがとても増えたのも苦痛だったため、vmix-rs / vmix-utility の2つになったのはかなり嬉しかったです。
また、GitHub Actionsを使った自動リリース・自動アップデート機能の提供もほぼtauriの公式workflowに頼るだけで成立しました。
移植時に困ったこと
思ったより無かったです。
強いて言うのであれば、自動アップデートの際に設定をミスってしまい、v2.0.0~v2.1.0 まで自動アップデートが動作しませんでした。
次バージョンであるv2.2.0 から修正される予定です。 修正しました。
ここはテストがなかなか出来ないので結構怖い。良いテスト方法はないのだろうか...?
おわりに
(個人開発とはいえ) 長い期間をかけて少しずつ熟成されたプロジェクトであり、レガシーな技術やコードも多かった中AIの力を借りることで簡単に移植出来たのは非常に素晴らしかったです。ありがとうClaude。ありがとうCursor。
最後に、vmix-utility は営利利用も含めて無料で利用できるOSSソフトウェアです。
数年間1円も貰っていません。フリーランスやスタジオで利用している方は是非寄付頂けると嬉しいです!
Discussion