Tauri 从零开始学习指南适合有 C/Qt 背景、想学习跨平台桌面应用开发的开发者官方文档Tauri 中文官网 | Tauri 英文文档本教程基于 Tauri 2.x目录Tauri 是什么环境准备创建第一个项目项目结构详解前后端通信原理启动流程解析热重载开发体验发布应用核心概念总结Tauri 是什么Tauri是一个用 Rust 后端 系统自带 WebView 前端来构建跨平台桌面应用的框架。vs Electron对比项ElectronTauri后端Node.jsRust前端Chromium 内嵌系统 WebView包体积~200-500MB~3-5MB启动速度较慢快内存占用较高低核心优势每个应用不用捆绑整个浏览器直接用 Windows 的 WebView2、macOS 的 WebKit、Linux 的 GTK WebView。Tauri 2 vs Tauri 1本教程基于 Tauri 2特性Tauri 1Tauri 2发布时间2022年2024年API 设计旧风格现代化、更清晰性能良好⭐ 显著提升文件系统 API基础⭐ 更强大插件系统稳定⭐ 全面重构类型定义部分⭐ 完整 TypeScript 支持社区生态成熟⭐ 更活跃主要改进 更简洁的 API如tauri-apps/api/core替代旧的模块结构 更好的开发体验更快的编译、更清晰的错误信息 强化的安全性权限系统更完善 更丰富的官方插件生态本教程代码完全兼容 Tauri 2.x。如果你找到的是 Tauri 1 教程API 细节会有差异但核心思想相同。环境准备检查工具链在 PowerShell 中执行rustc--version cargo--version node--version npm--version如果都有输出且版本正常说明环境就绪。对于 Windows还需要 WebView2 运行时通常 Windows 10 及以上已装# 查看注册表Get-ItemProperty-PathHKLM:\SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}-ErrorAction SilentlyContinue创建第一个项目步骤 1用官方脚手架创建项目在你的工作目录下敲npm create tauri-applatest交互式选择提问选择说明Project namehello-tauri项目名称Identifier默认com.xxx.hello-tauri应用唯一标识打包时用Frontend languageTypeScript/JavaScript我们用原生 JSPackage managernpm依赖管理UI templateVanilla无框架最纯粹UI flavorJavaScript不引入 TypeScript 复杂度步骤 2进入项目、安装依赖cd hello-tauri npm install这会下载前端依赖Tauri API、Vite 等。步骤 3运行开发环境npm run tauri dev你会看到Vite 开发服务器启动Rust 编译第一次较慢一个窗口弹出显示欢迎页面成功项目结构详解hello-tauri/ │ ├── index.html ← 【前端】页面文件根目录 ├── src/ ← 【前端】源代码 │ ├── main.ts ← JavaScript 入口UI 逻辑 │ ├── styles.css ← 样式表 │ └── assets/ ← 静态资源图片等 │ ├── src-tauri/ ← 【后端】Rust 代码 │ ├── src/ │ │ ├── main.rs ← Rust 程序入口 │ │ └── lib.rs ← 核心业务逻辑 │ ├── Cargo.toml ← Rust 依赖配置 │ ├── tauri.conf.json ← 应用全局配置 │ ├── build.rs ← 编译脚本 │ └── capabilities/ │ └── default.json ← 权限声明 │ ├── package.json ← Node.js 依赖和脚本 └── .gitignore前端文件index.html根目录!doctypehtmlhtmllangenheadmetacharsetUTF-8/linkrelstylesheethref/src/styles.css/scripttypemodulesrc/src/main.tsdefer/script/headbodymainclasscontainerh1Welcome to Tauri/h1!-- 表单输入框 按钮 --formclassrowidgreet-forminputidgreet-inputplaceholderEnter a name.../buttontypesubmitGreet/button/form!-- 显示结果 --pidgreet-msg/p/main/body/html作用定义应用的 HTML 结构窗口显示什么。src/main.ts前端逻辑入口import{invoke}fromtauri-apps/api/core;letgreetInputEl:HTMLInputElement|null;letgreetMsgEl:HTMLElement|null;asyncfunctiongreet(){if(greetMsgElgreetInputEl){// 调用后端的 greet 命令greetMsgEl.textContentawaitinvoke(greet,{name:greetInputEl.value,});}}// 页面加载完成后初始化window.addEventListener(DOMContentLoaded,(){greetInputEldocument.querySelector(#greet-input);greetMsgEldocument.querySelector(#greet-msg);// 绑定表单提交事件document.querySelector(#greet-form)?.addEventListener(submit,(e){e.preventDefault();greet();// 点击按钮时调用});});关键点invoke(greet, { name: ... })— 调用后端 Rust 命令await— 等待后端返回结果结果显示到页面上后端文件Rustsrc-tauri/src/main.rs// Prevents additional console window on Windows in release, DO NOT REMOVE!!#![cfg_attr(not(debug_assertions), windows_subsystem windows)]fnmain(){hello_tauri_lib::run()// 调用库的 run() 函数}作用Rust 程序的入口点。这里只是点火具体逻辑在lib.rs。src-tauri/src/lib.rs核心逻辑// 定义一个可被前端调用的命令#[tauri::command]fngreet(name:str)-String{format!(Hello, {}! Youve been greeted from Rust!,name)}pubfnrun(){tauri::Builder::default().plugin(tauri_plugin_opener::init()).invoke_handler(tauri::generate_handler![greet])// 注册 greet 命令.run(tauri::generate_context!()).expect(error while running tauri application);}关键概念#[tauri::command]— 宏标记这个函数可被前端调用generate_handler![greet]— 告诉 Tauri 前端可以调用greet函数配置文件tauri.conf.json{productName:hello-tauri,version:0.1.0,identifier:com.tianhaifu.hello-tauri,build:{beforeDevCommand:npm run dev,// 开发前运行devUrl:http://localhost:1420,// 开发时前端 URLbeforeBuildCommand:npm run build,// 发布前运行frontendDist:../dist// 前端打包输出目录},app:{windows:[{title:hello-tauri,width:800,height:600}]}}作用应用的全局配置窗口大小、名字、打包参数等。package.json{scripts:{dev:vite,// 启动前端开发服务器build:tsc vite build,// 编译前端tauri:tauri// Tauri CLI},dependencies:{tauri-apps/api:^2// Tauri API前端调用后端},devDependencies:{tauri-apps/cli:^2,vite:^6.0.3,typescript:~5.6.2}}作用管理前端依赖和构建脚本。类似 Qt 的.pro文件。前后端通信原理通信模型┌─────────────────────────────────┐ │ Web 前端 (JavaScript) │ │ HTML/CSS/JS 用户界面 │ └────────────────┬────────────────┘ │ invoke() 调用命令 │ listen() 监听事件 │ ═══════════════════════════════ ← IPC 通道 │ ┌────────────────▼────────────────┐ │ Rust 后端 (Tauri Runtime) │ │ #[tauri::command] 处理命令 │ │ 业务逻辑、文件 IO、系统调用 │ └─────────────────────────────────┘调用流程步骤 1前端发起请求constresultawaitinvoke(greet,{name:张三});步骤 2后端处理#[tauri::command]fngreet(name:str)-String{format!(Hello, {}! Youve been greeted from Rust!,name)}步骤 3前端接收结果console.log(result);// Hello, 张三! Youve been greeted from Rust!类比 Qt在 Qt 中你可能这样通信// C 后端publicslots:QStringgreet(constQStringname){returnHello, name!;}// QML 前端Button{onClicked:{var resultbackend.greet(张三)console.log(result)}}Tauri 的invoke()就像 Qt 的「跨进程槽调用」—— 前端通过 IPC 调用后端函数。启动流程解析C 程序的启动操作系统 ↓ main() 函数执行 ↓ 逐行执行代码 ↓ return 0程序结束Tauri 应用的启动两个进程并行用户敲npm run tauri dev ↓ ═════════════════════════════════════════════ ↓ ↓ 【前端进程启动】 【后端进程启动】 ↓ ↓ 1. Vite dev server 启动 1. Rust 编译cargo build 监听 http://localhost:1420 ↓ ↓ 2. main.rs 的 main() 执行 2. 等待 WebView 连接 ↓ ↓ 3. 调用 lib.rs 的 run() 3. WebView 启动 ↓ ↓ 4. Builder::default() 4. 加载 http://localhost:1420 .plugin(...) ↓ .invoke_handler(...) 5. 下载并解析 index.html .run() ↓ ↓ 6. 执行 main.ts 5. 启动事件循环 ↓ 永远监听 7. DOMContentLoaded 事件触发 ↓ 8. UI 初始化完成 ═════════════════════════════════════════════ 【前后端都运行通过 IPC 通信】关键认识Tauri 应用 两个独立进程通过 IPC 通信前端进程WebView JavaScript 运行时后端进程Rust Tauri 框架它们并行启动各司其职。热重载开发体验什么是热重载修改代码后应用自动重新编译/刷新无需手动重启。前端热重载修改src/main.ts或index.html→ Vite 自动刷新浏览器 → 立即看到效果修改 main.ts → 保存 ↓ Vite 检测到文件变化 ↓ 自动刷新页面 ↓ 几毫秒内看到新效果后端热重载修改src-tauri/src/lib.rs→ Cargo 自动编译 → 应用重启窗口修改 lib.rs → 保存 ↓ Cargo 检测到文件变化 ↓ 自动编译 Rust ↓ 编译完成应用窗口重启 ↓ 几秒钟内看到新效果对比传统开发Qt C改代码 → 手动编译 → 手动运行 → 看效果分钟级Tauri改代码 → 保存 → 自动重新加载秒级或毫秒级开发效率提升显著。发布应用修改打包配置打开src-tauri/tauri.conf.json修改bundle部分如果你只要 .exe 文件绿色版bundle:{active:false}或者只生成特定格式bundle:{active:true,targets:[nsis]}执行打包命令npm run tauri build第一次耗时较长3-5 分钟因为要编译 release 版 Rust。输出位置打包完成后可执行文件在src-tauri/target/release/hello_tauri.exe如果打包成安装器在src-tauri/target/release/bundle/nsis/发布将.exe文件分发给用户或用你自己的安装器包装这个.exe核心概念总结1. 前后端分离前端Web 技术HTML/CSS/JavaScript运行在 WebView 中后端Rust 代码运行在单独的进程中2. IPC 通信前端invoke()调用后端命令后端处理后返回结果通过进程间通信IPC传递数据3. #[tauri::command] 宏#[tauri::command]fnmy_command(arg:String)-String{// 处理逻辑arg.to_uppercase()}标记这个 Rust 函数可被前端调用。4. 热重载修改前端代码 → Vite 自动刷新修改后端代码 → Cargo 自动编译应用重启5. 项目配置tauri.conf.json— 应用全局配置Cargo.toml— Rust 依赖package.json— Node.js/前端依赖6. 启动流程不同于 C 的单一main()入口Tauri 是两个进程并行启动Rust 后端启动 → 初始化 Tauri 框架 → 进入事件循环WebView 前端启动 → 加载 HTML/JS → UI 初始化完成用户交互 → 前端调后端 → 后端处理 → 结果返回前端进阶话题下一步学习方向管理状态使用 Tauri 的StateT在后端存储应用状态pubstructAppState{count:i32,}#[tauri::command]fnincrement(state:tauri::StateAppState){// 修改状态}传递复杂数据用serde序列化结构体useserde::{Deserialize,Serialize};#[derive(Serialize, Deserialize)]structUser{name:String,age:u32,}#[tauri::command]fncreate_user(user:User)-String{format!({} is {} years old,user.name,user.age)}后端→前端事件使用emit向前端发送事件window.emit(event-name,payload)?;前端监听import{listen}fromtauri-apps/api/event;awaitlisten(event-name,(event){console.log(event.payload);});调用系统 API文件操作std::fs对话框tauri_plugin_dialog通知tauri_plugin_notification剪贴板tauri_plugin_clipboard常见问题Q: Tauri vs ElectronTauri 优势包体积小3-5MB vs 200-500MB启动快内存占用低更安全Rust 的内存安全Electron 优势生态成熟第三方库丰富跨平台支持更好Node.js 生态选择建议追求轻量级、性能的用 Tauri需要成熟生态的用 Electron。Q: 可以用 React/Vue 吗可以。脚手架支持 React TypeScript、Vue 等模板。本教程用原生 JS 是为了聚焦 Tauri 本身学会基础后可以加上你喜欢的框架。Q: 怎么调试后端代码在 Rust 代码里加println!()或dbg!()在终端看输出或用 VSCode 的 Rust 调试器CodeLLDB 扩展Q: 打包时很慢Rust 编译确实慢尤其是第一次 release build。可以喝杯咖啡等待 ☕或在Cargo.toml中加优化选项进阶话题Q: 支持哪些操作系统Windows 7 需要 WebView2macOS 10.13Linux需要 GTK WebView总结Tauri 是一个轻量级、高性能的跨平台桌面应用框架。核心思想✅用 Rust 写高性能后端业务逻辑、系统调用✅用 Web 技术写漂亮前端HTML/CSS/JS✅通过 IPC 优雅通信invoke()调用命令✅利用系统 WebView包体积极小如果你有 C/Qt 背景Tauri 会让你感到熟悉又新鲜 —— 熟悉的桌面应用概念全新的 Rust Web 技术栈。祝你开发愉快参考资源官方文档Tauri 中文官网— 中文社区维护的文档推荐先看这个Tauri 官方文档英文— 最新最全的官方文档GitHub 仓库— 源代码、issue、讨论学习资源Rust 官方书— 如果需要补 Rust 基础Rust 中文文档— 中文 Rust 资源Tauri 示例项目— 官方 demo参考价值高社区交流Tauri Discord— 官方社区英文Tauri 中文讨论— 中文社区技术博客— 掘金、知乎、Dev.to 等平台搜索 Tauri 相关文章