为什么用 Tauri

Tauri 是新一代桌面应用框架,用系统自带的 WebView 渲染前端,用 Rust 提供系统能力。与 Electron 的核心区别:

对比项 Electron Tauri 2
前端渲染 内置 Chromium(约 150MB+) 系统 WebView(macOS 用 WKWebView,Windows 用 WebView2)
后端语言 Node.js Rust
安装包体积 通常 60-150MB 通常 3-10MB
内存占用 高 低
安全性 需自行配置 默认更安全(权限模型)

适用场景:工具类软件、对体积和内存敏感的应用、愿意用 Rust 做底层逻辑的团队。

一、环境准备

需要安装:

  1. Rust:https://rustup.rs 下载安装,验证 rustc –version;
  2. Node.js(前端部分用);
  3. 平台依赖:
    • macOS:Xcode Command Line Tools(xcode-select –install);
    • Windows:VS Build Tools 的 C++ 组件 + WebView2;
    • Linux:webkit2gtk 等依赖包。

二、创建项目

1
npm create tauri-app@latest

按提示选择:

  • 项目名称,如 my-tauri-app
  • 前端模板:Vue / React / Svelte / 纯 HTML 均可
  • 包管理器:npm / pnpm 等

然后安装依赖并启动:

1
2
3
cd my-tauri-app
npm install
npm run tauri dev

首次运行会编译 Rust 代码,需要等几分钟。

三、项目结构

1
2
3
4
5
6
7
8
9
10
my-tauri-app/
├── src/ # 前端代码(Vue/React 等)
├── src-tauri/ # Rust 后端
│ ├── src/
│ │ ├── main.rs # 入口
│ │ └── lib.rs # 命令定义
│ ├── Cargo.toml # Rust 依赖配置
│ ├── tauri.conf.json # Tauri 配置(窗口、打包、权限)
│ └── capabilities/ # 权限能力配置(Tauri 2 新增)
└── package.json

四、前端调用 Rust 命令

Rust 端定义命令(src-tauri/src/lib.rs):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 定义一个简单的命令:打招呼
#[tauri::command]
fn greet(name: &str) -> String {
format!("你好,{}!我是从 Rust 返回的。", name)
}

// 一个更"系统级"的例子:读取文件
#[tauri::command]
fn read_file(path: &str) -> Result<String, String> {
std::fs::read_to_string(path).map_err(|e| e.to_string())
}

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

前端调用(src/App.vue,Vue3 示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<script setup>
import { invoke } from '@tauri-apps/api/core'
import { ref } from 'vue'

const result = ref('')

async function callRust() {
// invoke 第一个参数是命令名,第二个参数传参
result.value = await invoke('greet', { name: '张思帆' })
}

async function readFile() {
try {
const content = await invoke('read_file', { path: '/etc/hosts' })
result.value = content
} catch (e) {
result.value = '读取失败:' + e
}
}
</script>

<template>
<main>
<button @click="callRust">调用 Rust 打招呼</button>
<button @click="readFile">读取文件</button>
<pre>{{ result }}</pre>
</main>
</template>

注意参数命名:Rust 端用 snake_case(如 path),前端 invoke 传参时建议保持一致,避免命名转换踩坑。

五、Tauri 2 的权限模型(重要)

Tauri 2 引入了 capabilities 权限系统:前端能调用哪些插件能力,需要在 src-tauri/capabilities/default.json 里显式声明,而不是全开放。

1
2
3
4
5
6
7
8
9
10
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "主窗口默认权限",
"windows": ["main"],
"permissions": [
"core:default",
"opener:default"
]
}

例如要用文件对话框插件,需要安装并添加对应权限:

1
2
npm install @tauri-apps/plugin-dialog
# Rust 端 Cargo.toml 加 tauri-plugin-dialog
1
2
3
{
"permissions": ["core:default", "dialog:allow-open"]
}

这种”默认最小权限”的设计,让 Tauri 应用比 Electron 天生更安全。

六、打包发布

1
npm run tauri build

产物位置:

  • macOS:src-tauri/target/release/bundle/dmg/ 或 app/;
  • Windows:src-tauri/target/release/bundle/nsis/ 或 msi/;
  • Linux:.deb / .AppImage。

跨平台打包建议:在对应平台上各自打包(macOS 的 dmg 只能在 macOS 上打,Windows 同理),或用 GitHub Actions 的 tauri-action 做 CI 流水线。

常见坑

  1. 首次编译慢:Rust 编译 + 下载依赖需要几分钟,是正常现象,后续增量编译快很多;
  2. invoke 报 “not allowed”:大概率是 capabilities 权限没配,检查 default.json;
  3. 命令名不一致:Rust #[tauri::command] 的函数名就是 invoke 的命令名,改名要两边同步;
  4. Linux 依赖报错:webkit2gtk-4.1、libappindicator 等系统包没装全,按官方文档装齐即可。

总结

Tauri 2 适合追求”小体积、低内存、强安全”的桌面应用。上手路径:装好 Rust → create-tauri-app 建项目 → 定义 #[tauri::command] → 前端 invoke 调用 → 配置 capabilities 权限 → 打包。前端逻辑和 Web 完全一致,把精力花在 Rust 命令的设计上即可。