Comment utiliser TypeScript dans une configuration Monorepo

Une configuration monorepo vous permet de gérer plusieurs packages ou projets dans un seul référentiel. Avec TypeScript, cette configuration est particulièrement efficace pour partager des types, des interfaces et même des utilitaires entre différents packages. Ce guide vous explique comment configurer TypeScript dans un environnement monorepo.

1. Mise en place du Monorepo

Pour configurer un monorepo, vous pouvez utiliser des outils tels que les espaces de travail npm ou yarn. Ces outils vous permettent de gérer plusieurs packages dans le même référentiel et facilitent le partage de code entre les projets.

1.1 Initialisation d'un Monorepo

Tout d'abord, créez un nouveau dossier pour votre monorepo et initialisez-le avec npm ou yarn.

mkdir my-monorepo
cd my-monorepo
npm init -y

Ensuite, configurez les espaces de travail dans votre package.json:

{
  "name": "my-monorepo",
  "version": "1.0.0",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

Cette configuration indique à npm ou à yarn que tous les packages vivront dans le dossier packages.

2. Ajout de packages au Monorepo

Créez deux packages dans votre monorepo. Pour cet exemple, nous allons créer un package shared pour le code réutilisable et un package web-app pour une application frontend.

mkdir -p packages/shared
mkdir -p packages/web-app

À l'intérieur de chaque package, initialisez un package.json:

cd packages/shared
npm init -y

cd ../web-app
npm init -y

3. Ajout de TypeScript au Monorepo

Ensuite, nous allons configurer TypeScript. Installez TypeScript et les dépendances nécessaires à la racine de votre monorepo:

npm install typescript --save-dev

Créez un tsconfig.json au niveau racine pour définir la configuration TypeScript pour l'ensemble du monorepo:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "*": ["packages/*/src"]
    },
    "composite": true,
    "declaration": true,
    "outDir": "dist",
    "rootDir": ".",
    "skipLibCheck": true,
    "module": "ESNext",
    "target": "ES6",
    "moduleResolution": "node"
  },
  "include": ["packages/*"]
}

La clé ici est l'option paths, qui permet à TypeScript de comprendre les importations de différents packages dans le monorepo.

4. Configuration de TypeScript dans chaque package

Chaque paquet a besoin de son propre tsconfig.json pour fonctionner correctement dans le monorepo. Voici un exemple de configuration pour le paquet shared:

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

Et pour le package web-app:

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

Désormais, TypeScript peut être utilisé dans chaque package et les configurations sont partagées à partir de la racine tsconfig.json.

5. Ajout de code TypeScript aux packages

Ajoutons quelques exemples de code TypeScript aux deux packages. Dans le package shared, créez un dossier src et ajoutez un fichier TypeScript:

mkdir -p packages/shared/src
touch packages/shared/src/index.ts

Dans index.ts, exportez une fonction simple:

export const greet = (name: string): string => {
  return `Hello, ${name}!`;
}

Dans le package web-app, créez un dossier src et un fichier index.ts:

mkdir -p packages/web-app/src
touch packages/web-app/src/index.ts

Maintenant, importez la fonction partagée:

import { greet } from 'shared';

console.log(greet('TypeScript Monorepo'));

6. Construction du Monorepo

Pour compiler tout le code TypeScript du monorepo, nous devons utiliser le compilateur TypeScript. À la racine du monorepo, exécutez:

npx tsc --build

Cette commande compilera tous les packages en suivant leurs fichiers tsconfig.json respectifs.

Conclusion

Dans ce guide, nous avons expliqué comment configurer et utiliser TypeScript dans un monorepo. En organisant votre code dans une structure monorepo, vous pouvez facilement partager du code entre plusieurs packages, ce qui rend votre processus de développement plus efficace. Grâce au typage puissant et aux références de projet de TypeScript, cette configuration est parfaite pour les applications à grande échelle ou les bibliothèques partagées.