Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
重构所有代码和文档中的项目名称,将OpenFang统一更新为ZCLAW。包括: - 配置文件中的项目名称 - 代码注释和文档引用 - 环境变量和路径 - 类型定义和接口名称 - 测试用例和模拟数据 同时优化部分代码结构,移除未使用的模块,并更新相关依赖项。
7.5 KiB
7.5 KiB
Tauri 桌面端开发笔记
记录 ZCLAW Desktop Tauri 开发过程中的经验和注意事项。
1. 项目结构
desktop/
├── src/ # React 前端
│ ├── components/ # UI 组件
│ ├── store/ # Zustand 状态管理
│ ├── lib/ # 工具库
│ └── App.tsx # 入口组件
├── src-tauri/ # Tauri Rust 后端
│ ├── src/
│ │ ├── lib.rs # 主入口
│ │ └── main.rs # 主函数
│ ├── Cargo.toml # Rust 依赖
│ ├── tauri.conf.json # Tauri 配置
│ └── build.rs # 构建脚本
├── package.json
└── vite.config.ts
2. 开发命令
2.1 常用命令
# 启动开发服务器 (Vite + Tauri)
pnpm tauri dev
# 仅启动前端 (Vite)
pnpm dev
# 构建生产版本
pnpm tauri build
# 类型检查
pnpm tsc --noEmit
2.2 命令说明
| 命令 | 说明 | 端口 |
|---|---|---|
pnpm dev |
仅 Vite 开发服务器 | 1420 |
pnpm tauri dev |
Tauri + Vite | 1420 (Vite) + Native Window |
pnpm tauri build |
生产构建 | - |
3. 配置文件
3.1 tauri.conf.json 关键配置
{
"build": {
"beforeDevCommand": "pnpm dev",
"beforeBuildCommand": "pnpm build",
"devPath": "http://localhost:1420",
"distDir": "../dist"
},
"tauri": {
"windows": [
{
"title": "ZCLAW",
"width": 1200,
"height": 800,
"resizable": true,
"fullscreen": false
}
],
"security": {
"csp": "default-src 'self'; connect-src 'self' ws://localhost:* ws://127.0.0.1:*"
}
}
}
3.2 Vite 配置
// vite.config.ts
export default defineConfig({
plugins: [react()],
server: {
port: 1420,
strictPort: true,
proxy: {
'/api': {
target: 'http://127.0.0.1:50051',
changeOrigin: true,
secure: false,
ws: true, // WebSocket 支持
},
},
},
});
4. 常见问题
4.1 端口占用
症状: Port 1420 is already in use
解决方案:
# 查找占用进程
netstat -ano | findstr "1420"
# 终止进程
Stop-Process -Id <PID> -Force
4.2 Tauri 编译失败
常见原因:
-
Rust 版本过低
rustup update -
依赖缺失
# Windows 需要 Visual Studio Build Tools # 安装: https://visualstudio.microsoft.com/visual-cpp-build-tools/ # 确保 C++ 工作负载已安装 -
Cargo 缓存问题
cd desktop/src-tauri cargo clean cargo build
4.3 窗口白屏
排查步骤:
- 检查 Vite 开发服务器是否运行
- 打开 DevTools (F12) 查看控制台错误
- 检查
tauri.conf.json中的devPath
解决方案:
// 确保在 tauri.conf.json 中启用 devtools
{
"tauri": {
"windows": [{
"devtools": true // 开发模式下启用
}]
}
}
4.4 热重载不工作
检查:
beforeDevCommand是否正确配置- 文件监听限制 (Linux)
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf sudo sysctl -p
5. IPC 通信
5.1 Rust 端暴露命令
// src-tauri/src/lib.rs
#[tauri::command]
fn get_app_version() -> String {
env!("CARGO_PKG_VERSION").to_string()
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![
get_app_version,
// 其他命令
])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
5.2 前端调用
import { invoke } from '@tauri-apps/api/core';
const version = await invoke<string>('get_app_version');
5.3 常用 Tauri API
| API | 用途 |
|---|---|
@tauri-apps/api/core |
invoke, convertFileSrc |
@tauri-apps/api/window |
窗口管理 |
@tauri-apps/api/shell |
执行 shell 命令 |
@tauri-apps/api/fs |
文件系统 |
@tauri-apps/api/path |
路径 API |
6. 安全配置
6.1 CSP 配置
{
"tauri": {
"security": {
"csp": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src 'self' ws://localhost:* ws://127.0.0.1:* http://127.0.0.1:*; font-src 'self' https://fonts.gstatic.com"
}
}
}
6.2 允许的协议
确保 CSP 允许:
ws://localhost:*- 本地 WebSocketws://127.0.0.1:*- ZCLAW WebSockethttp://127.0.0.1:*- ZCLAW REST API
7. 本地 Gateway 集成
7.1 Bundled Runtime
ZCLAW Desktop 可以捆绑 ZCLAW Runtime:
desktop/src-tauri/resources/
└── zclaw-runtime/
├── zclaw.exe
├── config/
└── ...
7.2 启动本地 Gateway
#[tauri::command]
async fn start_local_gateway(app: AppHandle) -> Result<(), String> {
let resource_path = app.path_resolver()
.resource_dir()
.ok_or("Failed to get resource dir")?;
let zclaw_path = resource_path.join("zclaw-runtime/zclaw.exe");
// 启动进程
Command::new(zclaw_path)
.args(["start"])
.spawn()
.map_err(|e| e.to_string())?;
Ok(())
}
7.3 检测 Gateway 状态
// 前端检测
async function checkGatewayStatus(): Promise<'running' | 'stopped'> {
try {
const response = await fetch('http://127.0.0.1:50051/api/health');
if (response.ok) {
return 'running';
}
} catch {
// Gateway 未运行
}
return 'stopped';
}
8. 构建发布
8.1 构建命令
pnpm tauri build
输出位置:
desktop/src-tauri/target/release/
├── desktop.exe # 可执行文件
└── bundle/
├── msi/ # Windows 安装包
└── nsis/ # NSIS 安装包
8.2 构建配置
{
"tauri": {
"bundle": {
"identifier": "com.zclaw.desktop",
"icon": ["icons/32x32.png", "icons/128x128.png", "icons/icon.ico"],
"targets": ["msi", "nsis"],
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": ""
}
}
}
}
8.3 减小体积
# Cargo.toml
[profile.release]
lto = true
codegen-units = 1
panic = "abort"
strip = true
9. 调试技巧
9.1 启用 DevTools
开发模式下自动启用,生产模式需要在配置中启用:
{
"tauri": {
"windows": [{
"devtools": true
}]
}
}
9.2 日志记录
use log::{info, error};
#[tauri::command]
fn some_command() -> Result<String, String> {
info!("Command called");
// ...
Ok("result".to_string())
}
9.3 前端调试
// 开发模式下启用详细日志
if (import.meta.env.DEV) {
console.log('[Debug]', ...args);
}
10. 性能优化
10.1 延迟加载
// 延迟加载非关键组件
const Settings = lazy(() => import('./components/Settings'));
const HandsPanel = lazy(() => import('./components/HandsPanel'));
10.2 状态优化
// 使用 selector 避免不必要渲染
const messages = useChatStore((state) => state.messages);
// 而不是
const store = useChatStore();
const messages = store.messages; // 会导致所有状态变化都重渲染
更新历史
| 日期 | 变更 |
|---|---|
| 2026-03-14 | 初始版本 |