Leptosを使ってTauriアプリのフロントエンドもRustで書く
Tauri入門にありがちな状況として「Rustの学習目的ではじめたのにフロントエンドのJavaScriptばかり書いている」というものがあります(GUIアプリなので……)
そこでフロントエンドもRustで書くようにしたいと思い、Tauriに再入門することにしました
TauriとLeptosの概要
Tauriでは以前からYewでフロントエンドを書く選択肢があったのですが、 v2.0でさらにLeptos(やSycam)がcreate-tauri-appのテンプレートに追加されているので使ってみます
システムにtrunkがインストールされている必要があります。trunkはJavaScriptでいうviteのレイヤーです
❯ cargo create-tauri-app --beta -m cargo -t leptos -y tauri-app
❯ cd tauri-app
❯ cargo install tauri-cli --version '^2.0.0-beta'
❯ cargo tauri dev
プロジェクトの構成
Tauriプロジェクトでは、アプリケーションのコードは
- src: フロントエンド
- src-tauri:バックエンド
の2つのディレクトリに分けられています。
-t leptos
でプロジェクトを作成すると、フロントエンドのディレクトリにはJavaScriptはなく、Rustファイルのみ含まれるようになります
❯ tree src/
src/
├── app.rs
└── main.rs
Rustでフロントエンドを書くといってもGUIのAPIがあるわけではなくて、LeptosのClient-side rendering (CSR)のアプリケーションをWebViewで表示します
JSで書いていた部分だけRustに変わり、ビルド時にWebAssemblyに変換されます
実装の詳細
viewの部分はJSXようなリテラル表現でview!マクロの中に記述してコンポーネント化します
<main>
より外側のマークアップはプロジェクト直下にindex.htmlとstyle.cssが配備されていて、普通のSPAのように記述します
つまり、これまでJavaScriptで書いてた部分のみRust(WebAssembly)で書くということになります。(viewも含めてRustで記述できるtauri-eguiのようなソリューションもありますが、まだ試せていません)
実行はWebView上で行われるため、使用できるcrateには制限があります
イベントハンドラはupdate_name
の部分で、シグナルというリアクティブプログラミングでよく使われる概念を使用して状態変化を扱います(この例ではuseState()の役割を果たします)
invoke("greet", args)
の部分はTauriのIPC呼び出しを表し、これをバックエンド側で呼び出せるよう定義しておきます
この先は: ルーティング
leptos_routerの追加crateがあります
❯ cargo add leptos_router --features=csr
まだ試行錯誤している段階なのでこの情報だけに留めます(なんかSSRモードになってコンパイルが通らない)
Discussion