插件开发 #
一、插件概述 #
1.1 什么是插件 #
Tauri 插件是扩展应用功能的模块化组件,可以添加新的 API、命令和功能。
text
┌─────────────────────────────────────────────────────────────┐
│ 插件架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Tauri 应用 │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐│ │
│ │ │ 插件 A │ │ 插件 B │ │ 插件 C ││ │
│ │ │ fs │ │ dialog │ │ shell ││ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘│ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
1.2 插件类型 #
| 类型 | 说明 |
|---|---|
| 官方插件 | Tauri 团队维护 |
| 社区插件 | 社区开发者贡献 |
| 自定义插件 | 自己开发的插件 |
二、创建插件 #
2.1 使用脚手架 #
bash
# 创建插件项目
cargo tauri plugin new my-plugin
# 或使用 pnpm
pnpm tauri plugin new my-plugin
2.2 插件结构 #
text
my-plugin/
├── src/
│ ├── lib.rs # 插件主入口
│ └── commands.rs # 命令定义
├── Cargo.toml # Rust 配置
├── permissions/
│ ├── default.toml # 默认权限
│ └── allow-*.toml # 允许权限
├── guest-js/
│ ├── index.ts # 前端 API
│ └── package.json # 前端配置
└── README.md
2.3 插件主入口 #
rust
// src/lib.rs
use tauri::plugin::{Builder, TauriPlugin};
use tauri::Runtime;
mod commands;
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("my-plugin")
.invoke_handler(tauri::generate_handler![
commands::my_command,
])
.build()
}
2.4 定义命令 #
rust
// src/commands.rs
use tauri::command;
#[command]
pub async fn my_command(param: String) -> Result<String, String> {
Ok(format!("Received: {}", param))
}
三、前端 API #
3.1 创建前端模块 #
typescript
// guest-js/index.ts
import { invoke } from '@tauri-apps/api/core';
export async function myFunction(param: string): Promise<string> {
return invoke('my_command', { param });
}
export interface MyPluginOptions {
option1: boolean;
option2: string;
}
3.2 导出模块 #
json
// guest-js/package.json
{
"name": "tauri-plugin-my-plugin",
"version": "1.0.0",
"main": "index.ts",
"types": "index.ts",
"exports": {
".": "./index.ts"
}
}
四、权限配置 #
4.1 定义权限 #
toml
# permissions/default.toml
[default]
description = "Default permissions for my-plugin"
permissions = ["allow-my-command"]
toml
# permissions/allow-my-command.toml
[[permission]]
identifier = "allow-my-command"
description = "Allow my-command"
commands.allow = ["my_command"]
4.2 权限检查 #
rust
use tauri::command;
#[command]
pub async fn protected_command(app: tauri::AppHandle) -> Result<String, String> {
if !app.has_permission("my-plugin:allow-protected") {
return Err("Permission denied".to_string());
}
Ok("Protected operation completed".to_string())
}
五、插件状态 #
5.1 定义状态 #
rust
use std::sync::Mutex;
pub struct PluginState {
data: Mutex<Vec<String>>,
}
impl Default for PluginState {
fn default() -> Self {
Self {
data: Mutex::new(Vec::new()),
}
}
}
5.2 注册状态 #
rust
use tauri::plugin::{Builder, TauriPlugin};
use tauri::Runtime;
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("my-plugin")
.invoke_handler(tauri::generate_handler![
commands::add_data,
commands::get_data,
])
.setup(|app, _api| {
app.manage(PluginState::default());
Ok(())
})
.build()
}
5.3 使用状态 #
rust
use tauri::command;
use tauri::State;
#[command]
pub fn add_data(state: State<PluginState>, item: String) {
state.data.lock().unwrap().push(item);
}
#[command]
pub fn get_data(state: State<PluginState>) -> Vec<String> {
state.data.lock().unwrap().clone()
}
六、插件事件 #
6.1 发送事件 #
rust
use tauri::{command, Emitter};
#[command]
pub async fn trigger_event(app: tauri::AppHandle) -> Result<(), String> {
app.emit("my-plugin:event", { "data": "value" })
.map_err(|e| e.to_string())
}
6.2 前端监听 #
typescript
import { listen } from '@tauri-apps/api/event';
await listen('my-plugin:event', (event) => {
console.log('Event received:', event.payload);
});
七、插件配置 #
7.1 定义配置 #
rust
use serde::Deserialize;
#[derive(Debug, Default, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PluginConfig {
pub enabled: bool,
pub option1: String,
pub option2: i32,
}
7.2 读取配置 #
rust
use tauri::plugin::{Builder, TauriPlugin};
use tauri::Runtime;
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("my-plugin")
.setup(|app, _api| {
let config = app.config()
.plugins
.get("my-plugin")
.and_then(|v| serde_json::from_value(v.clone()).ok())
.unwrap_or_default();
app.manage(config);
Ok(())
})
.build()
}
7.3 配置示例 #
json
// tauri.conf.json
{
"plugins": {
"my-plugin": {
"enabled": true,
"option1": "value",
"option2": 42
}
}
}
八、发布插件 #
8.1 发布到 crates.io #
toml
# Cargo.toml
[package]
name = "tauri-plugin-my-plugin"
version = "1.0.0"
edition = "2021"
description = "My Tauri plugin"
license = "MIT"
repository = "https://github.com/user/tauri-plugin-my-plugin"
bash
# 发布
cargo publish
8.2 发布到 npm #
bash
# 构建
cd guest-js
pnpm build
# 发布
pnpm publish
九、最佳实践 #
9.1 命名规范 #
text
插件名称: my-plugin
Rust crate: tauri-plugin-my-plugin
npm 包: tauri-plugin-my-plugin
9.2 文档 #
markdown
# My Plugin
## Installation
\`\`\`bash
pnpm add tauri-plugin-my-plugin
\`\`\`
## Usage
\`\`\`typescript
import { myFunction } from 'tauri-plugin-my-plugin';
const result = await myFunction('param');
\`\`\`
## API
### myFunction(param: string): Promise<string>
Description of the function.
9.3 错误处理 #
rust
use thiserror::Error;
#[derive(Debug, Error)]
pub enum PluginError {
#[error("Invalid parameter: {0}")]
InvalidParameter(String),
#[error("Operation failed: {0}")]
OperationFailed(String),
}
impl From<PluginError> for String {
fn from(error: PluginError) -> String {
error.to_string()
}
}
十、总结 #
10.1 核心要点 #
| 要点 | 说明 |
|---|---|
| 插件结构 | lib.rs + commands.rs |
| 前端 API | TypeScript 封装 |
| 权限配置 | TOML 文件定义 |
| 状态管理 | 使用 app.manage |
| 事件系统 | 发送和监听事件 |
10.2 下一步 #
现在你已经掌握了插件开发,接下来让我们学习 原生模块,了解如何开发 Rust 原生模块!
最后更新:2026-03-28