🎃

macOS自作アプリをElectronからTauri(v2)へ移行した話

に公開

個人で開発しているmacOS用の自作アプリのElectronアップデートが煩雑になってきたため、思い切ってTauriへ移行してみました。

アプリの機能概要

このアプリは、指定したローカルフォルダから画像ファイルを読み込み、別の指定したフォルダへ移動させるシンプルな機能を持っています。

開発・実行環境

  • OS: MacOS
  • Rust: 1.85.0
  • Tauri: 2.4.0
  • Node.js: 22.8.0
    • Node.jsはDevbox(jetify)上で実行
  • フロントエンドフレームワーク: Nuxt 3.15.4
npm run tauri info

✔] Environment
    - OS: Mac OS 15.3.2 arm64 (X64)
    ✔ Xcode Command Line Tools: installed
    ✔ rustc: 1.85.0 (4d91de4e4 2025-02-17)
    ✔ cargo: 1.85.0 (d73d2caf9 2024-12-31)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-aarch64-apple-darwin (default)
    - node: 22.8.0
    - npm: 10.8.2

[-] Packages
    - tauri 🦀: 2.4.0
    - tauri-build 🦀: 2.1.0
    - wry 🦀: 0.50.5
    - tao 🦀: 0.32.8
    - @tauri-apps/api  : 2.4.0 (outdated, latest: 2.4.1)
    - @tauri-apps/cli  : 2.4.0 (outdated, latest: 2.4.1)

[-] Plugins
    - tauri-plugin-opener 🦀: 2.2.6
    - @tauri-apps/plugin-opener  : 2.2.6
    - tauri-plugin-dialog 🦀: 2.2.0
    - @tauri-apps/plugin-dialog  : 2.2.0 (outdated, latest: 2.2.1)
    - tauri-plugin-fs 🦀: 2.2.0
    - @tauri-apps/plugin-fs  : 2.2.0 (outdated, latest: 2.2.1)

[-] App
    - build-type: bundle
    - CSP: default-src 'self' ipc: http://ipc.localhost; img-src 'self' asset: http://asset.localhost
    - frontendDist: ../dist
    - devUrl: http://localhost:3000/
    - framework: Vue.js (Nuxt)
    - bundler: Vite

導入方法

Tauriのインストールと既存のNuxt3プロジェクトフォルダの移行は、以下の記事を参考にしました。ほどんど記事そのままなので、内容は省略します。
https://zenn.dev/crysta1221/scraps/f3266abadd8404
https://v2.tauri.app/ja/start/frontend/nuxt/

Tauriの起動

ルートディレクトリのpackage.jsonに定義されたスクリプトを使用してTauriを起動します。

npm run tauri:dev

この時点で、移行前のNuxt3アプリがTauri上で問題なく動作起動しました。

Tauriのプラグイン活用

今回のアプリはシンプルなため、Rustのコードをほとんど記述せずに、Tauriのプラグイン機能のみで実装できました。具体的には、以下のプラグインを使用して必要な機能を実装しました。

  • フォルダを開くダイアログを表示
  • 確認ダイアログを表示
  • ローカル画像ファイルの参照と表示
  • ファイルの移動と削除

プラグインのインストール

必要なプラグインは以下のコマンドでインストールしました。

npm run tauri add dialog
npm run tauri add fs

これらのコマンドを実行すると、lib.rsCargo.tomlにプラグインの設定が自動的に追加されます。

// src-tauri/src/lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_fs::init())      // 追加
        .plugin(tauri_plugin_dialog::init())  // 追加
        .plugin(tauri_plugin_opener::init())
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

アクセス権限の設定

fsプラグインなど、使用するメソッドにはアクセス権限の設定が必要です。

https://v2.tauri.app/ja/plugin/file-system/#security
https://v2.tauri.app/ja/reference/javascript/fs/#security

デフォルトではsrc-tauri/capabilities/default.jsonが設定されているので、ここにプラグインのメソッドを追加する形で設定を行いました。

// src-tauri/capabilities/default.json
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "Capability for the main window",
  "windows": [
    "main"
  ],
  "permissions": [
    "core:default",
    "opener:default",
    "dialog:default",
    "fs:allow-read-dir",
    "fs:allow-exists",
    "fs:allow-rename",
    "fs:allow-remove",
    {
      "identifier": "fs:scope",
      "allow": [
        {
          "path": "$HOME/**" // ユーザのHomeディレクトリ以下のみ許可
        }
      ]
    }
  ]
}

ローカルファイルアクセスのセキュリティ(CSP)

image要素でローカル画像ファイルを読み込むには、パス変換とCSP設定が必要です。convertFileSrc()を使用してパスを変換し、CSPを設定します。

// tauri.conf.json
  "app": {
    "security": {
      "assetProtocol": {
        "enable": true,
        "scope": [
          "**"
        ]
      },
      "csp": "default-src 'self' ipc: http://ipc.localhost; img-src 'self' asset: http://asset.localhost"
    }
  },

ビルド設定

.dmgファイルは不要なため、.appのみを生成するように設定を変更しました。デフォルト設定では、.dmg生成時にFinderへのアクセス許可が必要となる場合があります。

// tauri.conf.json
  "bundle": {
    "active": true,
    "targets": "app", // all->appに変更
    "icon": [
      "icons/32x32.png",
      "icons/128x128.png",
      "icons/128x128@2x.png",
      "icons/icon.icns",
      "icons/icon.ico"
    ]
  }

ビルド実行

npm run tauri build

ソースコード

今回作成したアプリのソースコードはこちら。
https://github.com/skysan87/image-assorter

参考

Discussion