Open6

Tauri を試す

nonanonnononanonno

最近 Tauri がバージョン 1.0.0 になったらしいので試してみる。

公式ガイドを参照して進める。

nonanonnononanonno

Prerequisites によると Rust とWebView2 に依存している。今回はLinux (Docker) で進めるが、Windows10ではWebView2が標準でインストールされているわけではないので注意(Windows11ではインストールされている)

手順は以下のもの

Dockerfile

FROM ubuntu:20.04

RUN apt-get update && apt install -y tzdata && apt-get clean && rm -rf /var/lib/apt/lists/*
ENV TZ Asia/Tokyo

RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
    libwebkit2gtk-4.0-dev \
    build-essential \
    curl \
    wget \
    libssl-dev \
    libgtk-3-dev \
    libayatana-appindicator3-dev \
    librsvg2-dev \
    && apt-get clean && rm -rf /var/lib/apt/lists/*

devcontainer

{
  "name": "tauri-test",
  "build": {
    "dockerfile": "Dockerfile"
  },
  "forwardPorts": [
    6080
  ],
  "remoteUser": "vscode",
  "features": {
    "git": "latest",
    "desktop-lite": "latest",
    "commont": "latest",
    "common": "latest",
    "rust": "latest",
    "node": "lts",
  },
  "extensions": [
    "rust-lang.rust-analyzer"
  ]
}

node は前提として明記されていないが、後でViteを使うので入れておく。

nonanonnononanonno
cargo install tauri-cli --version "^1.0.0"

により Tauri CLI をインストールする。Tauri CLI は以下の機能を含む。

  • Cargo による core (Rust製) のビルド
  • Frontend developement server の起動
  • アッセトのバンドル
  • sidecars and resources when building for production (?)
nonanonnononanonno

NPM 経由での Tauri CLI の導入

Tauri CLI は Node.js アドオンとしてもコンパイルされ、NPMパッケージとして配布している。CLIはコンパイル済みのものが導入され(cargo install ... ではソースをダウンロードしてビルドする)、npm の scripts セクションから呼ぶことができる。

npm install --save-dev @tauri-apps/cli

package.json

{
  // This content is just a sample
  "scripts": {
    "tauri": "tauri"
  }
}

インストール経由が違うだけでどちらを使っても良さそう。

nonanonnononanonno

Quick Start

クイックスタートでは HTML/CSS/JavaScriptVite のどちらかを選べる。Vite(ヴィートと読む)はフロントエンドのビルドツール。フロントエンド良く知らないので正直何なのかわからんが使ってみる。たぶん最近のフロントエンドの文脈が求められると思うが。

なお、クイックスタートではよくわからん場合は HTML/CSS/JS が勧められている。通信周りも自分で書くと思うので明確なのだろう。

nonanonnononanonno

Vite で Tauri アプリを作る

そもそもの話として、TauriはなんらかのFrontendフレームワークとRust coreを持つデスクトップアプリケーションをビルドするフレームワーク。つまり、以下を持つ。

  • Rustバイナリ。ウィンドウを作り、そのウィンドウが使用可能なネイティブ関数を公開する
  • Frontend。UI周り

手順では、

  1. Frontendの枠組みを作り
  2. Rustプロジェクトを作り
  3. FrontendとRustの通信方法を示す

Frontendを作る

# Project name -> 任意 (vite-project とする)
# Select a framework -> vanilla
# Select a variant -> vanilla-ts
npm create vite@latest

によりテンプレートからプロジェクトが作られる。その後 vite.config.ts を追加するが、これは作成したプロジェクトのルートに設置する。

import { defineConfig } from 'vite'

export default defineConfig({
  // prevent vite from obscuring rust errors
  clearScreen: false,
  // Tauri expects a fixed port, fail if that port is not available
  server: {
    port: 3000,
    strictPort: true,
  },
  // to make use of `TAURI_PLATFORM`, `TAURI_ARCH`, `TAURI_FAMILY`,
  // `TAURI_PLATFORM_VERSION`, `TAURI_PLATFORM_TYPE` and `TAURI_DEBUG`
  // env variables
  envPrefix: ['VITE_', 'TAURI_'],
  build: {
    // Tauri supports es2021
    target: ['es2021', 'chrome97', 'safari13'],
    // don't minify for debug builds
    minify: !process.env.TAURI_DEBUG && 'esbuild',
    // produce sourcemaps for debug builds
    sourcemap: !!process.env.TAURI_DEBUG,
  },
})

Rustプロジェクトの作成

Tauri CLI を使って Tauriプロジェクトを作る。これは、上で作成したvite-projectで実行する。

# cargo の場合
# What it your app name -> 任意(デフォルトにした)
# What should the window title be -> 任意(デフォルトにした)
# Where are your we assets... -> ../dist
# What is the url of your dev server -> http://localhost:3000
cargo tauri init

これによりsrc-tauri以下にTauriプロジェクト(Cargoプロジェクト)が作成される。

上記コマンドだけで準備はほとんどできているが、vite の開発サーバが自動的に起動するように src-tauri/tauri.config.jsonを修正する。

{
  "build": {
    // The Tauri CLI will execute this command when you run `tauri build`.
    // This is the place to bundle your frontend and place html,css, and js files into the `distDir`.
    "beforeBuildCommand": "npm run build", <- これ
    // The Tauri CLI will execute this command when you run `tauri dev`.
    // This should start your development server.
    "beforeDevCommand": "npm run dev", // <- これ
    "devPath": "http://localhost:3000",
    "distDir": "../dist"
  },

以下のコマンドでTauriアプリを起動する。

cargo tauri dev

Command を呼び出す

CommandによってFrontendはRustと通信する。Command#[tauri::command]アトリビュートで指定する。

#[tauri::command]
fn greet(name: &str) -> String {
	format!("Hello, {}", name)
}

そして .invoke_handler() 関数と generate_handler![]マクロで関数をJavaScriptから呼べる関数として登録する。

fn main() {
  tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![greet])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

NodeJS側では@tauri-apps/apiライブラリを使ってアクセスする。

# Install
npm install @tauri-apps/api

invoke関数で呼び出すことができる。

import { invoke } from '@tauri-apps/api'

// now we can call our Command!
// Right-click the application background and open the developer tools.
// You will see "Hello, World!" printed in the console!
invoke('greet', { name: 'World' })
  // `invoke` returns a Promise
  .then((response) => console.log(response))

何も表示されないが、Viteアプリでは右クリックから開発者モードに入れる。そこのコンソールに出力されていることを確認できる。