--- title: 开发指南 description: 从源代码构建、测试和贡献 DropOut --- # 开发指南 本指南将帮助你设置开发环境、从源代码构建 DropOut,以及为项目做出贡献。 ## 前置要求 ### 必需软件 1. **Rust** (最新稳定版) ```bash # 通过 rustup 安装 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` 2. **Node.js** (v22+) 和 **pnpm** (v9+) ```bash # 从 https://nodejs.org/ 安装 Node.js # 安装 pnpm npm install -g pnpm@9 ``` 3. **系统依赖** 按照你的平台参考 [Tauri 前置要求](https://v2.tauri.app/start/prerequisites/): **Linux (Debian/Ubuntu):** ```bash sudo apt update sudo apt install libwebkit2gtk-4.1-dev \ build-essential \ curl \ wget \ file \ libssl-dev \ libayatana-appindicator3-dev \ librsvg2-dev ``` **macOS:** ```bash xcode-select --install ``` **Windows:** - 安装 [Microsoft Visual C++ Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) - 安装 [WebView2](https://developer.microsoft.com/microsoft-edge/webview2/) ## 快速开始 ### 克隆仓库 ```bash git clone https://github.com/HydroRoll-Team/DropOut.git cd DropOut ``` ### 安装依赖 **前端依赖:** ```bash cd packages/ui pnpm install cd ../.. ``` **文档依赖:** ```bash cd packages/docs pnpm install cd ../.. ``` ### 开发模式 以开发模式运行 DropOut,支持热重载: ```bash cargo tauri dev ``` 这将: 1. 启动前端开发服务器(Vite 在 5173 端口) 2. 编译 Rust 后端 3. 打开 Tauri 窗口 4. 为前端更改启用热重载 5. 在 Rust 文件更改时重新编译 **终端输出:** - 来自 Vite 的前端日志 - Rust 标准输出/标准错误 - 编译状态 ### 构建生产版本 构建发布二进制文件: ```bash cargo tauri build ``` **输出位置:** - **Linux**: `src-tauri/target/release/bundle/` - `.deb` 软件包 - `.AppImage` 包 - **macOS**: `src-tauri/target/release/bundle/` - `.dmg` 安装器 - `.app` 包 - **Windows**: `src-tauri/target/release/bundle/` - `.msi` 安装器 - `.exe` 可执行文件 ## 项目结构 ``` DropOut/ ├── src-tauri/ # Rust 后端 │ ├── src/ │ │ ├── main.rs # Tauri 命令和入口点 │ │ ├── core/ # 核心模块 │ │ │ ├── auth.rs # 身份验证 │ │ │ ├── downloader.rs # 下载管理器 │ │ │ ├── fabric.rs # Fabric 支持 │ │ │ ├── forge.rs # Forge 支持 │ │ │ ├── java.rs # Java 管理 │ │ │ ├── instance.rs # 实例系统 │ │ │ └── ... │ │ └── utils/ # 工具类 │ └── Cargo.toml ├── packages/ │ ├── ui/ # Svelte 5 前端 │ │ ├── src/ │ │ │ ├── App.svelte │ │ │ ├── components/ │ │ │ ├── stores/ # 状态管理 │ │ │ └── lib/ │ │ └── package.json │ └── docs/ # 文档站点 │ ├── content/docs/ │ └── package.json ├── .github/ │ └── workflows/ # CI/CD 流水线 └── scripts/ # 构建脚本 ``` ## 开发工作流 ### 前端开发 **启动开发服务器:** ```bash cd packages/ui pnpm dev ``` **类型检查:** ```bash pnpm check ``` **代码检查:** ```bash pnpm lint ``` **格式化代码:** ```bash pnpm format ``` ### 后端开发 **运行 Rust 测试:** ```bash cargo test ``` **检查代码:** ```bash cargo check ``` **格式化代码:** ```bash cargo fmt ``` **代码检查:** ```bash cargo clippy ``` ### 文档开发 **启动文档开发服务器:** ```bash cd packages/docs pnpm dev ``` **构建文档:** ```bash pnpm build ``` **类型检查:** ```bash pnpm types:check ``` ## 代码风格 ### Rust 遵循标准 Rust 约定: - 使用 `cargo fmt` 格式化 - 使用 `cargo clippy` 检查 - 编写文档注释 (`///`) - 正确处理错误 - 对 I/O 使用 async/await **示例:** ```rust /// Starts the Microsoft authentication device flow #[tauri::command] async fn start_microsoft_login( window: Window, ) -> Result { emit_log!(window, "Starting Microsoft login..."); start_device_flow() .await .map_err(|e| e.to_string()) } ``` ### TypeScript/Svelte 遵循项目约定: - 使用 Svelte 5 runes (`$state`, `$effect`) - 优先使用 TypeScript 而非 JavaScript - 使用 Biome 进行格式化和检查 - 遵循组件结构 **示例:** ```typescript // stores/auth.svelte.ts export class AuthState { currentAccount = $state(null); isLoginModalOpen = $state(false); async login(username: string) { const account = await invoke('offline_login', { username }); this.currentAccount = account; } } ``` ## 测试 ### 单元测试 **Rust:** ```rust #[cfg(test)] mod tests { use super::*; #[test] fn test_generate_offline_uuid() { let uuid = generate_offline_uuid("Player"); assert!(uuid.len() > 0); } } ``` **运行:** ```bash cargo test ``` ### 集成测试 测试完整应用程序: 1. 以开发模式构建:`cargo tauri dev` 2. 手动测试功能 3. 检查控制台错误 4. 验证 UI 行为 ### CI 测试 GitHub Actions 在以下平台运行测试: - Ubuntu(最新版) - Arch Linux(Wayland) - Windows(最新版) - macOS(ARM64) 查看工作流:`.github/workflows/test.yml` ## 调试 ### 前端调试 1. 在 Tauri 窗口中打开开发工具:`Ctrl+Shift+I`(Windows/Linux)或 `Cmd+Option+I`(macOS) 2. 检查控制台错误 3. 使用 React DevTools 或 Svelte DevTools 4. 监控网络标签页查看 API 调用 ### 后端调试 **打印调试:** ```rust emit_log!(window, format!("Debug: {}", value)); println!("Debug: {}", value); ``` **Rust 调试器:** ```bash # 安装 rust-lldb 或 rust-gdb cargo install rust-gdb # 调试 rust-gdb target/debug/dropout ``` ### 日志 **前端:** ```typescript console.log("Info message"); console.error("Error message"); ``` **后端:** ```rust emit_log!(window, "Status update"); eprintln!("Error: {}", error); ``` ## 贡献 ### 贡献工作流 1. **Fork** 仓库 2. **创建**功能分支: ```bash git checkout -b feature/my-feature ``` 3. **进行**更改 4. **彻底测试** 5. **提交**时使用约定式提交: ```bash git commit -m "feat: add new feature" ``` 6. **推送**到你的 fork: ```bash git push origin feature/my-feature ``` 7. **创建** Pull Request ### 提交消息 遵循 [约定式提交](https://www.conventionalcommits.org/): **格式:** ``` [scope]: [optional body] [optional footer] ``` **类型:** - `feat`: 新功能 - `fix`: 错误修复 - `docs`: 文档 - `style`: 格式化 - `refactor`: 代码重构 - `perf`: 性能改进 - `test`: 添加测试 - `chore`: 维护 **示例:** ```bash feat(auth): add offline authentication support fix(java): resolve detection on Windows docs: update installation guide refactor(download): simplify progress tracking ``` ### Pull Request 指南 **提交前:** - [ ] 代码遵循风格指南 - [ ] 测试在本地通过 - [ ] 必要时更新文档 - [ ] 没有提交不必要的文件 - [ ] 提交消息清晰 **PR 描述:** - 解释做了什么以及为什么 - 链接相关 issue - 列出破坏性更改 - 为 UI 更改添加截图 ### 代码审查 维护者将审查你的 PR: - 代码质量和风格 - 测试覆盖率 - 文档 - 性能影响 - 安全影响 对反馈保持响应并进行要求的更改。 ## 常见任务 ### 添加 Tauri 命令 1. **在 `main.rs` 中定义命令:** ```rust #[tauri::command] async fn my_command(param: String) -> Result { Ok(format!("Received: {}", param)) } ``` 2. **在构建器中注册:** ```rust .invoke_handler(tauri::generate_handler![ my_command, // ... 其他命令 ]) ``` 3. **从前端调用:** ```typescript const result = await invoke('my_command', { param: 'value' }); ``` ### 添加 UI 组件 1. **创建组件文件:** ```svelte ``` 2. **导入并使用:** ```svelte ``` ### 添加 Store 1. **创建 store 文件:** ```typescript // packages/ui/src/stores/mystore.svelte.ts export class MyState { value = $state(0); increment() { this.value++; } } export const myState = new MyState(); ``` 2. **在组件中使用:** ```svelte ``` ## 开发问题故障排除 ### 构建失败 **"cannot find -lwebkit2gtk"** ```bash # 安装 WebKit 依赖 sudo apt install libwebkit2gtk-4.1-dev ``` **"pnpm not found"** ```bash # 安装 pnpm npm install -g pnpm@9 ``` **"Rust version too old"** ```bash # 更新 Rust rustup update ``` ### 运行时问题 **"Failed to load dynamic library"** - 重新构建:`cargo clean && cargo tauri dev` - 检查库路径 - 验证已安装依赖 **"CORS error"** - 开发模式下正常 - Tauri 自动处理 CORS **"Hot reload not working"** - 检查 Vite 配置 - 重启开发服务器 - 清除浏览器缓存 ## 资源 - [Tauri 文档](https://v2.tauri.app/) - [Svelte 5 文档](https://svelte.dev/docs) - [Rust 程序设计语言](https://doc.rust-lang.org/book/) - [DropOut 仓库](https://github.com/HydroRoll-Team/DropOut) ## 获取帮助 - **Issues**: [GitHub Issues](https://github.com/HydroRoll-Team/DropOut/issues) - **讨论**: [GitHub Discussions](https://github.com/HydroRoll-Team/DropOut/discussions) - **文档**: 本站点