【Tauri 2.x】における注意点と開発方法
目次
- はじめに
- tauriの基本
- Tauri 2.xの主要な変更点
- ハマるところ
- 開発について
- 注意
はじめに
Tauri 2.x系 (ここではv2.5.1) の開発は非常に快適ですが、プレリリース版ゆえの不安定さや仕様変更により、依存関係のバージョン管理で思いがけないトラブルに遭遇することがあります。
Tauriの基本(Invoke / Emit)
Tauriの連携は、基本的に以下のパターンで行われます。
Node/Frontend → Rust: invoke で Rustの関数(コマンド)を呼び出す。
Rust → Node/Frontend: emit でイベントを発行し、Node側で on で受け取る。
tsc, typescript, reactを入れる想定
node側からの呼び出し
import { invoke } from "./@tauri-apps/api/core"; //ここがapiからcoreになりました
function inoke_rust(){
invoke ("server", arg);
}
return {
<buttion onclick="invoke_rust"></button>
}
rust側はuseしなくても基本的なtauriは動作する
use tauri::command;
#[tauri::command]
fn server(arg){
//server cluc
let arg = test;
}
本記事では、私が直面した以下の2つの主要な問題の切り分けと解決策、そして動作確認済みの設定ファイルを共有します。
-
npmとRustクレート間でのマイナーバージョン不一致ビルドエラー
-
Invokeコマンドの引数における命名規則の問題
前提とする環境構成
-
OS: Linux (Windows/macOSでもRust環境があれば共通の解決策が適用可能です)
-
Frontend: React + TypeScript (Vite)
-
Backend: Rust (Tauri 2.x)私はとりあえず2.5.1で提示させていただきます。
Tauri 2.xの主要な変更点(InvokeとAPI)
変更点1: APIのパス変更
@tauri-apps/api のコア機能(invoke や on など)は、@tauri-apps/api/core へと移動しました。
変更前 (1.x): import { invoke } from "@tauri-apps/api";
変更後 (2.x): import { invoke } from "@tauri-apps/api/core";
Tauri 1.xから2.xへの移行で、最も重要な変更の一つが @tauri-apps/api の構造変更です。
変更点2: Rustコマンドの基本構造
Rust側は引き続き #[tauri::command] マクロを使用します。
use tauri::{Builder};
#[tauri::command]
fn app1(arg: String) {
// server logic here
println!("Received arg: {}", arg);
}
最大のハマりどころ:Invoke引数の命名規則
Tauri 2.xで特に注意が必要なのが、JavaScript側とRust側の引数名のマッピングです。
結論: Rust側の引数名もキャメルケース (camelCase) に合わせる必要があります。
Tauriは、JavaScript側の標準的な命名規則であるキャメルケースの引数名が、Rust側のスネークケース (snake_case) の引数名と**自動で一致すると期待しますが、これが意図通りに動作しないことがあります。**特に引数が一つではない場合や構造が複雑な場合、厳密な一致が求められます。
エラーになる例 (Rust側がスネークケースの場合)
JavaScript (キャメルケース)
// ipA (キャメル) を渡そうとしている
invoke("rust_fun", {
ipA: "192.168.1.1",
port: 8080
});
Rust (スネークケース)
#[tauri::command]
fn rust_fun(
ip_a: String, // スネークケース
port: u16,
) {
// ...
}
→ この組み合わせはエラーになる可能性が高い
解決策 (Rust側もキャメルケースに合わせる)
Rustの標準的な慣習はスネークケースですが、TauriのInvokeハンドラに関しては、JSの慣習であるキャメルケースに合わせることで確実になります。
Rust (キャメルケース)
#[tauri::command]
fn rust_fun(
ipA: String, // 解決策:キャメルケースに統一
port: u16,
) {
// ...
}
発生したエラー (バージョン不一致)
久しぶりにcargo tauri build 時に以下のエラーが発生しました。
Error Found version mismatched Tauri packages. Make sure the NPM package and Rust crate versions are on the same major/minor releases:
tauri (v2.5.1) : @tauri-apps/api (v2.6.0)
または、NPM側が追いついていないバージョンを参照するエラーです。
npm ERR! notarget No matching version found for @tauri-apps/api@2.5.1.
まぁAPI形が変わっていないから上げる必要がないのでしょうが、、、
開発について
一番楽な開発スタート
'npm install tauri-latest'
node周りは普通の開発と同じですのでrustのmainコードを示します
rust
use tauri::{Builder};
#[tokio::main]
async fn main() {
println!("App start");
Builder::default()
// generate_handler!に複数のコマンドを渡せます
.invoke_handler(tauri::generate_handler![
app1,
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
npmのパッケージ
npmのパッケージもrustとversionが1:1出ないことに注意
package.json
{
"name": "tauri-app",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"tauri": "tauri"
},
"dependencies": {
"@tauri-apps/api": "2.5.0",
"@tauri-apps/plugin-opener": "^2",
"chart.js": "^4.5.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^7.6.2"
},
"devDependencies": {
"@tauri-apps/cli": "2.5.0",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react": "^4.3.4",
"autoprefixer": "^10.4.21",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.10",
"typescript": "~5.6.2",
"vite": "^6.0.3"
}
}
キャロットはやめておくことを推奨
ここでrustはtauri2.5.1だが、
nodeは2.5.0までしか出ていない
昔はキャロットでも行けたり、できる場合もあるが、、、
一応tsのjson
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
vite
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// @ts-expect-error process is a nodejs global
const host = process.env.TAURI_DEV_HOST;
// https://vitejs.dev/config/
export default defineConfig(async () => ({
plugins: [react()],
root: './src',
// Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
//
// 1. prevent vite from obscuring rust errors
clearScreen: false,
// 2. tauri expects a fixed port, fail if that port is not available
server: {
port: 1420,
strictPort: true,
host: host || false,
hmr: host
? {
protocol: "ws",
host,
port: 1421,
}
: undefined,
watch: {
// 3. tell vite to ignore watching `src-tauri`
ignored: ["**/src-tauri/**"],
},
},
build: {
outDir: '../../dist'
}
}));
注意
現在tauri 2.5.1は脆弱性が確認されているようです!
localの動作に留めるなど、してください
私もtauriの依存をを追いますが、とりあえず2.x系への以降が大変かと思いますが、2.xまで行ってしまえば大きなAPI修正はないと思います。