Passer au contenu

Plugin CLI

TypeScript dispose d’un système de réflexion de métadonnées qui a plusieurs limitations, rendant impossible, par exemple, la détermination des propriétés d’une classe ou la reconnaissance d’une propriété donnée comme optionnelle ou requise. Cependant, certaines de ces contraintes peuvent être abordées lors de la compilation. Nest fournit un plugin qui améliore le processus de compilation TypeScript afin de réduire la quantité de code boilerplate requis.

Aperçu

Le plugin GraphQL fera automatiquement :

  • annoter toutes les classes de type objet, types d’objet et propriétés d’args avec @Field sauf si @HideField est utilisé
  • définir la propriété nullable en fonction du point d’interrogation (par exemple, name?: string définira nullable: true)
  • définir la propriété type en fonction du type (les tableaux sont également supportés)
  • générer des descriptions pour les propriétés basées sur les commentaires (si introspectComments est défini sur true)

Veuillez noter que vos noms de fichiers doivent avoir l’un des suffixes suivants pour être analysés par le plugin : ['.input.ts', '.args.ts', '.entity.ts', '.model.ts'] (par exemple, author.entity.ts). Si vous utilisez un suffixe différent, vous pouvez ajuster le comportement du plugin en spécifiant l’option typeFileNameSuffix.

Avec ce que nous avons appris jusqu’à présent, vous devez dupliquer beaucoup de code pour faire savoir au paquet comment votre type devrait être déclaré dans GraphQL. Par exemple, vous pourriez définir une classe Author simple comme suit :

authors/models/author.model.ts
Définition de la classe Author
@ObjectType()
export class Author {
@Field(type => ID)
id: number;
@Field({ nullable: true })
firstName?: string;
@Field({ nullable: true })
lastName?: string;
@Field(type => [Post])
posts: Post[];
}

Bien que cela ne soit pas un problème significatif pour des projets de taille moyenne, cela devient verbeux et difficile à maintenir une fois que vous avez un grand ensemble de classes.

En activant le plugin GraphQL, la définition de classe ci-dessus peut être déclarée simplement :

authors/models/author.model.ts
Définition simplifiée de la classe Author
@ObjectType()
export class Author {
@Field(type => ID)
id: number;
firstName?: string;
lastName?: string;
posts: Post[];
}

Le plugin ajoute les décorateurs appropriés à la volée, basés sur l’Arbre de Syntaxe Abstrait. Ainsi, vous n’aurez pas à lutter avec les décorateurs @Field disséminés dans le code.

Introspection des commentaires

Avec la fonction d’introspection des commentaires activée, le plugin CLI générera des descriptions pour les champs basées sur les commentaires.

Par exemple, pour une propriété d’exemple roles :

/**
* Une liste des rôles de l'utilisateur
*/
@Field(() => [String], {
description: `Une liste des rôles de l'utilisateur`
})
roles: string[];

Vous devez dupliquer les valeurs de description. Avec introspectComments activé, le plugin CLI peut extraire ces commentaires et fournir automatiquement des descriptions pour les propriétés. Désormais, le champ ci-dessus peut être déclaré simplement comme suit :

/**
* Une liste des rôles de l'utilisateur
*/
roles: string[];

Utilisation du plugin CLI

Pour activer le plugin, ouvrez nest-cli.json (si vous utilisez Nest CLI) et ajoutez la configuration suivante sous plugins :

{
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"plugins": [
"@nestjs/graphql"
]
}
}

Vous pouvez utiliser la propriété options pour personnaliser le comportement du plugin.

"plugins": [
{
"name": "@nestjs/graphql",
"options": {
"typeFileNameSuffix": [".input.ts", ".args.ts"],
"introspectComments": true
}
}
]

La propriété options doit respecter l’interface suivante :

export interface PluginOptions {
typeFileNameSuffix?: string[];
introspectComments?: boolean;
}
OptionPar défautDescription
typeFileNameSuffix['.input.ts', '.args.ts', '.entity.ts', '.model.ts']Suffixes pour les fichiers de types GraphQL
introspectCommentsfalseSi défini sur true, le plugin générera des descriptions pour les propriétés basées sur les commentaires

Si vous n’utilisez pas le CLI mais que vous avez une configuration webpack personnalisée, vous pouvez utiliser ce plugin en combinaison avec ts-loader :

getCustomTransformers: (program: any) => ({
before: [
require('@nestjs/graphql/plugin').before({}, program)
]
}),

Constructeur SWC

Pour les configurations standard (non-monorepo), pour utiliser les plugins CLI avec le constructeur SWC, vous devez activer la vérification de type, comme décrit ici.

Fenêtre de terminal
$ nest start -b swc --type-check

Pour les configurations monorepo, suivez les instructions ici.

Fenêtre de terminal
$ npx ts-node src/generate-metadata.ts
# OU npx ts-node apps/{YOUR_APP}/src/generate-metadata.ts

Maintenant, le fichier de métadonnées sérialisé doit être chargé par la méthode GraphQLModule, comme montré ci-dessous :

import metadata from './metadata'; // <--- fichier auto-généré par le "PluginMetadataGenerator"
GraphQLModule.forRoot({
... // autres options
metadata,
}),

Intégration avec ts-jest (tests e2e)

Lors de l’exécution des tests e2e avec ce plugin activé, vous pourriez rencontrer des problèmes avec la compilation du schéma. Par exemple, l’une des erreurs les plus courantes est :

Object type <name> must define one or more fields.

Cela se produit parce que la configuration de jest n’importe pas le plugin @nestjs/graphql/plugin nulle part.

Pour corriger cela, créez le fichier suivant dans votre répertoire de tests e2e :

const transformer = require('@nestjs/graphql/plugin');
module.exports.name = 'nestjs-graphql-transformer';
// vous devez changer le numéro de version à chaque fois que vous changez la configuration ci-dessous - sinon, jest ne détectera pas les changements
module.exports.version = 1;
module.exports.factory = (cs) => {
return transformer.before(
{
// options pour @nestjs/graphql/plugin (peuvent être vides)
},
cs.program, // "cs.tsCompiler.program" pour les anciennes versions de Jest (<= v27)
);
};

Avec cela en place, importez le transformateur AST dans votre fichier de configuration jest. Par défaut (dans l’application de démarrage), le fichier de configuration des tests e2e se trouve sous le dossier test et est nommé jest-e2e.json.

{
... // autre configuration
"globals": {
"ts-jest": {
"astTransformers": {
"before": ["<path to the file created above>"]
}
}
}
}

Si vous utilisez jest@^29, utilisez alors le snippet ci-dessous, car l’approche précédente a été dépréciée.

{
... // autre configuration
"transform": {
"^.+\\.(t|j)s$": [
"ts-jest",
{
"astTransformers": {
"before": ["<path to the file created above>"]
}
}
]
}
}