Monorepositorio con Rust: organización del código en la práctica

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Monorepositorio con Rust: organización del código en la práctica

Un monorepositorio (monorepo) es un enfoque de gestión de código donde múltiples proyectos o componentes se almacenan en un único repositorio. En el ecosistema de Rust, esta práctica es especialmente popular gracias al soporte integrado de Cargo Workspace. En este artículo, analizaremos cómo organizar un monorepositorio con Rust en la práctica: desde la creación de la estructura hasta la gestión de dependencias y las pruebas. Aprenderá cómo evitar errores típicos y hacer que su base de código sea escalable.



¿Qué es Cargo Workspace y por qué es necesario?

Cargo Workspace es un mecanismo que permite gestionar múltiples crates (bibliotecas o archivos ejecutables) dentro de un solo proyecto. En lugar de crear repositorios separados para cada componente, los unifica en una única estructura. Esto ofrece varias ventajas:

  • Sistema de compilación unificado — un solo comando cargo build compila todos los crates.
  • Dependencias compartidas — las dependencias duplicadas se resuelven una vez, lo que reduce el tamaño del binario final.
  • Pruebas simplificadas — se pueden ejecutar pruebas para todos los crates con un solo comando.
  • Consistencia de versiones — todos los componentes utilizan las mismas versiones de las bibliotecas.

Un monorepositorio es especialmente útil para microservicios, bibliotecas de propósito general o proyectos con una clara separación en capas (por ejemplo, núcleo, API, CLI).



Creación de la estructura del monorepositorio

Comencemos con un ejemplo práctico. Supongamos que estamos desarrollando un sistema de gestión de tareas. Tendremos tres crates:

  • core — biblioteca con la lógica de negocio.
  • cli — archivo ejecutable para la línea de comandos.
  • server — servidor web (archivo ejecutable).

Primero, crearemos el directorio raíz y el archivo Cargo.toml para el workspace:

mkdir task_managercd task_manager# Creamos el Cargo.toml raíztouch Cargo.toml

En el Cargo.toml raíz, especificamos el workspace:

[workspace]members = [    "core",    "cli",    "server",]

Ahora, creamos cada crate con cargo new:

cargo new core --libcargo new clicargo new server

Después de esto, la estructura se verá así:

task_manager/├── Cargo.toml          # Workspace raíz├── core/│   ├── Cargo.toml│   └── src/│       └── lib.rs├── cli/│   ├── Cargo.toml│   └── src/│       └── main.rs└── server/    ├── Cargo.toml    └── src/        └── main.rs

Tenga en cuenta: el Cargo.toml raíz no contiene la sección [package], solo [workspace]. Esto es importante para un funcionamiento correcto.



Gestión de dependencias entre crates

Una de las tareas clave en un monorepositorio es configurar correctamente las dependencias entre crates. En nuestro ejemplo, cli y server dependen de core. Especifiquemos esto en sus Cargo.toml:

Para cli/Cargo.toml:

[package]name = "cli"version = "0.1.0"edition = "2021"

[dependencies]core = { path = "../core" }clap = { version = "4.0", features = ["derive"] } # Dependencia externa para CLI

Para server/Cargo.toml:

[package]name = "server"version = "0.1.0"edition = "2021"

[dependencies]core = { path = "../core" }actix-web = "4" # Dependencia externa para el servidor web

En el Cargo.toml raíz también se pueden especificar dependencias comunes si son necesarias para todos los crates, pero normalmente esto se hace de forma individual. Sin embargo, el workspace permite resolver conflictos de versiones: si dos crates usan la misma biblioteca, Cargo automáticamente usará una sola versión.

Blogs

Book Recommendations