普通视图

发现新文章,点击刷新页面。
昨天以前首页

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

2025年3月31日 22:02

前言

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

image.png

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 命令行标志。

pnpm tauri plugin new [name]

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

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

. 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

[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. 实现插件结构

// 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 命令

// 添加命令处理
#[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. 前端调用插件

// 前端集成 (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 端触发事件
app.emit_all("plugin-event", "数据载荷").unwrap();

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

2. 状态管理

// 定义共享状态
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. 本地插件引用

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

2. 初始化插件

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

发布插件

1. 打包发布到 crates.io

cargo publish --allow-dirty

2. 前端用户安装

npm install tauri-plugin-example

调试技巧

  1. Rust 日志输出

    log::info!("调试信息: {:?}", data);
    

    启动应用时加环境变量:

    RUST_LOG=info cargo tauri dev
    
  2. 前端 DevTools

    .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…

Tauri(十七)—— 安装包和应用包的区别

2025年3月31日 19:40

Tauri 的 安装包应用包 在开发流程和最终产物中扮演不同角色,以下是两者的核心区别及技术细节:

定义与功能

  1. 安装包 (Installation Package)

    • 作用:用户直接运行的安装程序文件(如 .exe.dmg.deb),负责将应用程序部署到目标系统。
    • 特点
      • 包含应用程序二进制文件、依赖资源和安装脚本。
      • 可能集成 WebView 运行时(如 Windows 的 WebView2),具体取决于 tauri.conf.json 中的 webviewInstallMode 配置。
      • 支持多种安装模式:在线下载依赖(downloadBootstrapper)、离线嵌入依赖(offlineInstaller)等。
  2. 应用包 (Application Bundle)

    • 作用:安装完成后生成的应用程序本体,包含运行所需的所有文件。
    • 特点
      • 由前端资源(HTML/CSS/JS)、Rust 二进制文件、系统原生库(如 WebView)组成。
      • 平台差异显著:Windows 生成 .exe,macOS 生成 .app,Linux 生成 .debAppImage
      • 体积极小(通常仅 2-5 MB),因依赖系统 WebView 而非内置浏览器引擎。

技术实现差异

维度 安装包 应用包
核心内容 安装程序 + 可选依赖 可执行文件 + 前端资源 + 原生库
体积 受配置影响(如是否嵌入 WebView) 极小(依赖系统组件)
生成方式 通过 tauri build 命令打包 安装包解压或直接编译生成
用户交互 需要用户执行安装流程 直接运行无需安装(如绿色版 AppImage)
跨平台兼容 需为不同平台生成独立安装包 单平台专用(如 macOS 的 .app

配置与优化

  1. 安装包优化

    • WebView 集成策略
      • embedBootstrapper:增加约 1.8MB,兼容 Windows 7。
      • offlineInstaller:增加约 127MB,支持完全离线安装。
    • 签名与安全:支持代码签名防止篡改,需在 tauri.conf.json 中配置证书。
  2. 应用包优化

    • 资源压缩:通过 Tree Shaking 移除未使用的前端代码。
    • 原生功能调用:通过 Rust 接口访问系统 API(如文件读写、硬件传感器)。

典型场景对比

  • 场景 1:小型工具开发

    • 安装包:选择 downloadBootstrapper 减少体积,依赖用户联网安装 WebView。
    • 应用包:依赖系统 WebView,运行时内存占用低至 80MB(Electron 通常 120MB+)。
  • 场景 2:企业级分发

    • 安装包:使用 offlineInstaller 嵌入所有依赖,适合内网环境。
    • 应用包:通过签名确保来源可信,支持自动更新功能。

开发者注意事项

  1. 跨平台适配

    • Linux 需预装 libwebkit2gtk 等依赖,否则安装包可能失败。
    • Windows 7 需谨慎选择 WebView 安装模式(推荐 embedBootstrapper)。
  2. 调试与测试

    • 开发阶段使用 tauri dev 直接运行应用包,跳过安装流程。
    • 生产环境需测试不同安装模式下的用户兼容性。

小结

Tauri 通过分离 安装包(分发载体)和 应用包(运行实体),实现了轻量化与高性能的平衡。开发者需根据目标平台和用户环境,灵活选择安装包配置策略(如 WebView 嵌入方式),同时利用 Rust 的编译优化提升应用包效率。

Mac 命令行及 Linux 使用指南与示例

2025年3月30日 21:30

通用基础命令(Mac 和 Linux 均适用)

1. 文件与目录操作

命令 功能说明 示例
ls 列出目录内容 ls -al(显示所有文件,包括隐藏文件)
cd 切换目录 cd ~/Documents(进入用户文档目录)
pwd 显示当前目录路径 pwd
cp 复制文件或目录 cp file.txt backup/
mv 移动或重命名文件 mv old.txt new.txt
rm 删除文件或目录 rm -rf dir/(强制递归删除目录)
mkdir 创建目录 mkdir project
touch 创建空文件 touch newfile.txt

2. 文本操作与处理

命令 功能说明 示例
cat 查看文件内容 cat log.txt
grep 文本搜索 grep "error" /var/log/syslog
echo 输出内容或写入文件 echo "Hello" > hello.txt
nano / vim 文本编辑器 vim notes.md
head / tail 查看文件头/尾部内容 tail -f log.txt(实时追踪日志)

3. 系统信息与进程管理

命令 功能说明 示例
ps 查看进程信息 ps aux | grep chrome
top / htop 实时监控系统资源 htop(需安装)
kill 终止进程 kill -9 1234(强制终止 PID 1234 的进程)
df / du 查看磁盘使用情况 df -h(以易读格式显示磁盘空间)
free 查看内存使用(Linux) free -m(显示内存以 MB 为单位)

Mac 特有命令与工具

1. 系统信息与管理

命令/工具 功能说明 示例
sw_vers 查看 macOS 版本 sw_vers -productVersion
system_profiler 查看硬件和系统信息 system_profiler SPHardwareDataType
open 用默认程序打开文件或目录 open .(在 Finder 中打开当前目录)
pbcopy / pbpaste 剪贴板操作 cat file.txt | pbcopy(复制文件内容到剪贴板)

2. 包管理工具:Homebrew

# 安装 Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# 常用操作
brew install wget     # 安装软件
brew update           # 更新包列表
brew upgrade          # 升级所有已安装包
brew remove node      # 卸载软件

Linux 特有命令与工具

1. 包管理(Debian/Ubuntu)

# 更新与安装
sudo apt update        # 更新软件源
sudo apt install nginx # 安装软件
sudo apt remove nginx  # 卸载软件
sudo apt autoremove    # 清理无用依赖

# 查看已安装软件
apt list --installed

2. 系统服务管理(Systemd)

sudo systemctl start nginx    # 启动服务
sudo systemctl stop nginx     # 停止服务
sudo systemctl restart nginx  # 重启服务
sudo systemctl status nginx   # 查看服务状态

3. 网络工具

# 查看 IP 地址(Linux)
ip addr show

# 测试网络连通性
ping google.com

# 查看开放端口
netstat -tuln

Mac 与 Linux 的差异点

1. 命令参数差异

功能 Mac(BSD 风格) Linux(GNU 风格)
查看文件修改时间 ls -lT ls -l --time-style=full-iso
文本替换(sed) sed -i '' 's/old/new/g' file sed -i 's/old/new/g' file
计算 MD5 校验和 md5 file.txt md5sum file.txt

2. 文件系统路径差异

类型 Mac Linux
用户主目录 /Users/username /home/username
临时目录 /private/tmp /tmp
系统日志 /var/log/system.log /var/log/syslog

实用场景示例

1. 批量重命名文件

# Mac(需安装 rename)
brew install rename
rename 's/old/new/' *.txt

# Linux(使用 rename 或 mmv)
sudo apt install rename
rename 'old' 'new' *.txt

2. 查找文件

# 按名称查找
find ~/ -name "*.log"

# 按内容查找
grep -rn "error" /var/log/

3. 压缩与解压

# 压缩目录为 tar.gz
tar -czvf archive.tar.gz /path/to/dir

# 解压 tar.gz
tar -xzvf archive.tar.gz

# 压缩为 zip(Mac/Linux 通用)
zip -r archive.zip /path/to/dir

安全与权限管理

1. 修改文件权限

chmod 755 script.sh     # 设置权限为 rwxr-xr-x
chown user:group file   # 修改文件所有者和组

2. SSH 密钥管理

# 生成密钥对
ssh-keygen -t ed25519

# 将公钥复制到服务器
ssh-copy-id user@remote-server

开发环境配置

1. Python 虚拟环境

# 创建虚拟环境
python -m venv myenv

# 激活环境(Mac/Linux)
source myenv/bin/activate

2. Node.js 版本管理(nvm)

# 安装 nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash

# 安装 Node.js
nvm install 18
nvm use 18

注意事项

  1. 权限警告

    • 慎用 sudorm -rf,避免误删系统文件。
    • Mac 启用 SIP(系统完整性保护),部分系统目录不可修改。
  2. 脚本兼容性

    • 在 Mac 上使用 GNU 工具(如 gsedgrep)可提高与 Linux 的兼容性:
      brew install coreutils findutils gnu-sed
      
  3. 日志与调试

    • 使用 journalctl(Linux)或 log show(Mac)查看系统日志。

通过掌握这些命令和示例,您可以高效操作 Mac 和 Linux 系统!遇到问题时,记得善用 man <命令> 查看手册(如 man ls)。

❌
❌