Passer au contenu

Utilisation des bibliothèques Nest

Bibliothèques

De nombreuses applications doivent résoudre les mêmes problèmes généraux ou réutiliser un composant modulaire dans plusieurs contextes différents. Nest a plusieurs façons de répondre à cela, mais chacune fonctionne à un niveau différent pour résoudre le problème de manière à répondre à différents objectifs architecturaux et organisationnels.

Les modules Nest sont utiles pour fournir un contexte d’exécution qui permet le partage de composants au sein d’une seule application. Les modules peuvent également être emballés avec npm pour créer une bibliothèque réutilisable qui peut être installée dans différents projets. Cela peut être un moyen efficace de distribuer des bibliothèques configurables et réutilisables qui peuvent être utilisées par différentes organisations peu connectées ou non affiliées (par exemple, en distribuant/installant des bibliothèques tierces).

Pour partager du code au sein de groupes étroitement organisés (par exemple, au sein des limites d’une entreprise/projet), il peut être utile d’avoir une approche plus légère pour partager les composants. Les monorepos ont émergé comme un concept pour permettre cela, et au sein d’un monorepo, une bibliothèque fournit un moyen de partager du code de manière simple et légère. Dans un monorepo Nest, l’utilisation des bibliothèques permet un assemblage facile des applications qui partagent des composants. En fait, cela encourage la décomposition des applications monolithiques et des processus de développement pour se concentrer sur la construction et la composition de composants modulaires.

Bibliothèques Nest

Une bibliothèque Nest est un projet Nest qui diffère d’une application en ce sens qu’il ne peut pas s’exécuter seul. Une bibliothèque doit être importée dans une application contenant pour que son code s’exécute. Le support intégré pour les bibliothèques décrit dans cette section n’est disponible que pour les monorepos (les projets en mode standard peuvent réaliser une fonctionnalité similaire en utilisant des packages npm).

Par exemple, une organisation peut développer un AuthModule qui gère l’authentification en appliquant les politiques de l’entreprise régissant toutes les applications internes. Plutôt que de construire ce module séparément pour chaque application ou d’emballer physiquement le code avec npm et d’exiger que chaque projet l’installe, un monorepo peut définir ce module comme une bibliothèque. Organisé de cette manière, tous les consommateurs du module de bibliothèque peuvent voir une version à jour de AuthModule telle qu’elle est engagée. Cela peut apporter des avantages significatifs pour coordonner le développement et l’assemblage des composants, ainsi que pour simplifier les tests de bout en bout.

Création de bibliothèques

Toute fonctionnalité qui est appropriée pour une réutilisation est un candidat pour être gérée comme une bibliothèque. Décider ce qui doit être une bibliothèque et ce qui doit faire partie d’une application est une décision de conception architecturale. La création de bibliothèques implique plus que simplement copier du code d’une application existante vers une nouvelle bibliothèque. Lorsqu’elle est emballée en tant que bibliothèque, le code de la bibliothèque doit être découplé de l’application. Cela peut nécessiter plus de temps au départ et forcer certaines décisions de conception que vous pourriez ne pas rencontrer avec un code plus étroitement couplé. Mais cet effort supplémentaire peut être payant lorsque la bibliothèque peut être utilisée pour permettre un assemblage d’application plus rapide à travers plusieurs applications.

Pour commencer à créer une bibliothèque, exécutez la commande suivante :

Fenêtre de terminal
$ nest g library my-library

Lorsque vous exécutez la commande, le schéma library vous demande un préfixe (alias) pour la bibliothèque :

Fenêtre de terminal
What prefix would you like to use for the library (default: @app)?

Cela crée un nouveau projet dans votre espace de travail appelé my-library. Un projet de type bibliothèque, tout comme un projet de type application, est généré dans un dossier nommé en utilisant un schéma. Les bibliothèques sont gérées sous le dossier libs à la racine du monorepo. Nest crée le dossier libs la première fois qu’une bibliothèque est créée.

Les fichiers générés pour une bibliothèque sont légèrement différents de ceux générés pour une application. Voici le contenu du dossier libs après avoir exécuté la commande ci-dessus :

  • Répertoirelibs
    • Répertoiremy-library
      • Répertoiresrc
        • index.ts
        • my-library.module.ts
        • my-library.service.ts
      • tsconfig.lib.json

Le fichier nest-cli.json aura une nouvelle entrée pour la bibliothèque sous la clé "projects" :

...
{
"my-library": {
"type": "library",
"root": "libs/my-library",
"entryFile": "index",
"sourceRoot": "libs/my-library/src",
"compilerOptions": {
"tsConfigPath": "libs/my-library/tsconfig.lib.json"
}
}
...

Il y a deux différences dans les métadonnées nest-cli.json entre les bibliothèques et les applications :

  • la propriété "type" est réglée sur "library" au lieu de "application"
  • la propriété "entryFile" est réglée sur "index" au lieu de "main"

Ces différences clés permettent au processus de construction de traiter les bibliothèques de manière appropriée. Par exemple, une bibliothèque exporte ses fonctions via le fichier index.js.

Comme avec les projets de type application, chaque bibliothèque a son propre fichier tsconfig.lib.json qui étend le fichier tsconfig.json racine (à l’échelle du monorepo). Vous pouvez modifier ce fichier, si nécessaire, pour fournir des options de compilation spécifiques à la bibliothèque.

Vous pouvez construire la bibliothèque avec la commande CLI :

Fenêtre de terminal
$ nest build my-library

Utilisation des bibliothèques

Avec les fichiers de configuration générés automatiquement en place, utiliser des bibliothèques est simple. Comment importerions-nous MyLibraryService de la bibliothèque my-library dans l’application my-project ?

Tout d’abord, notez que l’utilisation des modules de bibliothèque est la même que l’utilisation de tout autre module Nest. Ce que fait le monorepo, c’est gérer les chemins de manière transparente lors de l’importation de bibliothèques et de la génération de builds. Pour utiliser MyLibraryService, nous devons importer son module déclaratif. Nous pouvons modifier my-project/src/app.module.ts comme suit pour importer MyLibraryModule.

Importation de MyLibraryModule dans l'application
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MyLibraryModule } from '@app/my-library';
@Module({
imports: [MyLibraryModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

Remarquez ci-dessus que nous avons utilisé un alias de chemin de @app dans la ligne import du module ES, qui était le préfixe que nous avons fourni avec la commande nest g library ci-dessus. En coulisses, Nest gère cela via le mappage de chemin tsconfig. Lors de l’ajout d’une bibliothèque, Nest met à jour la clé "paths" du fichier tsconfig.json global (monorepo) comme suit :

"paths": {
"@app/my-library": [
"libs/my-library/src"
],
"@app/my-library/*": [
"libs/my-library/src/*"
]
}

Ainsi, en résumé, la combinaison des fonctionnalités du monorepo et de bibliothèque a simplifié et rendu intuitif l’inclusion des modules de bibliothèque dans les applications.

Ce même mécanisme permet de construire et de déployer des applications qui composent des bibliothèques. Une fois que vous avez importé MyLibraryModule, l’exécution de nest build gère automatiquement toute la résolution des modules et regroupe l’application avec toutes les dépendances de bibliothèque pour le déploiement. Le compilateur par défaut pour un monorepo est webpack, donc le fichier de distribution résultant est un fichier unique qui regroupe tous les fichiers JavaScript transpilés en un seul fichier. Vous pouvez également passer à tsc comme décrit ici.