🙌

Tauri v2でプラグインを開発する

2024/02/07に公開

Tauri v2 BetaがアナウンスされてIPCや権限系の仕組みが変わったっぽいのでカスタムプラグインを作って試してみる

プラグインは初期化、ウィンドウ作成、ナビゲーション試行、イベントループイベントの処理などのライフサイクルをフックして任意の処理を実行できる

ドキュメントは以下にある

https://beta.tauri.app/guides/plugins/

npm create tauri-app@latest -- --alphamkdir my-tauri-plugin
❯ tauri plugin init -d my-tauri-plugin/
❯ tree my-tauri-plugin/
my-tauri-plugin/
├── examples
│   └── tauri-app
│       ├── public
│       ├── src
│       │   └── lib
│       └── src-tauri
│           ├── icons
│           └── src
├── src
├── webview-dist
└── webview-src
1  [error opening dir]

12 directories
cd my-tauri-plugin/
❯ npm i
❯ npm run build

> tauri-plugin-my-tauri-plugin-api@0.0.0 build
> rollup -c ./webview-src/rollup.config.js


./webview-src/index.ts → ./webview-dist...
created ./webview-dist in 568ms

プラグインのバイナリは以下でビルドできる

cargo build
...
   Compiling tauri-macros v2.0.0-beta.1                                                                                                                                                      
   Compiling reqwest v0.11.24    
    Finished dev [unoptimized + debuginfo] target(s) in 50.65s  

examples/tauri-app/ にプラグインを使う側のプロジェクトを作成してくれている

なのでアプリケーションからの動作確認はここから可能

Tauriの人たちはyarn派で、ここはまだnpmじゃなくてyarnでないと動かなかった(v1系でok)

cd examples/tauri-app/
❯ yarnyarn tauri dev

tauri devは親のプラグインのビルドも含めて実行してくれる

Viteのサーバーが立ち上がって、デスクトップアプリが起動してTauriのメインウィンドウが開く

UIがSvelteのプロジェクトが生成されていた

プラグインとの通信を試してみたところPermissionsを設定できてないという以下のエラーが画面に表示された

[20:49:07]"my-tauri-plugin.execute not allowed. Permissions associated with this command: my-tauri-plugin:allow-execute"

解消方法がドキュメントを読んでもよく分からなかったので、設定の読み込みの実装を調べて以下のファイルを用意した

mkdir src-tauri/capabilities
❯ touch src-tauri/gen/schemas/run-app.json
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "run-app",
  "description": "permissions to run the app",
  "windows": ["main", "main-*"],
  "permissions": [
    "my-tauri-plugin:allow-execute"
  ]
}

とりあえずこれが設置してあるとpermissionは通るけど、今度はRustコードで返した値が画面まで伝わってこない

プラグイン本体に以下のように書かれている

# my-tauri-plugin/src/commands.rs
use tauri::{AppHandle, command, Runtime, State, Window};

use crate::{MyState, Result};

#[command]
pub(crate) async fn execute<R: Runtime>(
  _app: AppHandle<R>,
  _window: Window<R>,
  state: State<'_, MyState>,
) -> Result<String> {
  state.0.lock().unwrap().insert("key".into(), "value".into());
  Ok("success".to_string())
}

なのでsuccessが画面に表示されるのが期待する結果なんだけどundefinedになってしまう

右クリックで開発者ツールを開いてみるとIPC内部のHTTP通信は成功していた

などで取り敢えず直接叩いてみる

この環境でalert()やconsole.log()は使えないので、以下のようにHTMLを追加して結果を確認する

<!-- examples/tauri-app/src/App.svelte -->
  <div>
    <button on:click="{_execute}">Execute</button>
    <div>{@html response}</div>
  </div>

  <p id="result"></p>

ハンドラを書き換えてしまう

function _execute() {
    fetch("ipc://localhost/plugin%3Amy-tauri-plugin%7Cexecute", {
        "headers": {
            "Tauri-Callback": "2802271624",
            "Tauri-Error": "2267197565",
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko)"
        },
        "method": "POST"
    })
    .then((res)=> res.text().then(s=>document.querySelector('#result').innerText = s))
}

表示された

Conclusion

  • Tauriのプラグインは、Rust(やSwift/Kotlin)で書いたコードをRustとJSから呼び出せるインターフェイスを生成してくれる
  • 生成されたコードは、IPCを使って通信している
  • JSのコードは値の交換がうまく動いてなかった

Discussion