$ sudo teach IT
Модуль 6 · Воркспейсы

Что такое воркспейс

Воркспейс — способ объединить несколько крейтов в одном репозитории и управлять ими единым Cargo.

📖 Теория 🕐 ~20 минут
🤔

Зачем нужен воркспейс

Представьте проект с CLI-приложением, серверной библиотекой и общими утилитами. Без воркспейса это три отдельных репозитория — неудобно. Воркспейс решает это:

❌ Без воркспейса
  • 3 отдельных git-репозитория
  • Разные версии зависимостей
  • Нельзя собрать всё сразу
  • Дублирование target/
✅ С воркспейсом
  • Один репозиторий
  • Единый Cargo.lock для всего
  • cargo build строит всё
  • Один общий target/
📂

Структура воркспейса

Файловая структура
my_project/                 ← корень воркспейса
├── Cargo.toml              ← главный манифест воркспейса
├── Cargo.lock              ← единый для всех крейтов
├── target/                 ← единая папка сборки
├── cli/                    ← крейт 1: бинарник
│   ├── Cargo.toml
│   └── src/main.rs
├── server/                 ← крейт 2: библиотека
│   ├── Cargo.toml
│   └── src/lib.rs
└── common/                 ← крейт 3: общие утилиты
    ├── Cargo.toml
    └── src/lib.rs
my_project/Cargo.toml — корневой манифест
[workspace]
members = [
    "cli",
    "server",
    "common",
]

# Общие зависимости — одна версия для всего воркспейса
[workspace.dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }

Корневой Cargo.toml — это только манифест воркспейса. В нём нет [package], только [workspace].

🔗

workspace.dependencies — единые версии

Объявите зависимость один раз в корне, а в каждом крейте просто ссылайтесь на неё через workspace = true:

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

[dependencies]
serde = { workspace = true }     # версия берётся из [workspace.dependencies]
common = { path = "../common" }  # другой крейт воркспейса
💡 Это гарантирует что все крейты воркспейса используют ровно одну версию serde — конфликтов нет, и обновить нужно только в одном месте.
📌 Что важно запомнить
→ Воркспейс — несколько крейтов в одном репозитории с единым Cargo.lock и target/
→ Корневой Cargo.toml содержит [workspace] со списком members
→ [workspace.dependencies] — объявить версию один раз, использовать везде через workspace = true
→ Крейты воркспейса ссылаются друг на друга через path = "../имя"