Tauri上手体验

简单尝试了下Tauri,上手还是比较简单的,半天的时间就可以搞定一个ToDo.exe。

代码可见 github

image.png

The Tauri Bundler is a Rust harness to compile your binary, package assets, and prepare a final bundle.

It will detect your operating system and build a bundle accordingly. It currently supports: Windows, macOS, Linux.

项目启动

Tauri支持html/js, next.js, qwik, sveltekit等前端框架。

此处选择SvelteKit,跟着官网教程跑就行 Quick Start/SvelteKit

pnpm create svelte
pnpm add -D @sveltejs/adapter-static
pnpm add -D @tauri-apps/cli
pnpm tauri init
pnpm tauri dev
// svelte.config.js
- import adapter from '@sveltejs/adapter-auto'
+ import adapter from '@sveltejs/adapter-static'


// src/routes/+layout.ts
+ export const prerender = true
+ export const ssr = false

其他功能

客制化窗口标题栏

对HTML元素添加 data-tauri-drag-region 字段, 此代码可放任意位置,示例中直接放在了app.html(index.html)中。


 
 
 

给dom添加点击事件,实现最小化,全屏,关闭的功能。

注意tauri中不支持Window:prompt(), 需要用 @tauri-apps/api/dialog 实现。

import { appWindow } from '@tauri-apps/api/window';
import { ask } from '@tauri-apps/api/dialog';

export function setupBar() {
 document
  .getElementById('titlebar-minimize')
  ?.addEventListener('click', () => appWindow.minimize());
 document
  .getElementById('titlebar-maximize')
  ?.addEventListener('click', () => appWindow.toggleMaximize());
 document.getElementById('titlebar-close')?.addEventListener('click', async () => {
  (await ask('Do you really want to leave?', { title: 'System', type: 'warning' })) &&
   appWindow.close();
 });
}

同时在tauri.conf.json配置中注册dialog

  {
    "tauri": {
        "allowlist": {
            "dialog": {
                "all": true, 
                "ask": true, 
                "confirm": true, 
                "message": true,
                "open": true, 
                "save": true 
            }
        }
    }
  }

标题栏样式控制,一般固定顶部fixed

.titlebar {
 height: 30px;
 background: hsl(206, 6%, 25%);
 user-select: none;
 box-sizing: border-box;
 display: flex;
 justify-content: flex-start;
 align-items: center;
 padding: 0 8px;
 position: fixed;
 top: 0;
 left: 0;
 right: 0;
}
.titlebar:hover {
 background: hsl(206, 6%, 27%);
}

.titlebar-button {
 display: inline-flex;
 justify-content: center;
 align-items: center;
 height: 14px;
 aspect-ratio: 1/1;
 border-radius: 50%;
 transition: 0.4s;
 cursor: pointer;
}
#titlebar-close {
 margin-right: 8px;
 background-color: #ff5f56;
 box-shadow: 0 0 0 0.5px #e0443e;
}
#titlebar-close:hover {
 background-color: #fc3c32;
}
#titlebar-minimize {
 margin-right: 8px;
 background-color: #ffbd2e;
 box-shadow: 0 0 0 0.5px #dea123;
}
#titlebar-minimize:hover {
 background-color: #ffa600;
}
#titlebar-maximize {
 background-color: #27c93f;
 box-shadow: 0 0 0 0.5px #1aab29;
}
#titlebar-maximize:hover {
 background-color: #12aa29;
}

前端与Rust服务通信

src-tarui目录下编写纯函数,直接返回数据,不要加return

use chrono::{Datelike, Utc, TimeZone,Local};

const  DAY_SECONDS: i32 = 24*60*60;

#[tauri::command]
fn greet(prefix: &str) -> String {
  let time =  Local::now();
  format!("{} {}", prefix, time.format("%Y-%m-%d %H:%M:%S"))
}

#[tauri::command]
fn ask_year() -> f64 {
  let now = Utc::now();
  let (is_common_era, year )= now.year_ce();
  let start =  Utc.with_ymd_and_hms(year as i32, 01, 01, 0, 0, 0).unwrap();
  let tol =  if is_common_era { DAY_SECONDS * 365 } else { DAY_SECONDS * 366 };
  let pass = now - start;
  // println!("tol {}; pass {}", tol, pass);
  pass.num_seconds() as f64 / tol as f64
}

在main函数中注册处理函数,以数组形式添加多个。

// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

// ... code

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

在前端中使用

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

let time = '';
let per = 0;

async function setTime() {
 time = await invoke('greet', { prefix: 'Now' });
 per = await invoke('ask_year');
}

构建打包

# 按当前系统打包对应可执行文件 如windows-> .exe | .msi
pnpm tauri build

构建成功在target/release/bundle可看到文件。

打包windows平台的话,还需要安装webview2(win11应该自动安装了),以及Microsoft C++ Build Tools。

这里有个小插曲,之前是在windows的wsl2下开发的,要打包windows平台的包就要安装rust-win的工具,不过试了下并没有成功,就直接在window下开发了。

# build win in *nix
rustup toolchain install stable-x86_64-pc-windows-msvc
rustup default stable-x86_64-pc-windows-msvc
pnpm tauri build --target x86_64-pc-windows-msvc