Monorepo avec JavaScript : organisation du code pour des projets évolutifs
Avec la complexité croissante des projets JavaScript (en particulier sur Node.js), les développeurs se posent la question : comment organiser le code pour qu'il reste maintenable, réutilisable et facilement évolutif ? L'approche traditionnelle — le multirepo (polyrepo) — où chaque service ou bibliothèque vit dans son propre dépôt Git. Cependant, pour de nombreuses équipes, le monorepo — un dépôt unique contenant plusieurs projets (packages) — s'avère plus pratique et plus efficace.
Dans cet article, nous allons voir ce qu'est un monorepo, quels outils existent pour JavaScript/Node.js, et comment organiser correctement la structure du code.
Qu'est-ce qu'un monorepo et pourquoi en a-t-on besoin ?
Un monorepo est une stratégie de gestion de code où tous les composants du système (frontend, backend, bibliothèques communes, configurations) sont stockés dans un seul dépôt. Dans le contexte de JavaScript, cela signifie souvent un ensemble de packages, chacun pouvant être publié séparément ou utilisé comme dépendance interne.
Avantages du monorepo
- Version unique des dépendances : Tous les packages utilisent un seul
node_modules(grâce au hoisting), ce qui réduit les doublons et les conflits de versions. - Refactoring simple : Les modifications dans une bibliothèque commune sont immédiatement visibles pour tous les consommateurs dans une seule PR.
- Atomicité transversale : Un seul commit peut contenir des modifications dans plusieurs packages, ce qui simplifie le rollback et le CI/CD.
- Réutilisation du code : Les utilitaires, types et configurations communs sont facilement partagés entre les projets.
- Outils unifiés : Un seul linter, un seul test-runner, un seul formateur pour tout le dépôt.
Inconvénients (et comment les atténuer)
- Augmentation de la taille du dépôt : Git peut ralentir. Solution : utiliser
git sparse-checkoutou des clones superficiels. - Complexité de configuration du CI : Nécessite une mise en cache intelligente et l'exécution uniquement des packages modifiés (des outils comme Nx ou Turborepo aident).
- Exigences de discipline accrues : Des règles claires pour les commits et le versioning sont obligatoires.
Outils pour organiser un monorepo en JavaScript
Le choix de l'outil dépend de la taille de l'équipe et de la complexité du projet. Examinons les trois options les plus populaires.
1. Yarn / npm Workspaces (niveau de base)
Il s'agit d'une fonctionnalité intégrée des gestionnaires de packages. Elle permet de gérer plusieurs packages dans un seul dépôt en utilisant un seul node_modules.
Exemple de structure :
my-monorepo/├── package.json # package.json racine├── packages/│ ├── utils/ # bibliothèque commune│ │ └── package.json│ ├── server/ # application backend│ │ └── package.json│ └── client/ # frontend (si nécessaire)│ └── package.json└── node_modules/package.json racine :
{ "name": "my-monorepo", "private": true, "workspaces": [ "packages/*" ]}Package packages/server/package.json :
{ "name": "@myorg/server", "version": "1.0.0", "dependencies": { "@myorg/utils": "*" // référence au package local }}Avantages : simplicité, ne nécessite pas de dépendances supplémentaires. Inconvénients : pas de mise en cache intelligente ni d'exécution parallèle des tâches.
2. Lerna (classique pour les monorepos)
Lerna est une norme depuis de nombreuses années. Il fonctionne par-dessus Yarn/npm Workspaces et ajoute des fonctionnalités pour la publication de packages et l'exécution de scripts.
Installation :
npm