Monorepo avec TypeScript : 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

Introduction aux monorepos avec TypeScript



Avec la complexité croissante des applications web modernes, les développeurs sont de plus en plus confrontés au problème de la gestion du code. Lorsqu'un projet est composé de nombreux modules interconnectés — frontend, backend, bibliothèques d'usage général — l'approche traditionnelle avec des dépôts séparés (polyrepo) peut entraîner une duplication de code, une désynchronisation des versions et des difficultés de refactoring.



Un monorepo est une stratégie dans laquelle le code de plusieurs projets est stocké dans un seul dépôt. Combiné avec TypeScript, le monorepo devient un outil puissant : le typage strict garantit la sécurité des modifications au sein de l'ensemble de la stack, et un système de build unifié simplifie la gestion des dépendances.



Dans cet article, nous verrons comment organiser un monorepo avec TypeScript : de la structure de base aux outils avancés comme Nx et Turborepo.



Avantages du monorepo pour les projets TypeScript



Avant de passer à la pratique, voyons pourquoi le monorepo est particulièrement avantageux pour les projets TypeScript :



  • Typage unifié — TypeScript permet de réutiliser les interfaces et les types entre les packages sans duplication.
  • Commits atomiques — les modifications de l'API et de ses consommateurs peuvent être effectuées en un seul commit, ce qui simplifie la revue et le rollback.
  • Refactoring simplifié — l'IDE (par exemple, VS Code) gère correctement les renommages et les déplacements de fichiers dans l'ensemble du dépôt.
  • Mise en cache des builds — des outils comme Nx mettent en cache les résultats de compilation, accélérant ainsi le CI/CD.


Structure de base d'un monorepo



Commençons par une structure simple mais efficace. Créons un projet racine et plusieurs packages :



my-monorepo/├── packages/│   ├── shared/          # Types et utilitaires communs│   │   ├── src/│   │   ├── package.json│   │   └── tsconfig.json│   ├── server/          # Backend (par exemple, Express)│   │   ├── src/│   │   ├── package.json│   │   └── tsconfig.json│   └── web/             # Frontend (React)│       ├── src/│       ├── package.json│       └── tsconfig.json├── package.json         # package.json racine├── tsconfig.base.json   # tsconfig de base pour tous les packages└── .gitignore


Le package.json racine doit contenir la configuration des workspaces. Pour npm et Yarn, cela ressemble à ceci :



{  "name": "my-monorepo",  "private": true,  "workspaces": [    "packages/*"  ],  "scripts": {    "build": "tsc --build",    "clean": "tsc --build --clean"  }}


Le tsconfig.base.json définit les paramètres de compilation communs :



{  "compilerOptions": {    "target": "ES2020",    "module": "commonjs",    "strict": true,    "esModuleInterop": true,    "skipLibCheck": true,    "forceConsistentCasingInFileNames": true,    "declaration": true,    "declarationMap": true,    "sourceMap": true,    "composite": true  }}


Chaque package étend la configuration de base :



{  "extends": "../../tsconfig.base.json",  "compilerOptions": {    "outDir": "./dist",    "rootDir": "./src"  },  "include": ["src"]}


Gestion des dépendances et TypeScript paths



L'un des problèmes clés des monorepos est la configuration correcte des imports entre les packages. Au lieu de publier les packages sur npm, nous utilisons les TypeScript Project References et les paths.



Configuration des Project References



Ajoutons dans le tsconfig.json racine des références aux projets :



{  "files": [],  "references": [    { "path": "./packages/shared" },    { "path": "./packages/server" },    { "path": "./packages/web" }  ]}


Maintenant, lors de l'exécution

Blogs

Book Recommendations