技術情報

Rustを使用したデスクトップアプリ開発!Tauriを使ってみた!

こんにちは、MSKです。
クロスプラットフォームデスクトップアプリのためのフレームワーク、Tauriがずっと気になっていたので、試してみました!

Tauriとは

デスクトップアプリ開発のためのフレームワークです。
Electronと同じようにアプリのUIをWeb技術で構築することができますが、メインプロセス側をJavaScriptではなくRustで書くことができます。

GitHubの公式のページをみると、Electronとの比較が書いてあるのですが、パッケージのサイズとメモリの消費が半分以下に小さく、起動時間がより速いということが書かれています。

他の違いは

  • ElectronはUIをChromium、TauriはWRYを使用している
  • Electronはモバイルに非対応、Tauriはモバイルに対応する計画がある

などがあります。

プロジェクトを作成する

まず、RustとNode.jsをインストールしておく必要があります。
インストールしている場合は、最新の安定版に更新しておきます。

プロジェクトの作成方法は簡単で、次をターミナルから入力して実行します。

npx create-tauri-app

実行すると、いくつかアプリについて聞かれるので必要な項目を入力・選択します。

現在有名なWebフレームワークにも対応しているみたいで、

  • Vanilla.js(フレームワークなし)
  • React
  • Vue
  • Angular
  • Svelte
  • Solid

などが使えます。

僕はReactを選択して、TypeScriptを使うようにしました。

プロジェクトが作成されるので、この中で次を実行するとアプリが立ち上がります。

npm run tauri dev

一番最初は、ビルド等でけっこうな時間がかかります。
僕の場合は次のようにアプリが立ち上がりました。

アプリの上で右クリックするとWebブラウザと同じように検証などを使うことができ、デバッグに活用できます。

カウントアップ・ダウンのサンプルを作ってみる

スタートのプロジェクトを少し変えて、よくあるカウントアップ・ダウンするアプリを作ります。

カウントする変数をState管理します。
main関数の中でmanageメソッドを呼び出すことでStateの初期化と設定ができます。

tauri::commandをつけるとレンダラープロセスから呼び出すことができます。
レンダラープロセスで呼び出したい関数はinvoke_handlerに登録します。

#![cfg_attr(
  all(not(debug_assertions), target_os = "windows"),
  windows_subsystem = "windows"
)]

use std::sync::atomic::{AtomicI32,Ordering};

struct CountValue(AtomicI32);

#[tauri::command]
fn increment(state: tauri::State<CountValue>) -> i32 {
  state.0.fetch_add(1,Ordering::SeqCst) + 1
}

#[tauri::command]
fn decrement(state: tauri::State<CountValue>) -> i32 {
  state.0.fetch_sub(1,Ordering::SeqCst) - 1
}

fn main() {
  tauri::Builder::default()
    .manage(CountValue(AtomicI32::new(0)))  
    .invoke_handler(tauri::generate_handler![increment,decrement]) 
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

レンダラープロセス側は今回は簡単なものにしています。

import React from 'react';
import {useState} from "react";
import './App.css';
import {invoke} from "@tauri-apps/api"

function App() {

  
  const [result,setResult] = useState<number>(0);


  return (
    <div className="App">
      <h1>tauri-sample</h1>
      <button id='increment_btn' onClick={()=>{invoke("increment").then((res) => setResult(res as number));}}>Increment</button>
      <button id='decrement_btn' onClick={()=>{invoke("decrement").then((res) => setResult(res as number));}}>Decrement</button>
      <div id='result'>{result}</div>
    </div>
  );
}

export default App;

Rust側で定義した関数はinvokeで関数名を書くことで呼び出すことができます。
そのために、invokeをインポートしておく必要があります。

最後に

プロジェクトの作成はコマンド一発なので、すぐに試すことができます。

ただ、まだ日本語のドキュメントも少ないですし、本家のドキュメントもあんまり親切といった感じではないので、カウントアップ・ダウンするアプリを作るにしても意外と時間がかかりました。

もう少し実用性のあるアプリを作ってみたいと思いますので、作ったらElectronと比べてどうなのかなどブログで発信できればいいなと思っています。

以上、「Rustを使用したデスクトップアプリ開発!Tauriを使ってみた!」でした。
最後までご覧頂き、ありがとうございました。

ABOUT ME
MSK
九州在住の組み込み系エンジニアです。 2児の父親でもあります。 数学やプログラミングが趣味です。 最近RustとReact、結び目理論と曲面結び目理論にはまっています。