使用Rust的单一代码库:代码组织与最佳实践

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言



单体仓库(monorepo)是一种源代码管理方法,它将多个项目(库、应用程序、服务)存储在一个单一的仓库中。在 Rust 生态系统中,这种方法通过 Cargo Workspace 机制获得了强大的支持。本文将分析如何在 Rust 中有效组织单体仓库,探讨其结构、依赖管理和最佳实践。



为什么单体仓库对 Rust 项目有用?它允许您:

  • 在多个 crate(库和二进制文件)之间复用代码。
  • 简化版本管理和 CI/CD。
  • 确保变更的原子性(一次提交可以更新多个 crate)。
  • 减少依赖管理的复杂性。


Cargo Workspace 基础知识



Cargo Workspace 是 Rust 内置的用于管理单体仓库的机制。它将多个 crate 整合在同一个顶层 Cargo.toml 文件之下。



创建工作区



首先,创建一个项目目录,并在根目录中创建 Cargo.toml 文件:



# Cargo.toml (root)[workspace]members = [    "core",    "cli",    "web-api",    "utils"]

[workspace.dependencies]serde = { version = "1.0", features = ["derive"] }tokio = { version = "1.37", features = ["full"] }


这里我们定义了四个 crate:core、cli、web-api 和 utils。关键点在于 [workspace.dependencies]。它允许您为工作区中的所有 crate 指定公共依赖项。每个 crate 都可以引用这些依赖项,而无需重复指定版本。



目录结构



典型的 Rust 单体仓库结构如下所示:



my-monorepo/├── Cargo.toml          # 根工作区├── Cargo.lock          # 公共锁文件├── core/│   ├── Cargo.toml│   └── src/│       └── lib.rs├── cli/│   ├── Cargo.toml│   └── src/│       └── main.rs├── web-api/│   ├── Cargo.toml│   └── src/│       └── main.rs├── utils/│   ├── Cargo.toml│   └── src/│       └── lib.rs└── README.md


每个子目录都是一个独立的 crate,拥有自己的 Cargo.toml。crate 可以是库(lib.rs)或可执行应用程序(main.rs)。



依赖管理与代码复用



内部依赖



工作区内的 crate 可以通过本地路径相互引用。例如,cli 可以依赖于 core 和 utils:



# cli/Cargo.toml[package]name = "cli"version = "0.1.0"edition = "2021"

[dependencies]core = { path = "../core" }utils = { path = "../utils" }serde = { workspace = true }tokio = { workspace = true }


请注意语法 { workspace = true }——它允许您使用在根目录 Cargo.toml 中声明的公共依赖项。这确保了所有 crate 使用相同版本的库。



示例:共享核心库



我们来创建一个简单的 core 库,它将包含业务逻辑:



// core/src/lib.rsuse serde::{Serialize, Deserialize};

#[derive(Debug, Clone, Serialize, Deserialize)]pub struct User { pub id: u64, pub name: String, pub email: String,}

pub fn create_user(name: String, email: String) -> User { User { id: rand::random(), name, email, }}

pub fn greet(user: &User) -> String { format!("Hello, {}!", user.name)}


现在,cli crate 可以使用这个库:



// cli/src/main.rsuse core::{create_user, greet};

fn main() { let user = create

博客

书籍推荐