棕地集成(Brownfield Integration)
Tauri 支持在 已有 Web 应用中集成 Tauri。 这称为 Brownfield(棕地)集成 —— 即把 Tauri 加到现有项目里,而不是从零启动一个新项目。 这对于步骤渐进迁移、现有应用转桌面端非常有用。
以下指南展示如何在已有 Web 应用中设置调用 Rust 端命令。 (v2.tauri.app)
前提条件(Prerequisites)
要在棕地应用中使用 IPC,你的项目需要:
- 一个 现有 Web 应用
- 安装了 @tauri-apps/api
- Tauri 目录(即
src-tauri/)已经初始化
如果没有初始化 Tauri,可以运行:
tauri init
之后需要确保你的项目:
- 可在浏览器中独立运行
- 构建后会生成静态资源目录(例如:
dist/)
这对于 Tauri 正常加载前端是必要的。 (v2.tauri.app)
在前端调用 Rust 命令
在 已有 Web 应用代码 中,你可以直接像使用普通 API 一样调用 Tauri 命令。
安装 API 包
确保先安装:
npm install @tauri-apps/api
或者:
yarn add @tauri-apps/api
然后在 Web 端代码中导入:
import { invoke } from '@tauri-apps/api/tauri';
示例:调用 Rust 命令
假设 Rust 端已经定义命令:
#[tauri::command]
fn multiply(a: i32, b: i32) -> i32 {
a * b
}
那么前端调用方式如下:
import { invoke } from '@tauri-apps/api/tauri';
const result = await invoke('multiply', { a: 5, b: 7 });
console.log(result); // 35
注意:
invoke()第一个参数是命令名称- 第二个参数是命令参数对象 → 键必须与命令参数名一致
发送事件给前端
Rust 可以主动触发事件通知 Web 端:
tauri::Window::emit_all(
&window,
"notification",
"新的消息来了!"
)?;
前端监听:
import { listen } from '@tauri-apps/api/event';
const unlisten = await listen('notification', event => {
console.log(event.payload); // "新的消息来了!"
});
条件加载 IPC
在 Brownfield 集成场景下:
因为你的 Web 应用可能也会在 普通浏览器中运行, 而浏览器无法加载 Tauri API(不存在 WebView 环境)。
因此推荐做条件判断 —— 如果运行在 Tauri 环境,才用 IPC:
import { isTauri } from '@tauri-apps/api/tauri';
if (isTauri) {
invoke('multiply', { a: 5, b: 7 });
}
isTauri在非 Tauri 浏览器中为false在 Tauri WebView 中为true
这样你的 Web 代码仍可在浏览器中正常运行,而不会因找不到 Tauri API 报错。
Rust 命令参数校验
即便在 Brownfield 场景下,你仍应:
- 校验 Rust 命令输入参数
- 不信任来自前端的任何输入
- 在 Rust 内部做严格检查
例如:
#[tauri::command]
fn div(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
return Err("除数不能为 0".into());
}
Ok(a / b)
}
然后前端处理可能的错误:
try {
const res = await invoke('div', { a: 10, b: 0 });
} catch (err) {
console.error(err);
}
注意事件监听生命周期
如果你在前端监听事件:
const unlisten = await listen('my-event', handler);
请务必在组件卸载或不需要时:
unlisten(); // 移除监听
避免内存泄漏或重复事件触发。
指令冲突避免
在棕地项目中,你可能已有很多命令或函数名。 为了避免 IPC 命令名冲突,你可以采用 命名空间(namespace)约定:
例如:
#[tauri::command]
fn file_read(path: String) -> String { … }
可以写成:
#[tauri::command]
fn fs_read_file(path: String) -> String { … }
这样在大型项目中可以更容易维护 IPC 接口。
总结(Summary)
在棕地集成场景中:
1️⃣ 确保 Tauri API 在 Web 项目中可用 2️⃣ 在 Web 端做条件判断(非 Tauri 环境不执行 IPC) 3️⃣ Rust 端严格验证参数 4️⃣ 事件监听要及时移除 5️⃣ 使用命名规则避免冲突
📌 这种方式让你能在 现有 Web 应用基础上:
✔ 无侵入加入桌面客户端 ✔ 与现有逻辑共存 ✔ 最小改动迁移至 Tauri
