Monorepo avec Swift : 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 Swift : organisation du code en pratique



Dans le développement iOS et macOS moderne, le choix de la stratégie de gestion du code est l'un des facteurs clés influençant l'évolutivité, la rapidité de livraison et la qualité du produit. Traditionnellement, les développeurs utilisaient des multi-repos (polyrepo), où chaque module ou service vit dans un dépôt Git distinct. Cependant, avec la croissance des projets et des équipes, la question se pose de plus en plus : comment organiser le code pour qu'il reste cohérent, réutilisable et facile à maintenir ? La réponse — monorepo avec Swift. Dans cet article, nous allons voir ce qu'est un monorepo, pourquoi il convient aux projets Swift, et comment l'organiser en pratique avec Swift Package Manager (SPM).



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



Un monorepo 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 au polyrepo, où chaque composant est isolé, le monorepo regroupe les bibliothèques, applications, tests, configurations et documentation sous un seul contrôle de version.



Pour les développeurs Swift, le monorepo est particulièrement pertinent pour plusieurs raisons :

  • Version unique des dépendances : Vous évitez la désynchronisation des versions des bibliothèques entre différentes applications.
  • Simplification du refactoring : Les modifications dans un module commun sont immédiatement visibles pour tous les consommateurs au sein du dépôt.
  • Intégration rapide : Les nouvelles fonctionnalités peuvent être testées et livrées en une seule pull request.
  • Compatibilité avec SPM : Swift Package Manager est idéal pour les monorepos, car il prend en charge les paquets locaux et les chemins relatifs.


Structure d'un monorepo pour un projet Swift



Prenons un exemple pratique. Supposons que nous ayons une application pour iOS (en SwiftUI) et macOS (en AppKit), qui utilisent des modules communs : une couche réseau, une logique d'authentification et des composants UI. Organisons le monorepo comme suit :



MyMonorepo/├── Package.swift├── Sources/│   ├── AppiOS/│   │   └── main.swift│   ├── AppMacOS/│   │   └── main.swift│   ├── CoreNetworking/│   │   ├── Sources/│   │   │   └── HTTPClient.swift│   │   └── Tests/│   ├── CoreAuth/│   │   ├── Sources/│   │   │   └── AuthService.swift│   │   └── Tests/│   └── UIComponents/│       ├── Sources/│       │   └── CustomButton.swift│       └── Tests/├── Tests/│   ├── AppiOSTests/│   └── AppMacOSTests/├── .gitignore└── README.md


Le fichier clé est Package.swift. Il décrit tous les modules et leurs dépendances. Exemple d'un tel fichier :



// swift-tools-version:5.9import PackageDescription

let package = Package( name: "MyMonorepo", platforms: [ .iOS(.v17), .macOS(.v14) ], products: [ .executable(name: "AppiOS", targets: ["AppiOS"]), .executable(name: "AppMacOS", targets: ["AppMacOS"]), .library(name: "CoreNetworking", targets: ["CoreNetworking"]), .library(name: "CoreAuth", targets: ["CoreAuth"]), .library(name: "UIComponents", targets: ["UIComponents"]) ], dependencies: [ // Dépendances externes, si nécessaires // .package(url: "https://github.com/...", from: "1.0.0") ], targets: [ .executableTarget( name: "AppiOS", dependencies: ["CoreNetworking", "CoreAuth", "UIComponents"], path: "Sources/AppiOS" ), .executableTarget( name: "AppMacOS", dependencies: ["CoreNetworking", "CoreAuth", "UIComponents"], path: "Sources/AppMacOS" ), .target( name: "CoreNetworking", dependencies: [], path: "Sources/CoreNetworking/Sources" ), .target( name: "CoreAuth",

Blogs

Book Recommendations