00 / 00
Desktop 项目结构
01MVP Desktop 模板的前端、runtime adapter、Tauri 和后端接入边界
桌面模板分四层:React 前端、API/Auth client、Tauri runtime adapter、Rust/Tauri 原生层。新手最容易犯的错是跨层导入——比如在 React 组件里直接散写 Tauri plugin 调用,或让桌面端 import Web app 里的模块。
products/01mvp/apps/desktop
├── src
│ ├── components # 模板 UI 组件
│ ├── config # VITE_DESKTOP_* 校验
│ ├── hooks # 偏好等客户端状态
│ ├── lib # Better Auth、oRPC、QueryClient
│ ├── runtime # Tauri adapter,浏览器预览 fallback
│ ├── App.tsx # 首屏工作台
│ ├── main.tsx
│ └── styles.css # Tailwind v4 入口和最小全局样式
├── src-tauri
│ ├── capabilities # Tauri v2 权限
│ ├── icons # Bundle icon
│ ├── src # Rust commands
│ ├── Cargo.toml
│ └── tauri.conf.json
├── .env.example
├── README.md
├── package.json
├── tsconfig.json
└── vite.config.ts每个目录负责什么
| 目录 | 职责 |
|---|---|
src/components | 只放模板 UI 组件,不放 API client 和 Tauri command 细节 |
src/config | 校验 VITE_DESKTOP_*,让错误尽早暴露 |
src/hooks | 组合 React state、query、runtime adapter |
src/lib | Better Auth、oRPC、TanStack Query 入口 |
src/runtime | TypeScript 侧唯一的 Tauri 入口,每个能力都要有浏览器 fallback |
src-tauri/src | Rust commands、tray、single instance、原生文件读写 |
src-tauri/capabilities | Tauri v2 权限配置 |
src-tauri/tauri.conf.json | 应用 identity、窗口、CSP、bundle、签名和构建配置 |
后端边界
桌面端不 import products/01mvp/apps/web/src/*。业务数据通过 @01mvp/api 类型和 oRPC client 访问。
桌面端有自己的 oRPC adapter:
src/lib/api-client.ts指向${VITE_DESKTOP_SERVER_URL}/rpcsrc/lib/auth-client.ts指向${VITE_DESKTOP_SERVER_URL}/auth- 浏览器/WebView fetch 使用
credentials: "include"
服务端仍由 Web app 承载:
products/01mvp/apps/web/src/server/hono.ts
products/01mvp/packages/auth/src/index.ts
products/01mvp/packages/api/src/router.ts桌面端只通过公开 HTTP 边界和这些服务交互。
Runtime 边界
src/runtime/* 是 TypeScript 侧对 Tauri 的唯一入口。每个 adapter 都要有浏览器预览 fallback,方便用普通 Vite dev server 调试 UI。
Rust 侧只保留模板通用能力:
- 读取和保存本地偏好
- 打开 app data 目录
- 托盘打开/退出
- single instance
- process/opener plugin skeleton
Updater 的 TypeScript 入口已保留,但默认不注册 Rust updater plugin;只有配好发布端点、签名公钥和产物策略后才启用。截图、录音、全局快捷键、文件系统或原生数据库也应在复制模板后按需加,不放进默认 scaffold。
加新功能的顺序
要加一个系统能力,按这个顺序做:
- 在
src-tauri/src/lib.rs新增 Rust command 或注册 Tauri plugin。 - 在
src-tauri/capabilities/default.json只开放需要的权限。 - 在
src/runtime/<feature>.ts封装 TypeScript adapter。 - 给 adapter 提供浏览器 fallback,至少返回清晰的 unavailable 状态。
- 在
src/hooks或组件里使用 adapter。 - 增加契约测试,确认浏览器 fallback 和参数处理正确。
这样排查问题时,能清楚区分前端状态、API 请求、Tauri IPC 和 Rust 原生逻辑。
这篇文档有问题?