Tauri v2 核心技术特性解析

0 阅读15分钟

执行摘要

Tauri v2 是由 Rust 语言驱动的轻量级跨平台应用程序开发框架,于 2024 年 10 月正式发布稳定版本。与前身 Tauri v1 相比,v2 版本进行了架构级重构,引入了革命性的插件系统、全面的权限管理机制、以及最重要的——原生移动端支持(iOS 和 Android)。本报告深入调研了 Tauri v2 的架构原理、核心组件、通信机制、新特性、性能优化、安全机制以及移动端支持等关键技术内容,为开发者提供全面的技术参考。

一、Tauri v2 架构原理

1.1 核心设计理念

Tauri 的设计理念建立在四个核心原则之上,这些原则决定了框架的技术方向和架构决策。

前端独立性原则:是 Tauri 架构的基石。Tauri 支持开发者使用任何前端框架(React、Vue、Svelte、Angular 等),允许开发者带入现有的 Web 技术栈而无需改变开发习惯。这种设计使得前端团队可以专注于 UI 开发,而无需学习新的领域特定语言。

跨平台兼容性原则:确保了 Tauri 应用程序能够运行在所有主流桌面和移动平台上。v2 版本支持 Linux、macOS、Windows、iOS 和 Android 五大平台,开发者可以使用单一代码库构建所有平台的应用程序。在架构层面,前端使用 JavaScript/TypeScript,应用逻辑使用 Rust,而系统集成层则使用 Swift(iOS)和 Kotlin(Android)。

最大安全性原则贯穿 Tauri 的整个设计。安全性是 Tauri 团队的首要优先事项,驱动着最大的创新。框架采用 Rust 的内存安全特性,结合精细的权限控制系统,为应用程序提供本质上的安全保证。

最小体积原则:是 Tauri 区别于 Electron 等竞品的关键差异。Tauri 使用操作系统原生的 WebView 组件来渲染 UI,而非捆绑整个浏览器引擎,这使得最终应用程序的体积可以小至 600KB,相比 Electron 的数百兆字节具有显著优势。

1.2 与 Tauri v1 的主要区别

Tauri v2 相比 v1 进行了全面的架构升级,这些变化不仅体现在功能层面,更深入到核心设计层面。

在配置结构方面,v1 版本中的 package 配置位于 tauri 对象内部,而 v2 版本将其提升到顶层对象。配置路径发生了大规模调整,例如 build.distDir 重命名为 frontendDistbuild.devPath 重命名为 devUrl。窗口相关的 fileDropEnabled 配置在 v2 中变更为 dragDropEnabled

在权限系统方面,v1 使用的 allowlist 白名单机制在 v2 中被完全废弃,取而代之的是基于 permissions、scopes 和 capabilities 的全新权限模型。新的权限系统提供了更细粒度的控制能力,支持针对特定窗口甚至远程 URL 定义作用域。

在插件系统方面,v1 版本中的核心功能(如 shell、fs、dialog、http)被内建在核心库中,而 v2 版本将这些功能全部插件化。开发者现在可以按需选择功能,实现真正的按需加载。

1.3 核心生态系统架构

Tauri 的核心生态系统由多个精密协作的组件构成,形成了完整的技术栈。

Tauri 主库:是整个框架的核心,它将所有组件整合在一起。主库在编译时读取 tauri.conf.json 配置文件,引入功能并配置应用程序,甚至包括解析项目文件夹中的 Cargo.toml 文件。在运行时,主库处理脚本注入、托管系统交互 API,并管理更新过程。

tauri-runtime:层作为 Tauri 与底层 WebView 库之间的粘合层,负责处理 WebView 与宿主之间的消息传递、托管系统交互 API、管理更新过程以及运行时脚本注入。

tauri-macros:通过代码生成 crate 为上下文、处理程序和命令创建宏,简化了开发流程。

tauri-utils:提供通用代码功能,包括配置文件解析、平台三元组检测、CSP 注入和资产管理。

tauri-codegen:负责嵌入、哈希和压缩资产,解析 tauri.conf.json 并生成 Config 结构体。

1.4 WRY 和 TAO 的关系

Tauri 底层依赖两个关键的 Rust 库来实现跨平台能力,理解它们的关系对于深入掌握 Tauri 架构至关重要。

TAO:是一个跨平台窗口创建库,支持 Windows、macOS、Linux、iOS 和 Android 五大平台。TAO 是 winit 的分支,扩展了菜单栏和系统托盘等系统集成功能。在架构关系中,TAO 负责窗口管理,与 WRY 形成协作关系。

WRY:是一个跨平台 WebView 渲染库,目前支持 Windows、macOS 和 Linux。WRY 作为抽象层,决定使用哪个 WebView 以及如何与 WebView 交互。Tauri 通过 WRY 与窗口内的 WebView 进行交互,获取渲染能力和消息传递通道。

两者的协作关系可以表示为:Tauri 通过 tauri-runtime-wry 连接 WRY 和 TAO,WRY 处理 WebView 渲染和交互,TAO 处理窗口管理和系统级交互。

1.5 与 Electron 架构对比

Tauri 和 Electron 虽然都旨在使用 Web 技术构建跨平台桌面应用,但它们的架构设计有着本质区别。

Electron 的核心是 Chromium 和 Node.js 的结合,提供了一个包含完整浏览器引擎和 JavaScript 运行时的运行时环境。Electron 应用运行一个主进程管理应用程序生命周期,生成多个渲染进程(每个窗口一个)处理 GUI。由于打包了整个 Chromium 和 Node.js,应用程序体积通常较大。

Tauri 采用完全不同的架构策略,仅使用操作系统的原生 WebView 组件(Windows 的 WebView2、macOS 的 WKWebView、Linux 的 WebKitGTK)来渲染 UI,后端逻辑使用 Rust 编写。Tauri 将前端(WebView 内运行)与后端(Rust 编写)分离,这种分离架构提高了安全性和性能,同时大幅减小了应用程序体积。

二、核心组件详解

2.1 WebView 组件

WebView 是 Tauri 应用程序的前端渲染引擎,负责显示 HTML/CSS/JavaScript 构建的用户界面。

在不同平台上,Tauri 使用不同的原生 WebView 实现。在 Windows 平台上,Tauri v2 使用 WebView2,这是基于 Microsoft Edge 和 Chromium 的现代 WebView 组件。WebView2 可以自动更新,确保用户始终拥有一个相对较新的 Chromium 版本。WebView2 支持 Windows 7 及以上版本,在 Windows 11 上已预装。对于早期版本,Tauri 安装程序会自动确保 WebView2 已正确安装。

在 macOS 和 iOS 平台上,Tauri 使用 WKWebView,这是 Apple 提供的现代化 WebView 组件,与 Safari 共享相同的渲染引擎。

在 Linux 平台上,Tauri 使用 WebKitGTK,这是 GNOME 项目的 WebKit 端口,提供与现代 Linux 桌面环境的深度集成。

WebView 的职责不仅是渲染 HTML 内容,还负责建立与 Rust 后端的通信通道。在 Tauri 架构中,WebView 通过 WRY 库与 Rust 后端进行消息传递,这种设计使得前端代码可以调用 Rust 函数并接收返回值,同时保持了良好的安全性隔离。

2.2 Rust 后端架构

Rust 后端是 Tauri 应用程序的核心,负责处理业务逻辑、系统交互和资源管理。

Rust 后端的核心组件包括命令系统、事件系统、窗口管理和插件系统。命令系统允许前端调用 Rust 函数,事件系统支持后端向前端推送消息,窗口管理负责控制应用程序窗口的生命周期,插件系统则提供了可扩展的功能模块。

Rust 后端通过 tauri::Builder 模式进行初始化和配置。典型的应用程序入口代码结构如下:

fn main() {
    tauri::Builder::default()
        .setup(|app| {
            // 初始化逻辑
            Ok(())
        })
        .invoke_handler(tauri::generate_handler![cmd_a, cmd_b])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

tauri::generate_context!() 宏在编译时读取 tauri.conf.json 配置,生成应用程序的运行时上下文,包括窗口配置、安全策略和插件设置。

2.3 IPC 通信机制

Tauri v2 的进程间通信(IPC)机制进行了彻底重写,相比 v1 版本在功能和性能上都有显著提升。

v1 版本的 IPC 使用了非常基础的 WebView 接口,迫使其将所有消息序列化为字符串,传递响应速度较慢。v2 版本使用自定义协议,在功能和性能上更接近于 WebView 处理常规基于 HTTP 的通信方式。

Tauri IPC 的核心是命令(Command)机制。命令是一种类型安全的方式,用于从 Web 应用调用 Rust 函数。命令可以接受参数并返回值,也可以返回错误和异步处理。

在 Rust 端定义命令需要使用 #[tauri::command] 属性标注:

#[tauri::command]
fn my_custom_command(invoke_message: String) -> Result<String, String> {
    if invoke_message.is_empty() {
        Err("Message cannot be empty".into())
    } else {
        Ok(format!("Received: {}", invoke_message))
    }
}

命令必须通过 tauri::generate_handler! 宏注册到构建器中,该宏接受一个命令列表作为参数。

在前端,调用命令使用 invoke 函数:

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

const result = await invoke('my_custom_command', {
    invokeMessage: 'Hello from frontend!'
});

参数命名遵循特定的转换规则:Rust 端使用 snake_case(如 invoke_message),前端使用 camelCase(如 invokeMessage)。这种转换是自动进行的,但如果需要保持一致,可以在命令定义时使用 rename_all = "snake_case" 属性。

v2 版本还引入了新的 Channel API,允许快速地从 Rust 向前端发送数据。这个 API 主要用于流式数据传输场景,如文件下载进度、实时日志等。

2.4 事件系统

Tauri 的事件系统提供了后端向前端推送消息的能力,是实现实时交互的重要机制。

在 Rust 端,事件系统通过 App 结构体的方法暴露。主要 API 包括:

listen_global 用于监听从任意窗口发出的事件:

use tauri::Manager;

let id = app.listen_global("event-name", |event| {
    println!("got event-name with payload {:?}", event.payload());
});

emit_all 用于将事件发送到前端所有 WebView 窗口:

app.emit_all("event-name", Payload { message: "Tauri is awesome!".into() }).unwrap();

unlisten 用于取消事件监听:

app.unlisten(id);

事件载荷类型必须实现 serde::SerializeClone traits,确保数据可以序列化和在多个监听器间共享。

在前端,监听事件的代码如下:

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

const unlisten = await listen<string>('backend-event', (event) => {
    console.log(event.payload);
});

// 取消监听
unlisten();

三、新特性详解

3.1 插件系统

Tauri v2 最重要的新特性之一是全新的插件系统。框架将大量核心功能转移到了插件中,开发者可以根据需求自由选择功能,让应用更加轻量化。

插件架构设计:遵循三个核心原则:使 Rust 代码能够执行特定操作、提供接口粘合剂、提供 JavaScript API 与 Rust 代码交互。

Tauri v2 提供了丰富的官方插件,覆盖了从基础功能到高级特性的广泛范围:

自动启动插件tauri-plugin-autostart允许应用程序在系统启动时自动运行,适用于需要常驻后台的应用场景。

条形码扫描器插件tauri-plugin-barcode-scanner允许移动应用使用相机扫描二维码和条形码,集成来处理移动设备的相机硬件。

生物识别插件tauri-plugin-biometric在 Android 和 iOS 上提供生物识别认证功能,支持指纹识别和面部识别。

剪贴板插件tauri-plugin-clipboard提供读取和写入系统剪贴板的能力,支持文本和图像内容。

命令行接口插件tauri-plugin-cli解析命令行界面的参数,使应用程序可以响应命令行调用。

深度链接插件tauri-plugin-deep-link将 Tauri 应用设置为特定 URL 的默认处理程序,支持自定义协议(如 myapp://)。

对话框插件tauri-plugin-dialog打开和保存文件的原生系统对话框,以及显示消息框。

文件系统插件tauri-plugin-fs提供访问文件系统的能力,支持读取、写入、创建和删除文件及目录。

全局快捷键插件tauri-plugin-global-shortcut注册全局快捷键,即使应用程序在后台运行也能响应。

HTTP 客户端插件tauri-plugin-http使用 Rust 编写的 HTTP 客户端,支持跨域请求。

本地主机插件tauri-plugin-localhost在生产应用程序中启用本地主机服务器。

日志插件tauri-plugin-log提供可配置的日志记录功能,支持多种日志目标和级别。

NFC 插件tauri-plugin-nfc在 Android 和 iOS 上读取和写入 NFC 标签。

通知插件tauri-plugin-notification向用户发送原生系统通知。

Shell 插件tauri-plugin-shell访问系统 Shell,使用默认应用程序管理文件和 URL,以及生成子进程。

单实例插件tauri-plugin-single-instance确保 Tauri 应用同时只运行一个实例。

SQL 插件tauri-plugin-sql提供前端与 SQL 数据库通信的接口,支持 SQLite 等数据库。

存储插件tauri-plugin-store提供持久化的键值存储。

Stronghold 插件tauri-plugin-stronghold提供加密、安全的数据库,适用于存储敏感数据。

系统托盘插件tauri-plugin-system-tray系统托盘功能,允许应用在系统托盘区域显示图标和菜单。

更新器插件tauri-plugin-updater应用内更新功能,支持检查和安装新版本。

WebSocket 插件tauri-plugin-websocket在 JavaScript 中使用 Rust 客户端打开 WebSocket 连接。

窗口自定义插件tauri-plugin-window-customization自定义窗口外观和行为。

窗口状态插件tauri-plugin-window-state保存和恢复窗口大小和位置。

3.2 多窗口支持

Tauri v2 引入了多窗口支持,允许应用程序创建和管理多个窗口。

在 Tauri v2 中,创建新窗口使用 WebviewWindow 类:

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

const webview = new WebviewWindow('my-label', {
    url: 'index.html',
    title: 'My Window',
    width: 800,
    height: 600,
    center: true
});

webview.once('tauri://created', function() {
    console.log('Window created successfully');
});

webview.once('tauri://error', function(e) {
    console.error('Error creating window:', e);
});

每个窗口通过唯一的 label 标识,可以独立控制其属性和行为。

窗口配置参数包括:

参数说明
url窗口加载的页面路径或 URL
title窗口标题
width窗口宽度
height窗口高度
minWidth窗口最小宽度
minHeight窗口最小高度
x窗口相对于屏幕左侧的坐标
y窗口相对于屏幕顶端的坐标
center是否居中显示
resizable是否支持缩放
maximized是否最大化
decorations是否显示窗口装饰(标题栏等)
alwaysOnTop是否置顶显示
visible是否可见

3.3 权限管理系统

Tauri v2 建立了全新的权限、作用域和能力(Capabilities)系统,用于约束前端行为,保护应用程序安全。

权限Permissions 是针对插件而言的,用来描述插件中命令的访问权限。权限可以使命令在 Tauri 应用的前端可访问,将作用域映射到命令并定义哪些命令是启用的。权限可以启用或拒绝某些命令、定义作用域或两者结合。

能力Capabilities 是 Tauri 或插件所提供的,是针对应用开发者而言的。能力是一组权限的组合,通过各自的标签映射到应用程序窗口和 WebView。能力可以影响多个窗口和 WebView,可以在多个能力中被引用。通过配置能力,可以逐步启用 Tauri 或插件的功能。

运行时权限执行流程:当一个窗口通过 invoke 调用后端命令时,请求首先经过 IPC 处理器,检查当前窗口是否有相应的能力,有对应命令的权限则传回后端执行命令,无权限则拒绝调用。

配置能力需要在 src-tauri/capabilities 目录下创建 JSON 文件:

{
  "$schema": "../../src-tauri/gen/schemas/desktop-schema.json",
  "identifier": "desktop-capability",
  "platforms": ["macOS", "windows", "linux"],
  "windows": ["main"],
  "permissions": [
    "global-shortcut:allow-is-registered",
    "global-shortcut:allow-register",
    "global-shortcut:allow-unregister",
    "core:window:allow-get-all-windows",
    "core:window:allow-set-decorations",
    "core:window:allow-set-fullscreen"
  ]
}

然后在 tauri.conf.jsonapp.security 下启用能力:

{
  "app": {
    "security": {
      "csp": null,
      "capabilities": ["desktop-capability"]
    }
  }
}

核心插件的权限标识必须以 core: 前缀或使用 core:default

四、性能优化与安全特性

4.1 性能优化

Tauri v2 在性能方面进行了多层面的优化,主要体现在以下几个方面。

应用程序体积优化是 Tauri 最大的性能优势。由于使用系统原生的 WebView 而非捆绑浏览器引擎,Tauri 应用程序的体积可以小至 600KB,相比 Electron 通常需要的数百兆字节具有数量级的优势。这不仅减少了存储空间占用,还加快了下载和安装速度。

内存使用优化得益于 Rust 的高效内存管理和轻量级运行时。Tauri 应用通常消耗较少的内存,因为它们由原生 WebView 和轻量级的 Rust 后端驱动,而非完整的浏览器实例。

启动时间优化得益于较小的应用程序体积和原生 WebView 的使用。Tauri 应用的启动速度通常比 Electron 应用快得多,因为它们不需要启动整个浏览器引擎。

IPC 性能优化是 v2 版本的重点改进。新的 IPC 机制使用自定义协议,支持原始数据传输,在功能和性能上更接近于 WebView 处理常规基于 HTTP 的通信方式。对于需要传输大量数据的应用场景,如文件处理、流媒体等,性能提升尤为显著。

批量处理建议:合并多个小请求、使用数据缓存、实现增量更新可以进一步提升性能。

消息优化建议:减少消息大小、使用二进制格式、实现消息压缩。

并发处理:利用 Rust 异步特性、实现并行处理、避免阻塞操作。

4.2 安全特性

Tauri 的安全模型建立在多层防护之上,为应用程序提供全面的安全保护。

架构级安全:Tauri 将 WebView/UI 与后端/逻辑隔离,从本质上降低了与安全漏洞相关的风险。相比之下,Electron 的主进程对系统具有完全访问权限,如果处理不当可能会引入安全隐患。

Rust 内存安全:Rust 语言的所有权系统和生命周期检查确保了内存访问的安全性,消除了空指针解引用、数据竞争等常见安全漏洞。

漏洞表面控制:由于使用系统的原生 WebView 组件,而不是内置和打包的完整浏览器引擎,Tauri 的漏洞表面积较小。系统 WebView 会随操作系统自动更新,用户可以及时获得安全修复。

精细权限控制:新的权限系统支持针对特定窗口、远程 URL 甚至具体命令定义访问范围,实现了最小权限原则。

安全最佳实践包括:

// 权限结构定义
#[derive(Debug, Serialize, Deserialize)]
struct Permissions {
    fs_access: bool,
    network_access: bool,
    shell_access: bool,
}

// 安全配置
fn main() {
    tauri::Builder::default()
        .setup(|app| {
            app.manage(tauri::SecurityConfig::default()
                .with_csp("default-src 'self'")
                .with_dangerous_allow_asset_csp_modification(false)
            );
            Ok(())
        })
        .invoke_handler(tauri::generate_handler![check_permissions])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

输入验证:验证所有输入参数、限制文件访问、防止注入攻击。

数据加密:使用强加密算法(如 Argon2、ChaCha20Poly1305)、安全的密钥管理、加密传输数据。

五、移动端支持

5.1 iOS 和 Android 支持

Tauri v2 最引人注目的新特性是对移动平台的支持,现在可以使用同一代码库开发 iOS 和 Android 应用。

Tauri 团队调查并尝试了不同的移动支持解决方案,最终决定使用两大移动操作系统的原生语言(Swift 和 Kotlin)为 Rust 代码构建界面。这种设计允许开发者复用 Swift 或 Kotlin 应用程序中与系统交互的现有逻辑,并将其暴露给 Rust 或前端。

移动端开发的前置依赖包括:

  • Rust 环境(iOS 交叉编译需要 macOS)
  • Xcode(iOS 开发)
  • Android Studio 和 Android SDK(Android 开发)
  • 平台特定的系统依赖

5.2 移动端原生 API

Tauri v2 为移动端提供了丰富的原生 API 支持,这些 API 通过官方插件的形式提供。

通知 API允许向用户发送原生系统通知,支持标题、正文、图标等通知元素。

对话框 API提供原生对话框支持,包括警告对话框、确认对话框、输入对话框等。

NFC API支持在 Android 和 iOS 上读取和写入 NFC 标签,适用于近场通信应用。

条形码扫描器 API允许移动应用使用相机扫描二维码和条形码。

生物识别 API在 Android 和 iOS 上提供生物识别认证功能,支持指纹识别和 Face ID。

剪贴板 API读取和写入系统剪贴板,支持文本内容。

深度链接 API将 Tauri 应用设置为特定 URL 的默认处理程序,支持自定义协议(如 myapp://)。

5.3 移动端项目配置

要在 Tauri v2 项目中添加 iOS 和 Android 支持,需要进行以下配置。

首先,在 Cargo.toml 中添加移动平台支持:

[lib]
crate-type = ["staticlib", "cdylib", "rlib"]

其次,重命名 main.rslib.rs,并创建新的 main.rs 调用 run() 方法:

// lib.rs
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

// main.rs
fn main() {
    tauri_plugin_example_lib::run();
}

六、最佳实践与开发流程

6.1 开发环境搭建

开发 Tauri 应用需要安装以下依赖:

Rust 环境

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

系统依赖(Ubuntu)

sudo apt update
sudo apt install libwebkit2gtk-4.0-dev \
    build-essential \
    curl \
    wget \
    file

Windows 平台需要安装 Visual Studio Build Tools(包含 C++ 构建工具和 Windows 10 SDK)以及 WebView2 运行时。

macOS 平台需要安装 Xcode Command Line Tools。

6.2 项目创建

使用 create-tauri-app 脚手架可以快速创建新项目:

npm create tauri-app@latest my-app

脚手架会提示选择前端框架(vanilla、Vue、React、Svelte 等),然后自动生成项目结构。

项目主要目录结构:

my-app/
├── src/                 # 前端源代码
├── src-tauri/          # Rust 后端代码
│   ├── src/
│   │   ├── lib.rs     # Rust 库入口
│   │   └── main.rs    # Rust 程序入口
│   ├── Cargo.toml     # Rust 依赖配置
│   ├── tauri.conf.json # Tauri 配置
│   └── capabilities/   # 权限能力配置
├── package.json        # 前端依赖配置
└── vite.config.ts      # Vite 配置

6.3 命令开发模式

推荐使用命令模式进行前后端分离开发。

Rust 端命令定义

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
pub struct UserInfo {
    pub id: u64,
    pub name: String,
    pub email: String,
}

#[tauri::command]
pub async fn get_user(user_id: u64) -> Result<UserInfo, String> {
    // 模拟数据库查询
    Ok(UserInfo {
        id: user_id,
        name: "Alice".to_string(),
        email: "alice@example.com".to_string(),
    })
}

#[tauri::command]
pub async fn save_user(user: UserInfo) -> Result<(), String> {
    // 模拟保存操作
    println!("Saving user: {:?}", user);
    Ok(())
}

注册命令

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![get_user, save_user])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

前端调用

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

interface UserInfo {
    id: number;
    name: string;
    email: string;
}

// 调用命令
const user = await invoke<UserInfo>('get_user', { userId: 1 });
console.log(`User: ${user.name} (${user.email})`);

// 保存数据
await invoke('save_user', {
    user: {
        id: 1,
        name: 'Alice',
        email: 'alice@example.com'
    }
});

6.4 异步命令处理

对于耗时的操作,推荐使用异步命令:

#[tauri::command]
async fn fetch_data(url: String) -> Result<String, String> {
    // 使用 reqwest 或其他 HTTP 客户端
    let response = reqwest::get(&url)
        .await
        .map_err(|e| e.to_string())?;
    let body = response.text().await.map_err(|e| e.to_string())?;
    Ok(body)
}

前端调用时可以直接使用 async/await:

const data = await invoke('fetch_data', {
    url: 'https://api.example.com/data'
});

6.5 状态管理

Tauri 支持使用状态(State)来共享数据:

use std::sync::Mutex;

struct AppState {
    counter: Mutex<i32>,
}

#[tauri::command]
fn increment(state: tauri::State<AppState>) -> Result<i32, String> {
    let mut counter = state.counter.lock().map_err(|e| e.to_string())?;
    *counter += 1;
    Ok(*counter)
}

#[tauri::command]
fn get_counter(state: tauri::State<AppState>) -> Result<i32, String> {
    let counter = state.counter.lock().map_err(|e| e.to_string())?;
    Ok(*counter)
}

pub fn run() {
    tauri::Builder::default()
        .manage(AppState {
            counter: Mutex::new(0),
        })
        .invoke_handler(tauri::generate_handler![increment, get_counter])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

6.6 调试技巧

Rust 控制台输出:在 Rust 代码中使用 println! 宏输出日志,在开发服务器终端中查看。

WebView 调试:Tauri 支持使用浏览器开发工具调试 WebView 内容。在 tauri.conf.json 中启用调试:

{
  "app": {
    "withGlobalTauri": true
  }
}

然后可以使用 Chrome DevTools 或 Safari Web Inspector 连接调试。

日志记录:推荐使用 tauri-plugin-log 插件:

tauri::Builder::default()
    .plugin(tauri_plugin_log::Builder::default()
        .targets([LogTarget::LogDir, LogTarget::Stdout])
        .build())
    .run(tauri::generate_context!())
    .expect("error while running tauri application");

6.7 生产构建

使用 tauri build 命令进行生产构建:

npm run tauri build

构建产物位于 src-tauri/target/release/ 目录(发布构建)或 src-tauri/target/debug/ 目录(调试构建)。

打包配置tauri.conf.json 中进行:

{
  "productName": "My App",
  "version": "1.0.0",
  "bundle": {
    "identifier": "com.example.myapp",
    "active": true,
    "targets": "all",
    "icon": [
      "icons/32x32.png",
      "icons/128x128.png",
      "icons/128x128@2x.png",
      "icons/icon.icns",
      "icons/icon.ico"
    ]
  }
}

七、从 v1 迁移指南

7.1 主要变更概述

从 Tauri v1 迁移到 v2 需要注意以下主要变化:

变更类别v1v2
配置根键tauriapp
打包配置位置tauri.bundle顶层 bundle
白名单tauri.allowlistpermissions/capabilities
窗口类名Window, WindowBuilderWebviewWindow, WebviewWindowBuilder
前端 API 路径@tauri-apps/api/tauri@tauri-apps/api/core

7.2 配置迁移

tauri.conf.json 的结构发生了大幅调整:

v1 配置

{
  "tauri": {
    "package": {
      "productName": "My App",
      "version": "1.0.0"
    },
    "allowlist": {
      "all": false,
      "shell": { "open": true }
    },
    "bundle": { ... },
    "windows": [ ... ]
  }
}

v2 配置

{
  "productName": "My App",
  "version": "1.0.0",
  "bundle": { ... },
  "app": {
    "security": {
      "csp": null,
      "capabilities": ["default"]
    }
  },
  "frontendDist": "../dist",
  "devUrl": "http://localhost:1420"
}

7.3 权限迁移

v1 的 allowlist 机制被完全废弃,需要迁移到新的 permissions 和 capabilities 系统。

创建 capabilities 文件 src-tauri/capabilities/default.json

{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "Default permissions for the app",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "shell:allow-open"
  ]
}

7.4 前端 API 迁移

v1v2
@tauri-apps/api/tauri@tauri-apps/api/core
@tauri-apps/api/window@tauri-apps/api/webviewWindow
@tauri-apps/api/dialog@tauri-apps/plugin-dialog
@tauri-apps/api/fs@tauri-apps/plugin-fs
@tauri-apps/api/http@tauri-apps/plugin-http
listen_globallisten_any

7.5 Rust API 迁移

v1v2
tauri::api::pathtauri::Manager::path
tauri::Windowtauri::WebviewWindow
tauri::WindowBuildertauri::WebviewWindowBuilder
tauri::SystemTraytauri::tray 模块

八、总结与展望

Tauri v2 代表了跨平台桌面应用开发框架的一次重大飞跃。通过全面采用插件化架构、重构的权限系统、以及革命性的移动端支持,Tauri v2 为开发者提供了一个现代化、高效、安全的应用程序开发平台。

核心优势总结

Tauri v2 的体积优势是其最显著的特点,使用系统原生 WebView 使得应用程序可以小至 600KB,相比 Electron 的数百兆字节具有压倒性的优势。Rust 语言带来的内存安全和性能提升,以及精细的权限控制系统,共同构建了 Tauri 的安全壁垒。

适用场景

Tauri v2 特别适合以下场景:对应用体积和性能要求高的项目、需要良好安全性的应用、团队具备 Rust 开发能力、项目从零开始开发且希望支持多平台。

生态系统发展

虽然 Tauri 的生态系统相比 Electron 仍处于早期阶段,但其发展速度令人瞩目。官方插件库的丰富、社区贡献的增长、以及活跃的开发社区都在推动 Tauri 生态系统的快速成熟。

未来展望

随着移动端支持的成熟和更多企业级应用采用 Tauri,预计其生态系统将持续扩展。Tauri 团队对安全性的持续关注、插件系统的不断完善,以及与现代 Web 开发工作流的深度集成,都将推动 Tauri 成为跨平台应用开发的首选框架。