Tauri(十八)——如何开发 Tauri 插件

前言

Tauri 项目也做了一段时间了,也有用别人开发的插件。自己也想知道如何开发 Tauri 插件。

Tauri 插件介绍

插件可以挂载到 Tauri 的生命周期中暴露需求 webview API 的 Rust 代码,使用 Rust、Kotlin 或 Swift 代码处理命令并能处理更多需求。

Tauri 提供了一个基于 webview 功能的视窗系统,一个在 Rust 进程和 webview 之间发送信息的方式,一个事件系统,以及一些增强开发体验的工具。 设计上 Tauri Core 只包含所有人都需要的功能。相对地,它提供了一种将外部功能添加到 Tauri 应用程序中的机制,被称为插件。

一个 Tauri 插件由一个 Cargo 包和一个可选的 NPM 包(用于提供命令和事件 API 绑定)构成

何时需要开发 Tauri 插件?

  1. 需要访问系统原生 API(文件、硬件、网络底层)
  2. 性能关键型任务(大数据处理、实时计算)
  3. 代码复用与团队协作(跨项目共享功能模块)
  4. 安全敏感场景(加密、认证、许可证管理)

通过 Tauri 插件,开发者可以 兼顾 Web 的开发效率与 Native 的性能能力,构建真正高性能、跨平台的桌面应用。

Tauri 插件核心概念

插件作用:封装可复用的跨平台功能模块(如硬件访问、加密算法),通过 Rust 后端 + 前端 API 暴露能力。

技术栈

  • Rust:核心逻辑实现
  • TypeScript/JavaScript:前端 API 接口
  • WASM(可选):浏览器端直接调用

创建基础插件模板

1. 命名规范

Tauri 插件具有一个前缀(Rust 包使用 tauri-plugin- 前缀,NPM 包使用 @tauri-apps/plugin- 前缀),随后是插件名称。 插件名称由插件配置中的 tauri.conf.json > plugin 和许可列表中的配置确定。

默认情况下,Tauri 会在你的插件 crate 前面加上 tauri-plugin-。这有助于你的插件被 Tauri 社区发现,但不是必须的。初始化新插件项目时,必须提供其名称。生成包名称将为 tauri-plugin-{plugin-name},JavaScript NPM 包名称为 tauri-plugin-{plugin-name}-api(尽管我们建议使用 NPM 范围如果可能的话)。NPM 包的 Tauri 命名约定是 @scope-name/plugin-{plugin-name}

2. 初始化 Rust 插件库

使用引导创建一个新的插件项目,请运行 plugin new。如果不需要相应的 NPM 程序包,请使用 --no-api 命令行标志。

bash 复制代码
pnpm tauri plugin new [name]

cargo new tauri-plugin-example --lib
cd tauri-plugin-example

这会在 tauri-plugin-[name] 目录下初始化插件,取决于初始化插件时所选择的命令行标志,项目将具有以下结构:

css 复制代码
. tauri-plugin-[name]/
├── src/                - Rust 代码
│ ├── commands.rs       - 定义 webview 可用的命令
| ├── desktop.rs        - 桌面实现
| ├── error.rs          - 用于返回 results 的默认的错误类型
│ ├── lib.rs            - 重新导出适当的实现、设置状态......
│ ├── mobile.rs         - 移动端实现
│ └── models.rs         - 公共的结构体
├── permissions/        - 这将托管(生成的)命令的权限文件
├── android             - 安卓库
├── ios                 - Swift 包
├── guest-js            - JavaScript API 绑定的源代码
├── dist-js             - 从 guest-js 转译的资源
├── Cargo.toml          - Cargo 包元数据
└── package.json        - NPM 包元数据

3. 编辑 Cargo.toml

toml 复制代码
[package]
name = "tauri-plugin-example"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]  # 编译为动态库

[dependencies]
tauri = { version = "2.0", features = ["plugin"] }
serde = { version = "1.0", features = ["derive"] }  # 序列化支持

4. 实现插件结构

rust 复制代码
// src/lib.rs
use tauri::{
  plugin::{Builder, TauriPlugin},
  Runtime, AppHandle,
};

// 定义插件配置(可选)
#[derive(serde::Deserialize)]
pub struct Config {
  api_key: String,
}

// 核心插件实现
pub fn init<R: Runtime>() -> TauriPlugin<R, Config> {
  Builder::new("example")
    .setup(|app, config| {
      println!("插件初始化,配置密钥: {}", config.api_key);
      Ok(())
    })
    .invoke_handler(|app, invoke| {
      // 处理前端调用
    })
    .build()
}

5. 生命周期事件

插件可以挂载到如下生命周期事件中:

实现前后端通信

1. 定义 Rust 命令

rust 复制代码
// 添加命令处理
#[tauri::command]
fn greet(name: &str) -> String {
  format!("Hello, {}!", name)
}

// 更新插件初始化
pub fn init<R: Runtime>() -> TauriPlugin<R, Config> {
  Builder::new("example")
    .setup(|app, config| { /* ... */ })
    .invoke_handler(tauri::generate_handler![greet])  // 注册命令
    .build()
}

2. 前端调用插件

typescript 复制代码
// 前端集成 (JavaScript/TypeScript)
import { invoke } from "@tauri-apps/api";

async function callPlugin() {
  const response = await invoke("plugin:example|greet", { name: "World" });
  console.log(response); // 输出 "Hello, World!"
}

高级功能扩展

1. 事件系统

rust 复制代码
// Rust 端触发事件
app.emit_all("plugin-event", "数据载荷").unwrap();

// 前端监听
import { listen } from "@tauri-apps/api/event";
listen("plugin-event", (event) => {
  console.log("收到事件:", event.payload);
});

2. 状态管理

rust 复制代码
// 定义共享状态
struct AppState {
  counter: Mutex<i32>,
}

// 注册状态
app.manage(AppState { counter: Mutex::new(0) });

// 在命令中使用状态
#[tauri::command]
fn increment(state: State<AppState>) -> i32 {
  let mut counter = state.counter.lock().unwrap();
  *counter += 1;
  *counter
}

插件集成到 Tauri 应用

1. 本地插件引用

toml 复制代码
# 主应用 Cargo.toml
[dependencies]
tauri-plugin-example = { path = "../tauri-plugin-example" }

2. 初始化插件

rust 复制代码
// main.rs
fn main() {
  tauri::Builder::default()
    .plugin(tauri_plugin_example::init())
    .run(tauri::generate_context!())
    .expect("运行失败");
}

发布插件

1. 打包发布到 crates.io

bash 复制代码
cargo publish --allow-dirty

2. 前端用户安装

bash 复制代码
npm install tauri-plugin-example

调试技巧

  1. Rust 日志输出

    rust 复制代码
    log::info!("调试信息: {:?}", data);

    启动应用时加环境变量:

    bash 复制代码
    RUST_LOG=info cargo tauri dev
  2. 前端 DevTools

    rust 复制代码
    .setup(|app| {
      #[cfg(debug_assertions)]
      app.get_window("main").unwrap().open_devtools();
      Ok(())
    })

相关插件

  1. github.com/tauri-apps/...
  2. v2.tauri.app/zh-cn/plugi...
  3. v2.tauri.app/zh-cn/devel...
相关推荐
C澒2 分钟前
IntelliPro 产研协作平台:基于 AI Agent 的低代码智能化配置方案设计与实现
前端·低代码·ai编程
一袋米扛几楼9812 分钟前
【Git】规范化协作:详解 GitHub 工作流中的 Issue、Branch 与 Pull Request 最佳实践
前端·git·github·issue
网络点点滴25 分钟前
前端与后端的区别与联系
前端
时空系26 分钟前
认识Rust——我的第一个程序 Rust中文编程
开发语言·后端·rust
EnCi Zheng1 小时前
M5-markconv自定义CSS样式指南 [特殊字符]
前端·css·python
kyriewen1 小时前
你的网页慢,用户不说直接走——前端性能监控教你“读心术”
前端·性能优化·监控
广州华水科技1 小时前
北斗GNSS变形监测在大坝安全监测中的应用与优势分析
前端
前端老石人1 小时前
前端开发中的 URL 完全指南
开发语言·前端·javascript·css·html
CAE虚拟与现实1 小时前
五一假期闲来无事,来个前段、后端的说明吧
前端·后端·vtk·three.js·前后端
时空系1 小时前
第10篇:归属权与借用——Rust的安全保障 Rust中文编程
开发语言·安全·rust