Monorepo avec Kotlin : organisation du code et bonnes pratiques

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 Kotlin : organisation du code et bonnes pratiques



Avec la croissance des projets et l'augmentation du nombre de services, les développeurs se posent la question : comment organiser le code pour qu'il reste gérable, facilement testable et rapidement déployable ? Une approche populaire est le monorepo. Dans cet article, nous allons voir comment organiser efficacement un monorepo en Kotlin avec Gradle, quels outils et patterns utiliser, et comment éviter les erreurs typiques.



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



Un monorepo est une approche où le code de plusieurs projets (modules, bibliothèques, services) est stocké dans un seul dépôt. Dans le contexte de Kotlin, cela signifie que vous pouvez avoir un projet Gradle commun contenant des modules pour les services backend, les applications Android, les bibliothèques partagées et même la documentation.



Avantages du monorepo :

  • Versionnage unifié — tous les modules utilisent la même version de Kotlin et des dépendances communes.
  • Refactoring simplifié — les modifications dans une bibliothèque commune sont immédiatement visibles par tous les consommateurs.
  • Configuration CI/CD partagée — un seul pipeline pour tous les modules.
  • Collaboration améliorée — les développeurs voient tout le code du projet.


Cependant, le monorepo exige de la discipline : sans une bonne organisation, il peut se transformer en « monolithe » avec des dépendances complexes. Kotlin et Gradle fournissent d'excellents outils pour y remédier.



Structure d'un monorepo en Kotlin



Considérons une structure typique de projet avec un service backend en Ktor, une bibliothèque commune pour les modèles de données et une application Android :



my-monorepo/├── build.gradle.kts          # fichier de build racine├── settings.gradle.kts       # inclusion des modules├── gradle.properties         # versions communes├── common/│   ├── build.gradle.kts│   └── src/│       └── main/kotlin/│           └── com/example/common/│               └── Models.kt├── backend/│   ├── build.gradle.kts│   └── src/│       └── main/kotlin/│           └── com/example/backend/│               └── Application.kt├── android-app/│   ├── build.gradle.kts│   └── src/│       └── main/kotlin/│           └── com/example/android/│               └── MainActivity.kt└── ci/    └── build.sh


Le fichier settings.gradle.kts inclut les modules :



rootProject.name = "my-monorepo"

include(":common")include(":backend")include(":android-app")


Le build.gradle.kts racine contient généralement uniquement les plugins et paramètres communs :



plugins {    kotlin("jvm") version "1.9.22" apply false    kotlin("android") version "1.9.22" apply false    id("org.jetbrains.kotlin.plugin.serialization") version "1.9.22" apply false}

allprojects { group = "com.example" version = "1.0.0"}


Important : les plugins sont spécifiés avec apply false pour qu'ils ne s'appliquent pas au projet racine, mais soient disponibles pour les modules enfants.



Gestion des dépendances dans un monorepo



L'un des principaux défis est d'éviter la duplication des versions de dépendances. Pour cela, on utilise le Gradle Version Catalog (fichier libs.versions.toml dans le dossier gradle). Exemple :



# gradle/libs.versions.toml[versions]kotlin = "1.9.22"ktor = "2.3.7"coroutines = "1.7.3"

[libraries]ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" }kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }

[plugins]kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.

Blogs

Book Recommendations