Skip to content

Tauri 参考 ​

基于 Tauri 2.x · 核于 2026-07

速查 ​

  • 版本:Tauri v2(2.0 stable);CLI @tauri-apps/cli v2.x;底层 WRY ≈0.55.x / TAO ≈0.35.x;GitHub ≈107–108k star;MSRV Rust 1.77.2
  • 架构:Core(Rust) + WRY / TAO + 系统 WebView;依赖链 tauri → tauri-runtime → tauri-runtime-wry → WRY → TAO
  • 最常踩:v1 allowlist 已废改 ACL;逻辑在 lib.rs、main.rs 是薄壳;命令 pub 规则;async 命令禁借用参数;Emitter/Manager trait;Channel 用 new Channel()

一、版本坐标 ​

项值
主版本Tauri v2(2.0 stable)
CLI@tauri-apps/cli v2.x
底层 WRY≈0.55.x(WebView 封装)
底层 TAO≈0.35.x(窗口库,fork 自 winit)
GitHub star≈107–108k(2026-07)
MSRVRust 1.77.2
平台Linux / macOS / Windows + iOS / Android

二、核心 API 速记 ​

场景API
定义命令#[tauri::command] fn foo(...) -> T {}
注册命令.invoke_handler(tauri::generate_handler![foo, bar])
前端调命令import { invoke } from '@tauri-apps/api/core'; invoke('foo', { arg })
参数命名默认 camelCase;#[tauri::command(rename_all = "snake_case")]
错误处理返回 Result<T, E>(E 实现 Serialize,用 thiserror)→ 前端 .catch
async 命令async fn;禁借用参数,可返回 Result<T, ()>
大二进制返回tauri::ipc::Response::new(bytes)
Rust 发事件use tauri::Emitter; app.emit("ev", payload) / emit_to("label", ...)
前端听事件import { listen, once } from '@tauri-apps/api/event'; const un = await listen('ev', cb)
高吞吐流tauri::ipc::Channel<T>(后端 .send())+ 前端 new Channel()
注册状态.manage(Mutex::new(state))
取状态(命令内)state: State<'_, Mutex<T>> → state.lock().unwrap()
取状态(命令外)app.state::<Mutex<T>>()(需 use tauri::Manager)
取窗口app.get_webview_window("main")(需 use tauri::Manager)
注册插件.plugin(tauri_plugin_fs::init())

三、关键 CLI ​

bash
npm create tauri-app@latest            # 脚手架(交互式选前端/语言/包管理器)
npm run tauri dev / build              # 桌面开发 / 构建
npm run tauri build --no-bundle        # 只编不打包
npm run tauri android|ios init|dev|build   # 移动端
npm run tauri signer generate -- -w key    # 生成更新签名密钥
rustc --print host-tuple               # 查目标三元组(sidecar 命名用)

四、权限标识符速记 ​

  • core(内置):core:default、core:window:allow-close、core:event:default、core:path:default
  • 插件:fs:default、fs:read-files、fs:allow-mkdir、fs:scope-home、shell:allow-execute、shell:allow-spawn、updater:default、dialog:default、notification:default
  • 移动:biometric:allow-authenticate、nfc:allow-scan
  • 规则:<插件>:<allow|deny>-<命令> 或 <插件>:default;deny > allow;tauri-plugin- 前缀自动补全;标识符限 ASCII 小写、长度 ≤116

五、配置骨架(tauri.conf.json) ​

json
{
  "productName": "MyApp",
  "version": "1.0.0",
  "identifier": "com.example.myapp",
  "build": {
    "beforeDevCommand": "npm run dev",
    "devUrl": "http://localhost:3000",
    "beforeBuildCommand": "npm run build",
    "frontendDist": "../dist"
  },
  "app": {
    "windows": [{ "title": "Main" }],
    "security": { "csp": "default-src 'self'", "capabilities": ["main-capability"] }
  },
  "bundle": { "active": true, "targets": "all", "icon": ["icons/icon.png"] },
  "plugins": { "updater": { "pubkey": "...", "endpoints": ["..."] } }
}

六、vs Electron 对照 ​

维度Tauri v2Electron
后端语言Rust(移动可 Swift/Kotlin)Node.js
渲染引擎系统 WebView打包 Chromium
安装包极小(<600KB~10MB)大(100MB+)
内存低(~50MB 级)高
渲染一致性各 OS 有差异一致
移动端支持 iOS/Android不支持
生态较新、增长快老牌、最全

七、高频坑 / 考点 ​

#要点
1v1→v2:allowlist 已废,改 Permissions/Capabilities ACL;核心 API 拆成 tauri-plugin-*
2入口:逻辑在 lib.rs 的 run(),main.rs 是薄壳;移动靠 mobile_entry_point 宏
3命令 pub 规则:lib.rs 内命令不能 pub;独立模块内必须 pub
4async 命令:不能收借用参数(&str / State<'_>)
5参数命名:Rust snake_case ↔ 前端默认 camelCase
6两个 trait:app.emit 需 use tauri::Emitter;app.state()/get_webview_window() 需 use tauri::Manager
7Channel:前端用 new Channel() 对象作 invoke 参数传入
8远程 IPC:默认禁远程调 API;Linux/Android 无法区分 iframe 与主窗口
9Isolation:Windows 下不支持 ES Modules,脚本须内联
10渲染差异:系统 WebView 版本不同 → 需跨平台测;这是「小体积」的代价
11sidecar 命名:必须带 -$TARGET_TRIPLE 后缀,否则打包/运行失败
12updater:createUpdaterArtifacts: true + 签名私钥务必妥存(丢了无法再发更新)

八、权威链接 ​