Monorepo avec TypeScript : organisation du code en pratique
\n\nDans le développement web moderne, en particulier lorsqu'on travaille avec TypeScript, les développeurs sont souvent confrontés à un dilemme : stocker tout le code dans un seul dépôt (monorepo) ou le diviser en plusieurs petits dépôts (polyrepo). Pour les projets de taille moyenne et grande, où la réutilisabilité du code et une configuration unifiée sont importantes, le monorepo devient un standard de facto. Dans cet article, nous allons voir comment organiser correctement un monorepo en TypeScript, de la structure de base aux techniques avancées.
\n\nQu'est-ce qu'un monorepo et pourquoi en a-t-on besoin ?
\n\nUn monorepo est une approche où le code de plusieurs projets (packages, bibliothèques, applications) est stocké dans un seul dépôt. Dans le contexte de TypeScript, c'est particulièrement pratique car cela permet :
\n\n- \n
- Réutiliser les types et les interfaces entre différentes parties du système sans publication sur npm. \n
- Simplifier le refactoring : une modification dans un package est automatiquement validée dans tous les packages dépendants. \n
- Avoir une configuration unifiée pour le linter, le formateur et le builder. \n
- Simplifier le CI/CD : un dépôt, un pipeline. \n
Parmi les outils populaires pour travailler avec les monorepos en TypeScript, on distingue Nx, Turborepo et npm/yarn/pnpm workspaces. Nous allons aborder l'approche utilisant pnpm workspaces et TypeScript Project References, car c'est un ensemble minimal et flexible.
\n\nStructure du monorepo : configuration de base
\n\nCréons une structure typique de monorepo pour un projet TypeScript. Supposons que nous ayons trois packages : core (types et utilitaires communs), server (backend) et web (frontend).
1. Configuration racine
\n\nCommençons par la racine du projet. Créons un fichier package.json avec workspace :
{\n "name": "my-monorepo",\n "private": true,\n "workspaces": [\n "packages/*"\n ],\n "scripts": {\n "build": "tsc -b",\n "clean": "tsc -b --clean",\n "lint": "eslint packages/*/src"\n }\n}\n\n\nEnsuite, configurons le tsconfig.json racine. Utilisons Project References — c'est une fonctionnalité clé de TypeScript pour les monorepos :
{\n "compilerOptions": {\n "target": "ES2020",\n "module": "commonjs",\n "strict": true,\n "composite": true,\n "declaration": true,\n "declarationMap": true,\n "sourceMap": true,\n "outDir": "./dist",\n "rootDir": ".",\n "skipLibCheck": true\n },\n "references": [\n { "path": "./packages/core" },\n { "path": "./packages/server" },\n { "path": "./packages/web" }\n ]\n}\n\n\nImportant : l'option composite: true est obligatoire pour les packages référencés par d'autres packages. Elle active la compilation incrémentale et la génération de fichiers .d.ts.
2. Configuration du package core
\n\nAllons dans packages/core. Créons un package.json :
{\n "name": "@my/core",\n "version": "1.0.0",\n "main": "dist/index.js",\n "types": "dist/index.d.ts",\n "scripts": {\n "build": "tsc -b"\n }\n}\n\n\nEt le tsconfig.json pour ce package :
{\n "extends": "../../tsconfig.json",\n "compilerOptions": {\n "outDir": "./dist",\n "rootDir": "./src"\n },\n "include": ["src"]\n}\n\n\nCréons un module simple src/index.ts :
export interface User {\n id: string;\n name: string;\n email: string;\n}\n\nexport function greet(user: User): string {\n return `Hello, ${user.name}!`;\n}\n\n\nMaintenant, le package
Blogs
Book Recommendations
Lire aussi
Déploiement de Rust sur Kubernetes : guide pratique de base
PHP en 2025 : par où commencer pour un débutant — guide pas à pas
Comment devenir développeur C# : conseils et CV
Comment obtenir la date actuelle en JavaScript : analyse complète pour les débutants
Salaires des développeurs JavaScript en Russie : aperçu du marché 2024