Monorepo avec Rust : organisation du code en pratique

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Monorepo avec Rust : organisation du code en pratique

\n\n

Lors du développement de grands projets en Rust, la question se pose tôt ou tard : comment organiser le code pour qu'il reste maintenable, réutilisable et facilement évolutif ? Une approche populaire est le monorepo. Dans cet article, nous allons voir ce qu'est un monorepo dans le contexte de Rust, comment le configurer avec Cargo Workspaces et quelles astuces pratiques permettent d'éviter le chaos dans la base de code.

\n\n

Ce contenu sera utile aussi bien aux débutants qui commencent à travailler sur de grands projets qu'aux développeurs expérimentés cherchant des moyens efficaces d'organiser le code.

\n\n

Qu'est-ce qu'un monorepo et pourquoi en a-t-on besoin en Rust ?

\n\n

Un monorepo (monorepository) est une approche où tout le code d'un projet (ou de plusieurs projets liés) est stocké dans un seul dépôt. Contrairement aux multi-repos, où chaque service ou bibliothèque vit dans un dépôt Git séparé.

\n\n

Pourquoi les développeurs Rust choisissent-ils souvent le monorepo ?

\n
    \n
  • Version unique des dépendances. Vous évitez les conflits lorsque différentes crates nécessitent différentes versions de la même bibliothèque.
  • \n
  • Refactorisation simplifiée. La modification d'une API dans une crate est immédiatement visible dans toutes les crates dépendantes — le compilateur Rust signalera tous les endroits à corriger.
  • \n
  • Compilation partagée. Cargo peut optimiser la construction en réutilisant les artefacts déjà compilés.
  • \n
  • Historique unique des modifications. Vous n'avez pas besoin de synchroniser les commits entre différents dépôts.
  • \n
\n\n

L'outil principal pour organiser un monorepo en Rust est Cargo Workspaces. Voyons comment l'utiliser en pratique.

\n\n

Configuration de Cargo Workspaces : exemple pas à pas

\n\n

Supposons que nous créons une application composée de trois parties :

\n
    \n
  • la bibliothèque core_lib — logique commune ;
  • \n
  • la bibliothèque utils — utilitaires ;
  • \n
  • le fichier exécutable app — le binaire principal.
  • \n
\n\n

Créons la structure du monorepo :

\n\n
my_monorepo/\n├── Cargo.toml          # manifeste racine du workspace\n├── core_lib/\n│   ├── Cargo.toml\n│   └── src/\n│       └── lib.rs\n├── utils/\n│   ├── Cargo.toml\n│   └── src/\n│       └── lib.rs\n└── app/\n    ├── Cargo.toml\n    └── src/\n        └── main.rs\n
\n\n

Étape 1. Cargo.toml racine

\n\n
[workspace]\nmembers = [\n    "core_lib",\n    "utils",\n    "app",\n]\n
\n\n

Désormais, les trois crates font partie d'un même workspace. Cargo les gérera comme un tout.

\n\n

Étape 2. Dépendances internes

\n

Dans le fichier app/Cargo.toml, indiquons qu'il dépend de nos bibliothèques :

\n\n
[package]\nname = "app"\nversion = "0.1.0"\nedition = "2021"\n\n[dependencies]\ncore_lib = { path = "../core_lib" }\nutils = { path = "../utils" }\n
\n\n

Étape 3. Écriture du code

\n

Exemple de code dans core_lib/src/lib.rs :

\n\n
pub fn greet(name: &str) -> String {\n    format!("Hello, {}!", name)\n}\n
\n\n

Dans app/src/main.rs, utilisons cette fonction :

\n\n
use core_lib::greet;\n\nfn main() {\n    println!("{}", greet("Rust Developer"));\n}\n
\n\n

Étape 4. Compilation et exécution

\n

Les commandes cargo build, cargo test et cargo run fonctionnent pour tout le workspace. On peut aussi exécuter une crate spécifique :

\n\n
cargo run -p app\ncargo test -p core_lib\n
\n\n

Voici la configuration de base. Passons maintenant à des pratiques plus avancées.

\n\n

Organisation avancée : modules, tests et versionnage

\n\n

Lorsque le nombre de crates augmente, il est important de respecter une discipline. Voici quelques conseils

Blogs

Book Recommendations