人人都会AI编程

tauri::Builder 构建器、应用初始化流程

更新时间:2026-07-11

tauri::Builder 是 Tauri 应用的真正起点。它像是一个“装配流水线”,让你用链式调用的方式一步步配置窗口行为、注册插件、暴露 Rust 命令、注入共享状态,最后启动事件循环。整个初始化流程遵循一个清晰的模式:构建 → 配置 → 运行


1. Builder 是什么?

在 Rust 的 main 函数中,你总是会看到类似这样的代码:

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![my_command])
        .run(tauri::generate_context!())
        .expect("启动应用失败");
}
  • tauri::Builder::default() 创建一个默认的构建器,它已经包含了 WebView 窗口创建、IPC 通信、菜单管理等基础能力。
  • 随后你可以通过一系列 .xxx() 方法进行定制。
  • 最终 .run() 会阻塞主线程,进入事件循环,等待窗口关闭或其他退出信号。

2. 核心配置方法

| 方法 | 用途 | 说明 |
|------|------|------|
| .invoke_handler(tauri::generate_handler![...]) | 注册 Rust 命令 | 将 Rust 函数暴露给前端调用,所有命令必须在此注册 |
| .manage(state) | 注入全局共享状态 | 比如数据库连接池、配置对象,任何命令都可以通过参数获取 |
| .setup(|app| { ... }) | 应用初始化钩子 | 在窗口创建前执行,适合加载插件、创建托盘、初始化系统 |
| .plugin(tauri_plugin_xxx::init()) | 安装 Tauri 官方/社区插件 | 快速集成日志、存储、对话框等功能,一行代码搞定 |
| .menu(menu) | 设置原生菜单 | 配合系统托盘或主窗口使用 |
| .on_window_event(|window, event| { ... }) | 监听窗口事件 | 如关闭、获得焦点等 |


3. 实际初始化流程示例

下面是一个更完整的例子,展示了典型的小型工具应用的 Builder 配置:

use tauri::Manager;

// 定义全局状态
struct AppConfig {
    app_name: String,
}

// 一个简单的 Rust 命令
#[tauri::command]
fn greet(name: &str) -> String {
    format!("你好, {}!", name)
}

fn main() {
    // 初始化数据库连接池、读取配置等(如果耗时,可异步)
    let config = AppConfig {
        app_name: "MyTool".into(),
    };

    tauri::Builder::default()
        // 注入状态,使命令和 setup 中都能访问
        .manage(config)
        // 注册所有暴露给前端的命令
        .invoke_handler(tauri::generate_handler![greet])
        // 添加官方插件,例如日志和存储
        .plugin(tauri_plugin_log::Builder::default().build())
        .plugin(tauri_plugin_store::Builder::default().build())
        // 启动前执行:创建系统托盘、请求权限等
        .setup(|app| {
            // 可以通过 app.handle() 获取 AppHandle,发送事件等
            let _window = app.get_window("main").unwrap();
            // 设置托盘图标和菜单(这里略)
            Ok(())
        })
        // 监听窗口关闭事件(例如保存数据)
        .on_window_event(|event| {
            if let tauri::WindowEvent::CloseRequested { .. } = event.event() {
                // 执行清理工作
            }
        })
        // 加载 tauri.conf.json 配置并启动
        .run(tauri::generate_context!())
        .expect("应用启动失败");
}

4. 流程关键点说明

1) generate_context!
它读取项目根目录下的 tauri.conf.json,解析出窗口标题、尺寸、允许的 API 权限等配置,传递给 Builder。没有它,Tauri 不知道要创建什么样的窗口。

2) 命令注册必须在 run 之前
Rust 的 #[tauri::command] 标记的函数,必须通过 tauri::generate_handler! 宏注册到 Builder。前端调用 invoke('command_name') 时,Tauri 会在这个注册表中查找对应函数。

3) setup 钩子是单向的
它返回 Ok(()) 表示初始化成功,然后窗口才会真正创建。严格来说,setup 中不应该执行会阻塞很久的任务(否则窗口迟迟不出现),但可以安排异步任务。

4) .manage 与命令参数
注入的状态类型必须满足 Send + Sync。在命令函数中,可以直接通过参数获取:

#[tauri::command]
fn setup_info(config: tauri::State<AppConfig>) -> String {
    config.app_name.clone()
}

Tauri 会自动根据类型从托管池中取出引用,无需手动提取。

5) .run() 是最终调用
调用后,控制权交给 Tauri 的事件循环,主线程会阻塞直到所有窗口关闭。这也是为什么通常 main 函数的最后一行就是 .run()


5. 最小的“Hello World”初始化

如果你只是想看最简单的启动代码,就是:

fn main() {
    tauri::Builder::default()
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

这会根据 tauri.conf.json 创建一个窗口并加载你构建后的前端资源(默认 ../dist 目录),不需要任何命令或状态。

总结tauri::Builder 的初始化流程始终遵循“注册资源 → 配置行为 → 启动事件循环”的步骤。这种模式让你可以按需添加功能,而不会出现隐藏的全局状态,也让测试和拆分插件变得容易。