第二章 五分钟跑起第一个 Tauri 应用#
"Talk is cheap. Show me the code." — Linus Torvalds
上一章我们聊了很多"为什么",现在是时候动手了。本章的目标很简单:搭建开发环境,用 Tauri 跑起你的第一个桌面应用。 如果你是 C++/Java 后端工程师,你会发现这个过程比配置 CMake 或 Maven 多模块项目简单得多。
mindmap
root((第一个 Tauri 应用))
环境准备
Rust
Node.js
平台依赖
创建项目
create-tauri-app
Vite
src-tauri
运行调试
dev server
WebView
Rust 日志
交付增量
Hello World
项目结构
常见错误
2.1 环境准备#
2.1.1 系统要求#
Tauri 支持三大桌面平台,每个平台有不同的前置依赖:
┌─────────────────────────────────────────────────────────┐
│ 环境依赖一览 │
├──────────┬──────────────────────────────────────────────┤
│ 所有平台 │ Rust (rustup) + Node.js (≥18) + 包管理器 │
├──────────┼──────────────────────────────────────────────┤
│ macOS │ Xcode Command Line Tools │
│ │ (xcode-select --install) │
├──────────┼──────────────────────────────────────────────┤
│ Windows │ Microsoft Visual Studio C++ Build Tools │
│ │ + WebView2 (Win10 1803+ 已预装) │
├──────────┼──────────────────────────────────────────────┤
│ Linux │ 系统依赖包 (见下文) │
└──────────┴──────────────────────────────────────────────┘
2.1.2 安装 Rust#
如果你还没有安装 Rust,只需要一行命令:
# macOS / Linux
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Windows (下载并运行 rustup-init.exe)
# https://rustup.rs
安装完成后验证:
$ rustc --version
rustc 1.82.0 (f6e511eec 2024-10-15)
$ cargo --version
cargo 1.82.0 (8f40fc59f 2024-10-15)
给 C++ 工程师的提示:
cargo之于 Rust,就像cmake + make + conan的合体。它同时负责构建、依赖管理、测试和发布。给 Java 工程师的提示:
cargo类似于 Maven + Gradle 的结合体,但更快、更简洁。Cargo.toml对应pom.xml/build.gradle。
2.1.3 安装 Node.js#
Tauri 的前端部分需要 Node.js。推荐使用 nvm(Node Version Manager)管理版本:
# 安装 nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# 安装并使用 Node.js LTS
nvm install --lts
nvm use --lts
# 验证
$ node --version
v20.18.0
$ npm --version
10.8.2
2.1.4 平台特定依赖#
macOS:
xcode-select --install
Linux(Ubuntu/Debian):
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
Windows:
安装 Visual Studio Build Tools,勾选"C++ 桌面开发"
WebView2 在 Windows 10 (1803+) 和 Windows 11 中已预装
2.1.5 安装 Tauri CLI#
# 通过 Cargo 安装(推荐)
cargo install tauri-cli
# 或通过 npm 安装
npm install -g @tauri-apps/cli
2.2 创建第一个 Tauri 项目#
2.2.1 使用脚手架#
Tauri 提供了交互式脚手架工具:
# 使用 cargo 创建
cargo create-tauri-app hive
# 或使用 npm 创建
npm create tauri-app@latest hive
脚手架会询问你几个问题:
✔ Choose which language to use for your frontend · TypeScript / JavaScript
✔ Choose your package manager · npm
✔ Choose your UI template · Vanilla
✔ Choose your UI flavor · TypeScript
为什么选 Vanilla? 在学习阶段,我们先用最简单的 Vanilla(原生 HTML/CSS/JS)来理解 Tauri 的工作原理。后续章节会切换到 React/Vue 等框架。
2.2.2 项目结构#
创建完成后,项目结构如下:
hive/
├── src-tauri/ # Rust 后端
│ ├── Cargo.toml # Rust 依赖配置(类似 pom.xml)
│ ├── build.rs # 构建脚本
│ ├── tauri.conf.json # Tauri 配置文件
│ ├── capabilities/ # 安全权限配置
│ │ └── default.json
│ ├── icons/ # 应用图标
│ │ ├── icon.ico
│ │ ├── icon.png
│ │ └── ...
│ └── src/
│ ├── main.rs # Rust 入口
│ └── lib.rs # Rust 库代码
│
├── src/ # 前端代码
│ ├── index.html # 主页面
│ ├── main.ts # 前端入口
│ └── styles.css # 样式
│
├── package.json # Node.js 依赖配置
└── tsconfig.json # TypeScript 配置
让我们用一张图来理解这个结构:
┌─────────────────────────────────────────────────┐
│ hive 项目 │
│ │
│ ┌──────────────────┐ ┌──────────────────────┐ │
│ │ src/ (前端) │ │ src-tauri/ (后端) │ │
│ │ │ │ │ │
│ │ index.html │ │ Cargo.toml │ │
│ │ main.ts │ │ tauri.conf.json │ │
│ │ styles.css │ │ src/main.rs │ │
│ │ │ │ src/lib.rs │ │
│ │ → 运行在 │ │ → 运行在 │ │
│ │ WebView 中 │ │ 原生进程中 │ │
│ └────────┬─────────┘ └──────────┬───────────┘ │
│ │ IPC │ │
│ └───────────────────────┘ │
└─────────────────────────────────────────────────┘
C++ 工程师视角:
src-tauri/就像你的 C++ 项目目录,Cargo.toml对应CMakeLists.txt,src/main.rs对应main.cpp。Java 工程师视角:
src-tauri/类似 Spring Boot 的src/main/java/,Cargo.toml对应pom.xml。
2.3 理解核心文件#
2.3.1 Rust 入口:src-tauri/src/main.rs#
// 防止在 release 模式下弹出控制台窗口(仅 Windows)
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
// 调用 lib.rs 中的 run() 函数
hive_lib::run()
}
2.3.2 核心逻辑:src-tauri/src/lib.rs#
// 定义一个 Tauri 命令(可以从前端调用)
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
// 构建并运行 Tauri 应用
pub fn run() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet]) // 注册命令
.run(tauri::generate_context!()) // 运行
.expect("error while running tauri application");
}
逐行解析:
代码 |
含义 |
C++/Java 类比 |
|---|---|---|
|
属性宏,标记为可从前端调用的命令 |
Java |
|
接收字符串引用,返回 String |
|
|
构建器模式,配置应用 |
Spring Boot |
|
注册命令处理器 |
注册 Controller |
|
启动应用 |
|
2.3.3 前端页面:src/index.html#
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="styles.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hive</title>
<script type="module" src="/main.ts" defer></script>
</head>
<body>
<main class="container">
<h1>Welcome to Hive!</h1>
<div class="row">
<input id="greet-input" placeholder="Enter a name..." />
<button type="button" id="greet-btn">Greet</button>
</div>
<p id="greet-msg"></p>
</main>
</body>
</html>
2.3.4 前端逻辑:src/main.ts#
const { invoke } = window.__TAURI__.core;
let greetInputEl: HTMLInputElement | null;
let greetMsgEl: HTMLElement | null;
async function greet() {
if (greetInputEl && greetMsgEl) {
// 调用 Rust 后端的 greet 命令
greetMsgEl.textContent = await invoke("greet", {
name: greetInputEl.value,
});
}
}
window.addEventListener("DOMContentLoaded", () => {
greetInputEl = document.querySelector("#greet-input");
greetMsgEl = document.querySelector("#greet-msg");
document.querySelector("#greet-btn")?.addEventListener("click", () => greet());
});
关键点: invoke("greet", { name: "Walter" }) 就是前端调用 Rust 后端的方式。这就是 Tauri 的 IPC(进程间通信)机制,我们会在第 11 章深入探讨。
┌──────────────────────────────────────────────┐
│ IPC 调用流程 │
│ │
│ 前端 (WebView) Rust (Core) │
│ │
│ invoke("greet", ──────► #[tauri::command] │
│ {name:"Walter"}) fn greet(name) │
│ │
│ "Hello, Walter!" ◄────── return String │
│ │
└──────────────────────────────────────────────┘
2.3.5 Tauri 配置:src-tauri/tauri.conf.json#
{
"productName": "hive",
"version": "0.1.0",
"identifier": "com.hive.app",
"build": {
"frontendDist": "../src",
"devUrl": "http://localhost:1420",
"beforeDevCommand": "npm run dev",
"beforeBuildCommand": "npm run build"
},
"app": {
"windows": [
{
"title": "Hive",
"width": 800,
"height": 600
}
],
"security": {
"csp": null
}
},
"bundle": {
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
}
重要配置项说明:
配置项 |
含义 |
类比 |
|---|---|---|
|
应用名称 |
Maven |
|
唯一标识符(反向域名) |
Java 包名 |
|
开发模式下的前端地址 |
webpack-dev-server |
|
窗口配置 |
Qt |
|
打包配置 |
Maven Assembly Plugin |
2.4 运行与调试#
2.4.1 开发模式#
cd hive
# 安装前端依赖
npm install
# 以开发模式运行
cargo tauri dev
第一次运行会比较慢(需要编译 Rust 依赖),后续增量编译会快很多。
Compiling hive v0.1.0
...
Finished `dev` profile [unoptimized + debuginfo] target(s) in 45.32s
Info Watching /Users/you/hive/src-tauri for changes...
Info Running `target/debug/hive`
你会看到一个桌面窗口弹出,输入名字点击 "Greet",就能看到 Rust 返回的问候语!
┌──────────────────────────────────┐
│ Hive — □ ✕ │
├──────────────────────────────────┤
│ │
│ Welcome to Hive! │
│ │
│ ┌──────────────┐ ┌───────┐ │
│ │ Walter │ │ Greet │ │
│ └──────────────┘ └───────┘ │
│ │
│ Hello, Walter! You've been │
│ greeted from Rust! │
│ │
└──────────────────────────────────┘
2.4.2 热重载#
Tauri 开发模式支持双向热重载:
前端热重载:修改 HTML/CSS/JS 后自动刷新 WebView
Rust 热重载:修改 Rust 代码后自动重新编译并重启应用
2.4.3 调试技巧#
前端调试: 右键点击应用窗口 → "检查元素",会打开 DevTools(和浏览器开发者工具一样)。
Rust 调试:
# 使用 println! 宏(最简单)
println!("Debug: name = {}", name);
# 使用 log 库(推荐)
# 在 Cargo.toml 中添加 log 和 env_logger
log::info!("Processing greet for: {}", name);
VS Code 调试配置:
在 .vscode/launch.json 中添加:
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Tauri Development Debug",
"cargo": {
"args": [
"build",
"--manifest-path=./src-tauri/Cargo.toml",
"--no-default-features"
]
},
"preLaunchTask": "ui:dev"
}
]
}
2.5 构建发布版本#
2.5.1 生产构建#
cargo tauri build
构建完成后,安装包位于 src-tauri/target/release/bundle/ 目录:
src-tauri/target/release/bundle/
├── macos/ # macOS .app 和 .dmg
├── msi/ # Windows .msi 安装包
├── nsis/ # Windows .exe 安装包
└── deb/ # Linux .deb 包
2.5.2 体积对比#
让我们来看看构建产物的体积:
┌────────────────────────────────────────────┐
│ Hello World 应用体积对比 │
├────────────────┬───────────┬───────────────┤
│ │ Electron │ Tauri │
├────────────────┼───────────┼───────────────┤
│ macOS .dmg │ ~160 MB │ ~4 MB │
│ Windows .msi │ ~155 MB │ ~3 MB │
│ Linux .deb │ ~150 MB │ ~3 MB │
├────────────────┼───────────┼───────────────┤
│ 体积缩减 │ 基准 │ ~97% ↓ │
└────────────────┴───────────┴───────────────┘
没错,Tauri 应用只有 Electron 的 3% 大小。这就是使用系统 WebView 的威力。
2.6 动手练习:定制你的 Hive#
在进入 Rust 学习之前,让我们做一些小练习来熟悉 Tauri 的开发流程。
练习 1:修改问候语#
修改 src-tauri/src/lib.rs 中的 greet 函数,让它返回中文问候:
#[tauri::command]
fn greet(name: &str) -> String {
format!("你好,{}!欢迎来到 Hive 蜂巢!", name)
}
练习 2:添加新命令#
在 lib.rs 中添加一个获取系统信息的命令:
#[tauri::command]
fn get_system_info() -> String {
format!(
"OS: {} {}\nArch: {}",
std::env::consts::OS,
std::env::consts::FAMILY,
std::env::consts::ARCH
)
}
pub fn run() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet, get_system_info])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
然后在前端调用它:
const sysInfo = await invoke("get_system_info");
console.log(sysInfo);
// 输出: OS: macos unix\nArch: aarch64
练习 3:修改窗口配置#
编辑 tauri.conf.json,尝试修改窗口大小、标题,或添加第二个窗口:
"windows": [
{
"title": "Hive - 蜂巢协作",
"width": 1024,
"height": 768,
"resizable": true,
"fullscreen": false
}
]
2.7 常见问题排查#
问题 |
可能原因 |
解决方案 |
|---|---|---|
|
Rust 工具链未安装或版本过旧 |
|
WebView 空白 |
前端未正确启动 |
检查 |
Linux 编译报错缺少库 |
系统依赖未安装 |
运行 2.1.4 中的 apt install 命令 |
Windows 找不到 WebView2 |
系统版本过旧 |
手动安装 WebView2 Runtime |
第一次编译太慢 |
正常现象,需下载和编译依赖 |
耐心等待,后续增量编译会很快 |
端口 1420 被占用 |
其他进程占用了端口 |
修改 |
2.8 小结#
Tauri 开发环境需要 Rust + Node.js + 平台特定依赖
cargo create-tauri-app可以快速创建项目脚手架项目分为 前端(
src/) 和 Rust 后端(src-tauri/) 两部分前后端通过 IPC(
invoke) 通信cargo tauri dev开发模式支持热重载cargo tauri build生成的安装包只有 Electron 的 3% 大小Tauri 的配置文件
tauri.conf.json控制窗口、构建和打包行为
下一章,我们将正式开始 Rust 语言的学习之旅。如果你是 C++ 工程师,你会觉得很多概念似曾相识;如果你是 Java 工程师,你会发现 Rust 在很多设计上做了更激进的取舍。