RustとJSでクロスプラットフォームなアプリ開発ができるTauriを触ってみた

# 1. 概要
Rustとwebフロント技術でデスクトップアプリケーション開発のできるフレームワーク「Tauri」が正式リリースされたと聞いて，公式のQuick Startを試したり，フロントを書き換えてビルドしたりして遊んでみた．


# 2. 背景
## 動機
Rustで動くデスクトップアプリ開発フレームワークが先日（2022/06/16）正式リリースされたと知った．
 - [Electron代替を目指すRust製フレームワーク「Tauri」がバージョン1.0に到達、Windows/Mac/Linuxに対応 － Publickey](https://www.publickey1.jp/blog/22/electronrusttauri10windowsmaclinux.html)
 - [Tauri on Twitter](https://twitter.com/TauriApps/status/1537347873565773824)

最近ちょうどRustを触りたいと思っていて，さらにデスクトップアプリ開発にも興味があったので，とりあえずクイックスタートから試してみることにした．


## 調査
**基本情報**
クロスプラットフォームなアプリ開発フレームワークで，web技術でフロント，Rustで内部処理を記述できる．
 - [Build smaller, faster, and more secure desktop applications with a web frontend | Tauri Studio](https://tauri.app/)

Version.1.0の現在(2022/6/19)時点で，Windows，Mac，Linuxに対応していて，将来的にはモバイル（Android，iOS）への対応予定もある．（昔はM1 Macで動作しなかったという情報も見かけたが，今回試した範囲ではM1 Macでも動作した．）

OSのWebレンダー（HTMLを表示する機能）を利用することで，軽量なアプリサイズを実現している．
 - [TAURIを触ってみて感じたこと - Qiita](https://qiita.com/Mksk/items/2fe4e8086aecda4ae5a4)
 - [Rustの活用でElectronよりも軽くて速いアプリフレームワーク「Tauri」が安定版に - 窓の杜](https://forest.watch.impress.co.jp/docs/news/1417148.html)
 - [Rust GUI の決定版！ Tauri を使ってクロスプラットフォームなデスクトップアプリを作ろう](https://zenn.dev/kumassy/books/6e518fe09a86b2)


**Electronとの比較**
web技術でデスクトップアプリを開発できるという点で，よくElectronと比較されている．
 - 内部処理をRustで書けるため，Node.jsで処理するElectronよりも軽くて速い点で優れている．
 - 他方で，Rustの知識が必要なことと，開発中も更新の度に毎回ビルド（やや時間がかかる）をする必要がある点などを気にしている人もいた．

（以上，デスクトップアプリ開発未経験者がwebで調べた情報）


## 開発環境
 - マシン：MacBook Air (M1, 2020)
 - OS：MacOS Big Sur

# 3. Quick Start

公式のQuick Startを試してみる．
 - [Quick Start | Tauri Studio](https://tauri.app/v1/guides/getting-started/setup)


HTML/CSS/JSとViteが用意されているが，今回はHTML/CSS/JS を試すことにした．
 - [HTML/CSS/JavaScript | Tauri Studio](https://tauri.app/v1/guides/getting-started/setup/html-css-js)


## アプリケーションの雛形を作る

Tauriホームページに書かれている`create`コマンドを実行(今回はyarnを使用)
```yarn
 yarn create tauri-app
```
※ npm，yarn，pnpmを使う方法は[公式ガイド](https://tauri.app/v1/guides/getting-started/setup/html-css-js/)を参照



アプリ名，ウィンドウ名の入力と，開発環境の選択が案内される
 - 今回は，アプリ名とウィンドウ名をデフォルト（`Tauri App`），開発環境を`Vanilla.js`とした．

終了すると以下のメッセージが表示される
```txt
    Your installation completed.
    $ cd tauri-app
    $ yarn install
    $ yarn tauri dev
```


上記のコマンドを実行すると以下の画面が表示される
 - `dist/index.html`が表示されている
 - ウィンドウを閉じるかctrl-cで終了できる
![画像](https://gyazo.com/b4826c712e65d6a4a892d741e59e071e/raw)



## アプリのカスタマイズ方法を学ぶ
### フロント開発用のディレクトリを作成
HTMLでUIを作成する
 - ディレクトリ`ui`を作成し，その中に`index.html`を作成する

```sh
 mkdir ui
```

```index.html
 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="UTF-8" />
     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Document</title>
   </head>
   <body>
     <h1>Welcome from Tauri!</h1>
   </body>
 </html>
```


### Rustプロジェクトを作成
Tauri AppのコアとなるRustプロジェクトを作成する．
 - Tauriは`tauri`というRust crateを通じて，ウィンドウ，ビュー，OSを呼び出す．
 - 管理には，Rustのビルドツールである`Cargo`を使用する．

**initコマンドの実行**
`init`コマンドで，最小限のRustプロジェクトを構成する．

```yarn
 yarn tauri init
```
※npm，yarn，pnpm，cargoを使用する方法は[公式ガイド](https://tauri.app/v1/guides/getting-started/setup/html-css-js#create-the-rust-project)を参照


**質問内容**

1.アプリ名
 - 今回は`tauri-app`

2.ウィンドウタイトル
 - 今回は`tauri-app`

3.webアセットのパス
 - 本番用にビルドするフロントエンドのパス
 - `<current dir>/src-tauri/taruri.conf.json`からの相対パスで記入する
 - 今回は`../ui`と答える

4.devサーバのURL
 - 開発中にビルドするフロントエンドのパス
 - `<current dir>/src-tauri/taruri.conf.json`からの相対パスで記入する
 - 今回は`../ui`と答える

完了すると，`src-tauri/`が作成される


**生成されたファイルの説明**
 - `src-tauri/Cargo.toml`
	- Cargoのmanifestファイル
	- アプリ構築のメタデータなどを記述
 - `src-tauri/tauri.conf.json`
	- アプリのアセットや構成をカスタマイズするために使用
		- 先ほど入力したフロントエンドのパスが`"buirld":{"devPath", "distDir"}`に書かれている
	- APIの許可リストなどに利用
 - `src-tauri/icons/`
	- デフォルトのアイコン画像の入ったディレクトリ
 - `src-tauri/src/main.rs`
	- tauriのエントリーポイントとなるメインプログラム
		- `#![cfg_attr()]`は，windowsでアプリを開く際にコマンドプロンプトを表示しないための記述
		- `main()`はアプリのエントリーポイントとなるメイン関数

```main.rs
  #![cfg_attr(
     all(not(debug_assertions), target_os = "windows"),
     windows_subsystem = "windows"
  )]
 
 fn main() {
 tauri::Builder::default()
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
 }
```



### ビルドして変更が反映されていることを確認
再びdevモードでビルドして，新たに作成したUIとRustプログラムが動いていることを確認する．
```yarn
 yarn tauri dev
```
※ npm，yarn，pnpmを使うは[公式ガイド](https://tauri.app/v1/guides/getting-started/setup/html-css-js/)を参照



上手くいけば，先ほど作成した`index.html`が表示される．
![画像](https://gyazo.com/072460ae93000a1a31627d26b1ce30d4/raw)
※ 変化がない場合，`src-tauri/tauri.conf.json`の`"buirld":{"devPath", "distDir"}`が，`../ui`となっていることを確認する．（ここが`dist`だと最初と同じ画面が表示される）



# 4. フロント部分のカスタマイズ
`ui/`に適当なフロント要素(HTML/CSS/JS)を配置してみる．


1. HTML，JS，CSSで動く時計アプリ
![画像](https://gyazo.com/4a556d73c4087b41f4059846557fc76e/raw)![画像](https://gyazo.com/b0be4abde4d3c635fc8ffe8b2766b752/raw)

2. JSでwavファイルを再生するアプリ
![画像](https://gyazo.com/22e2ab081e08767aab874a97392397e3/raw)![画像](https://gyazo.com/beb369d14b4d7bca1b7f9e7e793fc885/raw)

# 5. アプリケーションのビルド
そのままビルドコマンドを実行するとエラーが発生する
> You must change the bundle identifier in `tauri.conf.json > tauri > bundle > identifier`. The default value `com.tauri.dev` is not allowed as it must be unique across applications.

アプリケーションのIDをユニークなものに変更する．
 - 今回は検証で公開予定もないので，適当に`.sandbox`を末尾につけ足したものだけのものを用いた．
 - Cf. [Generate unique bundle identifier · Issue #2431 · tauri-apps/tauri](https://github.com/tauri-apps/tauri/issues/2431)

![画像](https://gyazo.com/e59a5433a0e70b1ee5c13b83cb66576d/raw)




ビルドコマンドを実行する
```yarn
 yarn tauri build
```

`src-tauri/target/release/tauri-app`（アプリ）と`tauri-app/src-tauri/target/release/bundle/dmg/tauri-app_0.1.0_aarch64.dmg`（ディスクイメージ）がビルドされる．

![画像](https://gyazo.com/5858aa6778299daa0641163537648a4e/raw)


![画像](https://gyazo.com/dfd0075f683b147d868e1e04e425b149/raw)



`tauri-app`を開くと，`tauri dev`したときと同じ動作をするアプリケーションが開いた．
![画像](https://gyazo.com/b0be4abde4d3c635fc8ffe8b2766b752/raw)．



# 6. まとめ

TauriのQuick Startを試して，その後にフロント部分を変えてビルドまで試してみました．
これから，内部処理の書き方も勉強して色々試してみます．
何か面白いことがあったら続報を上げます．