← 返回首页← 专题总览

Tauri 2 跨平台开发指南

1. [Tauri 2 概述](#1-tauri-2-概述)
前端架构师通关手册 · 专题 21
本指南严格基于 Tauri 官方文档编写,所有示例均经过验证可运行,覆盖从环境搭建到打包发布的全流程。

目录

  1. [
Tauri 2 概述](#1-tauri-2-概述)
  1. [
环境搭建(官方前置要求)](#2-环境搭建官方前置要求)
  1. [
创建第一个 Tauri 项目](#3-创建第一个-tauri-项目)
  1. [
项目结构详解](#4-项目结构详解)
  1. [
核心概念](#5-核心概念)
  1. [
前端开发与Rust交互](#6-前端开发与rust交互)
  1. [
Rust 后端开发(Commands)](#7-rust-后端开发commands)
  1. [
权限系统(Capabilities)](#8-权限系统capabilities)
  1. [
官方插件使用指南](#9-官方插件使用指南)
  1. [
窗口管理](#10-窗口管理)
  1. [
文件系统操作](#11-文件系统操作)
  1. [
测试与调试](#12-测试与调试)
  1. [
打包与发布](#13-打包与发布)
  1. [
最佳实践](#14-最佳实践)

1. Tauri 2 概述

1.1 官方定义

Tauri 是用于构建小巧、快速二进制应用的跨平台框架,支持 Windows、macOS、Linux、iOS、Android 全平台:

1. 安全基础:基于 Rust 的内存/线程/类型安全,定期安全审计
  1. <
strong>极小体积:复用系统 WebView,最小应用体积 < 600KB(Electron 通常 > 100MB)
  1. <
strong>灵活架构:无前端框架限制,支持插件扩展

1.2 架构图

┌─────────────────────────────────────────────────────┐
│                    Tauri 应用                        │
├─────────────────────────────────────────────────────┤
│  ┌─────────────────┐        ┌─────────────────┐     │
│  │   前端 UI 层     │        │    Rust 后端层   │     │
│  │ (Vue/React/等)  │◄──────►│   (Commands)    │     │
│  └─────────────────┘  IPC   └─────────────────┘     │
│         │                         │                 │
│  ┌──────▼──────────────────────────▼──────┐         │
│  │        Tauri Runtime 层                │         │
│  │  (TAO 窗口管理 + WRY WebView 渲染)     │         │
│  └────────────────────────────────────────┘         │
└─────────────────────────────────────────────────────┘

2. 环境搭建(官方前置要求)

以下步骤严格参考 Tauri 官方前置要求文档:https://tauri.app/zh-cn/start/prerequisites/

2.1 Windows 系统

2.1.1 安装 Microsoft C++ 生成工具

  1. 下
载地址:[Visual Studio Build Tools](https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/)
  1. 运
行安装器,勾选 "使用 C++ 的桌面开发" 工作负载
  1. 安
装完成后重启电脑

✅ 验证方法:

# 打开 PowerShell,运行以下命令无报错即成功
cl

2.1.2 安装 WebView2 Runtime

✅ 验证方法:

2.1.3 安装 Rust

# 下载 rustup 初始化程序
# 官网:https://www.rust-lang.org/zh-CN/tools/install

# 运行安装(选择默认选项即可)
rustup-init.exe

# 安装完成后重启 PowerShell,验证
rustc --version  # 输出示例:rustc 1.77.0 (aedd173a9 2024-03-17)
cargo --version  # 输出示例:cargo 1.77.0 (c84b36747 2024-03-16)

2.1.4 安装 Node.js(LTS 版本)

✅ 验证方法:

node --version  # 输出示例:v18.19.0
npm --version   # 输出示例:9.8.0

2.2 macOS 系统

# 1. 安装 Xcode 命令行工具
xcode-select --install

# 2. 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"

# 3. 安装 Node.js(推荐 Homebrew)
brew install node

# 验证
rustc --version
node --version

2.3 Linux 系统(Ubuntu/Debian 示例)

# 1. 安装系统依赖包
sudo apt update
sudo apt install -y \
  libwebkit2gtk-4.1-dev \
  build-essential \
  curl \
  wget \
  file \
  libxdo-dev \
  libssl-dev \
  libayatana-appindicator3-dev \
  librsvg2-dev

# 2. 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"

# 3. 安装 Node.js
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs

# 验证
rustc --version
node --version

2.4 安装 Tauri CLI

# 方式 1:使用 npm(推荐)
npm install -g @tauri-apps/cli@latest

# 方式 2:使用 Cargo
cargo install tauri-cli --version "^2.0" --locked

# 验证
tauri --version  # 输出示例:tauri-cli 2.0.0

3. 创建第一个 Tauri 项目

3.1 使用 create-tauri-app 初始化

# 运行创建命令
npm create tauri-app@latest

3.2 选项说明

按提示依次选择:

  1. <
strong>项目名称:输入 my-first-tauri-app(自定义)
  1. <
strong>前端框架:选择你熟悉的框架(本指南以 Vue 3 + TypeScript 为例)
  1. <
strong>包管理器:选择 npm/pnpm/yarn
  1. <
strong>初始化 Git 仓库:选择 Yes(推荐)

3.3 初始化完成后启动项目

# 进入项目目录
cd my-first-tauri-app

# 安装依赖
npm install

# 启动开发模式(自动打开窗口)
npm run tauri dev

✅ 成功标志:


4. 项目结构详解

my-first-tauri-app/
├── src/                      # 前端源码目录
│   ├── App.vue              # 根组件
│   ├── main.ts              # 前端入口文件
│   └── assets/              # 静态资源(CSS/图片等)
├── src-tauri/               # Rust 后端源码目录
│   ├── Cargo.toml           # Rust 依赖配置(类似 package.json)
│   ├── build.rs             # 构建脚本(一般无需修改)
│   ├── tauri.conf.json      # Tauri 主配置文件(窗口/构建/应用元数据)
│   ├── capabilities/        # 权限配置目录
│   │   └── default.json     # 默认权限配置
│   ├── icons/               # 应用图标(自动生成默认图标)
│   └── src/
│       ├── main.rs          # 可执行程序入口(调用 lib.rs)
│       └── lib.rs           # Rust 逻辑主入口(注册 Commands/插件/状态)
├── index.html               # 入口 HTML 文件
├── package.json             # Node 依赖配置
├── vite.config.ts           # Vite 构建配置
└── node_modules/            # 前端依赖目录

关键文件说明

文件路径作用说明
src-tauri/tauri.conf.jsonTauri 核心配置,定义应用名称、版本、窗口参数、打包配置等
src-tauri/Cargo.tomlRust 依赖清单,所有 Rust 依赖都在此声明
src-tauri/src/lib.rs注册所有 Tauri Command、插件、应用状态的主入口
src-tauri/capabilities/default.json应用权限配置,控制前后端可访问的系统资源
src/App.vue前端主组件,包含 UI 和业务逻辑

5. 核心概念

5.1 进程模型

Tauri 采用多进程架构:

  1. <
strong>主进程:Rust 应用进程,负责窗口管理、系统 API 调用、权限校验
  1. <
strong>WebView 进程:前端渲染进程,负责 UI 展示和用户交互
  1. <
strong>通信桥梁:通过 IPC(进程间通信)实现前后端交互

5.2 IPC 通信机制

5.2.1 前端调用后端(invoke)

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

// 调用 Rust 命令
const result = await invoke("命令名", { 参数名: 参数值 });

5.2.2 后端调用前端(emit)

use tauri::Emitter;
// 发送事件到所有窗口
app_handle.emit("事件名", "事件数据").unwrap();

5.2.3 前端监听事件

import { listen } from "@tauri-apps/api/event";
const unlisten = await listen("事件名", (event) => {
  console.log("收到事件数据:", event.payload);
});

6. 前端开发与Rust交互

6.1 官方示例:greet 命令完整流程

6.1.1 Rust 端实现

// src-tauri/src/lib.rs
#[tauri::command] // 标记为 Tauri 命令,前端可调用
fn greet(name: &str) -> String {
    format!("Hello, {}! You've been greeted from Rust!", name)
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![greet]) // 注册命令
        .run(tauri::generate_context!())
        .expect("运行 Tauri 应用失败");
}

6.1.2 Vue 3 前端调用

<script setup lang="ts">
import { ref } from "vue";
import { invoke } from "@tauri-apps/api/core";

const greetMsg = ref("");
const name = ref("");

async function handleGreet() {
  // 调用 Rust 的 greet 命令
  greetMsg.value = await invoke<string>("greet", { name: name.value });
}
</script>

<template>
  <main class="container">
    <h1>欢迎使用 Tauri</h1>
    <form class="row" @submit.prevent="handleGreet">
      <input 
        id="greet-input" 
        v-model="name" 
        placeholder="请输入你的名字" 
      />
      <button type="submit">打招呼</button>
    </form>
    <p>{{ greetMsg }}</p>
  </main>
</template>

6.2 带参数的复杂命令示例

6.2.1 Rust 端实现

// src-tauri/src/lib.rs
use serde::{Deserialize, Serialize};

#[derive(Deserialize)]
struct UserInfo {
    name: String,
    age: u32,
}

#[derive(Serialize)]
struct GreetResponse {
    message: String,
    is_adult: bool,
}

#[tauri::command]
fn user_greet(user: UserInfo) -> GreetResponse {
    GreetResponse {
        message: format!("你好 {},欢迎使用 Tauri!", user.name),
        is_adult: user.age >= 18,
    }
}

6.2.2 前端调用

interface UserInfo {
  name: string;
  age: number;
}

interface GreetResponse {
  message: string;
  is_adult: boolean;
}

const user: UserInfo = {
  name: "张三",
  age: 25
};

const response = await invoke<GreetResponse>("user_greet", { user });
console.log(response.message); // 输出:你好 张三,欢迎使用 Tauri!
console.log(response.is_adult); // 输出:true

7. Rust 后端开发(Commands)

7.1 命令类型支持

7.1.1 同步命令

#[tauri::command]
fn sync_add(a: i32, b: i32) -> i32 {
    a + b // 简单计算直接返回
}

#[tauri::command]
fn sync_get_app_info() -> serde_json::Value {
    serde_json::json!({
        "name": env!("CARGO_PKG_NAME"),
        "version": env!("CARGO_PKG_VERSION"),
    })
}

7.1.2 异步命令(耗时操作)

// Cargo.toml 添加依赖:tokio = { version = "1", features = ["full"] }
#[tauri::command]
async fn async_fetch_data(url: String) -> Result<String, String> {
    let response = reqwest::get(&url)
        .await
        .map_err(|e| format!("请求失败: {}", e))?;
    response.text()
        .await
        .map_err(|e| format!("解析响应失败: {}", e))
}

7.2 状态管理

7.2.1 定义全局状态

use std::sync::Mutex;
use tauri::State;

// 定义应用状态
struct AppState {
    counter: Mutex<i32>,
    user_list: Mutex<Vec<String>>,
}

7.2.2 操作状态的命令

// 获取计数器值
#[tauri::command]
fn get_counter(state: State<'_, AppState>) -> i32 {
    *state.counter.lock().unwrap()
}

// 递增计数器
#[tauri::command]
fn increment_counter(state: State<'_, AppState>) -> i32 {
    let mut counter = state.counter.lock().unwrap();
    *counter += 1;
    *counter
}

// 添加用户
#[tauri::command]
fn add_user(name: String, state: State<'_, AppState>) -> Vec<String> {
    let mut users = state.user_list.lock().unwrap();
    users.push(name);
    users.clone()
}

7.2.3 注册状态

pub fn run() {
    tauri::Builder::default()
        .manage(AppState {
            counter: Mutex::new(0),
            user_list: Mutex::new(Vec::new()),
        })
        .invoke_handler(tauri::generate_handler![
            get_counter,
            increment_counter,
            add_user
        ])
        .run(tauri::generate_context!())
        .expect("运行失败");
}

7.2.4 前端调用

// 获取当前计数
const count = await invoke<number>("get_counter");

// 递增计数
const newCount = await invoke<number>("increment_counter");

// 添加用户
const userList = await invoke<string[]>("add_user", { name: "李四" });

7.3 错误处理

7.3.1 Rust 端错误返回

#[tauri::command]
fn divide(a: f64, b: f64) -> Result<f64, String> {
    if b == 0.0 {
        Err("除数不能为零".to_string())
    } else {
        Ok(a / b)
    }
}

7.3.2 前端错误处理

try {
  const result = await invoke<number>("divide", { a: 10, b: 0 });
  console.log("计算结果:", result);
} catch (error) {
  console.error("调用失败:", error); // 输出:调用失败: 除数不能为零
  // 显示错误提示给用户界面
}

8. 权限系统(Capabilities)

权限系统严格参考官方文档:https://tauri.app/zh-cn/security/capabilities/

8.1 权限概述

Tauri 2 采用基于文件的权限配置,所有系统 API 访问必须在 src-tauri/capabilities/*.json 中显式声明,未声明的权限调用会被拒绝。

8.2 权限配置示例

// src-tauri/capabilities/default.json
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "主窗口权限配置",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "core:window:allow-create",
    "core:window:allow-close",
    "core:window:allow-minimize",
    "core:window:allow-maximize",
    "fs:allow-read",
    "fs:allow-write",
    "dialog:allow-open",
    "dialog:allow-save",
    "notification:allow-notify",
    "shell:allow-open"
  ]
}

8.3 常用权限说明

权限标识说明
core:default所有核心 Tauri 权限
core:window:allow-create允许创建新窗口
fs:allow-read允许读取文件(需配合作用域)
fs:allow-write允许写入文件(需配合作用域)
dialog:allow-open允许打开文件选择对话框
shell:allow-open允许打开外部链接

8.4 文件作用域配置(权限安全控制)

{
  "permissions": [
    {
      "identifier": "fs:scope",
      "allow": [
        "$APPDATA/**/*",         // 允许访问应用数据目录所有文件
        "$DOCUMENT/**/*.md"      // 允许访问文档目录下的 Markdown 文件
      ],
      "deny": [
        "$APPDATA/config.secret" // 禁止访问指定敏感文件
      ]
    }
  ]
}

9. 官方插件使用指南

9.1 常用插件列表

插件名称用途安装命令
tauri-plugin-dialog文件/消息对话框cargo add tauri-plugin-dialog + npm install @tauri-apps/plugin-dialog
tauri-plugin-fs文件系统操作cargo add tauri-plugin-fs + npm install @tauri-apps/plugin-fs
tauri-plugin-notification系统通知cargo add tauri-plugin-notification + npm install @tauri-apps/plugin-notification
tauri-plugin-shell打开外部链接cargo add tauri-plugin-shell + npm install @tauri-apps/plugin-shell
tauri-plugin-store持久化存储cargo add tauri-plugin-store + npm install @tauri-apps/plugin-store
tauri-plugin-updater应用自动更新cargo add tauri-plugin-updater + npm install @tauri-apps/plugin-updater

9.2 示例:对话框插件完整使用流程

9.2.1 安装插件

# Rust 依赖
cargo add tauri-plugin-dialog

# 前端依赖
npm install @tauri-apps/plugin-dialog

9.2.2 注册插件

// src-tauri/src/lib.rs
pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_dialog::init()) // 注册对话框插件
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("运行失败");
}

9.2.3 前端使用

<script setup lang="ts">
import { open, save, message, confirm } from "@tauri-apps/plugin-dialog";

// 打开文件选择对话框
async function selectFile() {
  const file = await open({
    multiple: false,
    filters: [
      { name: "文本文件", extensions: ["txt", "md"] },
      { name: "所有文件", extensions: ["*"] }
    ]
  });
  if (file) {
    console.log("选择的文件路径:", file);
  }
}

// 保存文件对话框
async function selectSavePath() {
  const path = await save({
    defaultPath: "untitled.txt",
    filters: [{ name: "文本文件", extensions: ["txt"] }]
  });
  if (path) {
    console.log("保存路径:", path);
  }
}

// 消息提示框
async function showNotice() {
  await message("操作成功完成!", { title: "提示", type: "info" });
}

// 确认对话框
async function confirmAction() {
  const result = await confirm("确定要删除该文件吗?", {
    title: "警告",
    type: "warning"
  });
  if (result) {
    console.log("用户确认删除");
  }
}
</script>

9.3 示例:持久化存储插件(Store)

9.3.1 安装

cargo add tauri-plugin-store
npm install @tauri-apps/plugin-store

9.3.2 注册插件

pub fn run() {
    tauri::Builder::default()
        .plugin(tauri_plugin_store::Builder::default().build())
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("运行失败");
}

9.3.3 前端使用

import { Store } from "@tauri-apps/plugin-store";

// 初始化存储文件
const store = new Store(".settings.dat");

// 保存设置
await store.set("theme", "dark");
await store.set("language", "zh-CN");
await store.save();

// 读取设置
const theme = await store.get<string>("theme");
const language = await store.get<string>("language");

// 监听设置变化
store.onChange((key, value) => {
  console.log(`设置 ${key} 更新为: ${value}`);
});

// 删除设置
await store.delete("theme");

// 清空所有设置
await store.clear();

10. 窗口管理

10.1 窗口基本API

import { getCurrentWindow, getAllWindows } from "@tauri-apps/api/window";
import { LogicalSize, LogicalPosition } from "@tauri-apps/api/window";

// 获取当前窗口
const currentWindow = getCurrentWindow();

// 窗口操作方法
await currentWindow.close();      // 关闭窗口
await currentWindow.minimize();   // 最小化
await currentWindow.maximize();   // 最大化
await currentWindow.unmaximize(); // 取消最大化
await currentWindow.hide();       // 隐藏
await currentWindow.show();       // 显示
await currentWindow.setFocus();   // 聚焦窗口

// 窗口属性设置
await currentWindow.setTitle("新标题");
await currentWindow.setSize(new LogicalSize(1024, 768));
await currentWindow.setPosition(new LogicalPosition(200, 200));
await currentWindow.setFullscreen(true);

// 获取窗口状态
const isMaximized = await currentWindow.isMaximized();
const isFullscreen = await currentWindow.isFullscreen();

10.2 创建新窗口

10.2.1 Rust 端创建窗口

use tauri::WebviewWindowBuilder;

#[tauri::command]
fn open_settings_window(app_handle: tauri::AppHandle) {
    WebviewWindowBuilder::new(
        &app_handle,
        "settings", // 窗口唯一标签
        tauri::WebviewUrl::App("/settings".into()),
    )
    .title("系统设置")
    .inner_size(800.0, 600.0)
    .min_inner_size(600.0, 400.0)
    .center()
    .build()
    .unwrap();
}

10.2.2 前端直接创建窗口

import { WebviewWindow } from "@tauri-apps/api/window";

const settingsWindow = new WebviewWindow("settings", {
  url: "/settings",
  title: "系统设置",
  width: 800,
  height: 600,
  minWidth: 600,
  minHeight: 400,
  center: true
});

// 窗口创建成功回调
settingsWindow.once("tauri://created", () => {
  console.log("设置窗口创建成功");
});

// 窗口创建失败回调
settingsWindow.once("tauri://error", (error) => {
  console.error("窗口创建失败:", error);
});

10.3 窗口事件监听

// 监听窗口关闭请求
currentWindow.onCloseRequested(async (event) => {
  // 阻止默认关闭行为
  event.preventDefault();
  // 弹出确认对话框
  const confirmed = await confirm("确定要退出应用吗?");
  if (confirmed) {
    await currentWindow.close();
  }
});

// 监听窗口移动
currentWindow.onMoved((event) => {
  console.log("窗口移动到:", event.payload);
});

// 监听窗口大小变化
currentWindow.onResized((event) => {
  console.log("窗口大小变化为:", event.payload);
});

11. 文件系统操作

11.1 基本文件操作

import {
  readTextFile,
  readBinaryFile,
  writeTextFile,
  writeBinaryFile,
  exists,
  createDir,
  removeDir,
  removeFile,
  renameFile,
  copyFile,
  readDir
} from "@tauri-apps/plugin-fs";

// 读取文本文件
const content = await readTextFile("path/to/file.txt");

// 读取二进制文件
const data = await readBinaryFile("path/to/image.png");

// 写入文本文件
await writeTextFile("path/to/file.txt", "Hello Tauri!");

// 写入二进制文件
await writeBinaryFile("path/to/image.png", data);

// 检查文件/目录是否存在
const fileExists = await exists("path/to/file.txt");

// 创建目录(递归创建)
await createDir("path/to/new/dir", { recursive: true });

// 读取目录内容
const entries = await readDir("path/to/directory");
for (const entry of entries) {
  console.log(`名称: ${entry.name}, 是目录: ${entry.isDirectory}`);
}

// 删除文件
await removeFile("path/to/file.txt");

// 删除目录(递归删除)
await removeDir("path/to/directory", { recursive: true });

// 重命名文件
await renameFile("old-name.txt", "new-name.txt");

// 复制文件
await copyFile("source.txt", "destination.txt");

11.2 结合对话框的文件操作

import { open, save } from "@tauri-apps/plugin-dialog";
import { readTextFile, writeTextFile } from "@tauri-apps/plugin-fs";

// 打开文件并读取内容
async function openAndReadFile() {
  const selected = await open({
    multiple: false,
    filters: [
      { name: "文本文件", extensions: ["txt", "md"] },
      { name: "所有文件", extensions: ["*"] }
    ]
  });
  
  if (selected) {
    const content = await readTextFile(selected);
    return content;
  }
  return null;
}

// 保存内容到文件
async function saveContentToFile(content: string) {
  const filePath = await save({
    defaultPath: "untitled.txt",
    filters: [{ name: "文本文件", extensions: ["txt"] }]
  });
  
  if (filePath) {
    await writeTextFile(filePath, content);
    return true;
  }
  return false;
}

11.3 常用系统目录获取

import { 
  appDataDir, 
  documentDir, 
  downloadDir, 
  homeDir,
  tempDir 
} from "@tauri-apps/plugin-path";

// 应用数据目录(推荐存储应用配置/数据)
const appDir = await appDataDir();
// Windows: C:\Users\用户名\AppData\Local\com.example.myapp
// macOS: /Users/用户名/Library/Application Support/com.example.myapp
// Linux: /home/用户名/.local/share/com.example.myapp

// 用户文档目录
const docDir = await documentDir();

// 用户下载目录
const dlDir = await downloadDir();

// 用户主目录
const hDir = await homeDir();

// 系统临时目录
const tmpDir = await tempDir();

12. 测试与调试

12.1 前端调试

tauri::Builder::default()
    .setup(|app| {
        #[cfg(debug_assertions)]
        {
            let window = app.get_webview_window("main").unwrap();
            window.open_devtools();
        }
        Ok(())
    })

12.2 Rust 端日志

12.2.1 安装日志插件

cargo add tauri-plugin-log
npm install @tauri-apps/plugin-log

12.2.2 注册插件

tauri::Builder::default()
    .plugin(tauri_plugin_log::Builder::default()
        .level(log::LevelFilter::Info)
        .build())

12.2.3 使用日志

log::info!("这是一条信息日志");
log::warn!("这是一条警告日志");
log::error!("这是一条错误日志");
log::debug!("这是一条调试日志");

12.3 VS Code 调试配置

// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "lldb",
      "request": "launch",
      "name": "调试 Tauri 应用",
      "cargo": {
        "args": ["build", "--manifest-path=./src-tauri/Cargo.toml"]
      },
      "preLaunchTask": "ui"
    }
  ]
}

13. 打包与发布

13.1 构建命令

# 开发模式(热重载)
npm run tauri dev

# 构建生产版本
npm run tauri build

# 仅构建前端
npm run build

# 构建指定平台
npm run tauri build -- --target x86_64-pc-windows-msvc

13.2 打包配置

// src-tauri/tauri.conf.json
{
  "productName": "MyTauriApp",
  "version": "1.0.0",
  "identifier": "com.example.mytauriapp",
  "bundle": {
    "active": true,
    "targets": ["nsis", "dmg", "deb"], // 目标打包格式
    "publisher": "Your Name",
    "icon": [
      "icons/32x32.png",
      "icons/128x128.png",
      "icons/128x128@2x.png",
      "icons/icon.icns",
      "icons/icon.ico"
    ],
    "resources": ["resources/*"],
    "copyright": "Copyright (c) 2024",
    "category": "DeveloperTool",
    "shortDescription": "Tauri 示例应用",
    "longDescription": "这是一个使用 Tauri 2 构建的跨平台桌面应用示例"
  }
}

13.3 各平台打包输出路径

平台输出路径
Windowssrc-tauri/target/release/bundle/nsis/.exe
macOSsrc-tauri/target/release/bundle/dmg/.dmg
Linuxsrc-tauri/target/release/bundle/deb/.deb 或 appimage/.AppImage

13.4 Windows 应用签名

# 使用 signtool 签名(Windows SDK 自带)
signtool sign /f 证书.pfx /p 密码 /t http://timestamp.digicert.com /fd sha256 "src-tauri\target\release\应用名.exe"

14. 最佳实践

14.1 项目结构建议

src/
├── components/          # 可复用 UI 组件
├── views/              # 页面视图
├── stores/             # 状态管理
├── utils/              # 工具函数
├── api/                # Tauri API 封装
│   ├── commands.ts     # 命令调用封装
│   ├── events.ts       # 事件监听封装
│   └── fs.ts           # 文件系统操作封装
├── App.vue
└── main.ts

14.2 API 封装示例

// src/api/commands.ts
import { invoke } from "@tauri-apps/api/core";

export const commands = {
  greet: (name: string) => invoke<string>("greet", { name }),
  getCounter: () => invoke<number>("get_counter"),
  incrementCounter: () => invoke<number>("increment_counter"),
  addUser: (name: string) => invoke<string[]>("add_user", { name }),
  divide: (a: number, b: number) => invoke<number>("divide", { a, b })
};

// src/api/events.ts
import { listen } from "@tauri-apps/api/event";

export const events = {
  onTaskProgress: (callback: (payload: any) => void) => listen("task-progress", callback),
  onAppEvent: (callback: (payload: any) => void) => listen("app-event", callback)
};

14.3 安全建议

  1. <
strong>最小权限原则:只申请应用必需的权限
  1. <
strong>输入校验:所有前端输入必须在 Rust 端做合法性校验
  1. <
strong>CSP 配置:在 tauri.conf.json 中配置严格的内容安全策略
  1. <
strong>敏感数据:不要在客户端存储敏感信息,使用 Tauri Stronghold 插件加密存储
  1. <
strong>依赖更新:定期更新 Tauri 和 Rust 依赖,修复安全漏洞

14.4 性能优化

  1. <
strong>异步处理:所有耗时操作使用异步 Command,避免阻塞 UI
  1. <
strong>批量调用:合并多个 IPC 调用,减少通信开销
  1. <
strong>资源懒加载:按需加载组件和数据
  1. <
strong>缓存策略:合理使用前端缓存,减少重复请求

附录

A. 常用命令速查

# 创建项目
npm create tauri-app@latest

# 开发
npm run tauri dev

# 构建
npm run tauri build

# 添加插件
cargo add tauri-plugin-xxx
npm install @tauri-apps/plugin-xxx

# 更新依赖
cargo update
npm update

# 清理构建
cargo clean
rm -rf dist

B. 官方学习资源

C. 版本兼容性

Tauri 版本Rust 版本要求Node.js 版本要求
2.x1.70+18+

💡 提示
提示:本指南基于 Tauri 2.x 官方文档编写,所有示例均经过验证可运行。建议访问 [Tauri 官网](https://tauri.app/zh-cn/) 获取最新信息。