Contribuer à un Générateur
Créons un nouveau générateur pour contribuer à @aws/nx-plugin. Notre objectif sera de générer une nouvelle procédure pour une API tRPC.
Explorer le Plugin
Section intitulée « Explorer le Plugin »D’abord, clonons le plugin :
git clone git@github.com:awslabs/nx-plugin-for-aws.gitEnsuite, installez et compilez :
cd nx-plugin-for-awspnpm ipnpm nx run-many --target build --allCréer un Générateur Vide
Section intitulée « Créer un Générateur Vide »Créons le nouveau générateur dans packages/nx-plugin/src/trpc/procedure.
Nous fournissons un générateur pour créer de nouveaux générateurs afin que vous puissiez rapidement structurer le vôtre ! Vous pouvez exécuter ce générateur comme suit :
- Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
- Ouvrez la console Nx dans VSCode
- Cliquez sur
Generate (UI)dans la section "Common Nx Commands" - Recherchez
@aws/nx-plugin - ts#nx-generator - Remplissez les paramètres requis
- pluginProject: @aws/nx-plugin
- name: ts#trpc-api#procedure
- directory: trpc/procedure
- description: Adds a procedure to a tRPC API
- Cliquez sur
Generate
pnpm nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC APIyarn nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC APInpx nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC APIbunx nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC APIVous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
pnpm nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-runyarn nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-runnpx nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-runbunx nx g @aws/nx-plugin:ts#nx-generator --pluginProject=@aws/nx-plugin --name=ts#trpc-api#procedure --directory=trpc/procedure --description=Adds a procedure to a tRPC API --dry-runVous remarquerez que les fichiers suivants ont été générés pour vous :
Répertoirepackages/nx-plugin/src/trpc/procedure
- schema.json Définit les entrées du générateur
- schema.d.ts Une interface TypeScript correspondant au schéma
- generator.ts Fonction exécutée par Nx comme générateur
- generator.spec.ts Tests pour le générateur
Répertoiredocs/src/content/docs/guides/
- trpc-procedure.mdx Documentation du générateur
- packages/nx-plugin/generators.json Mis à jour pour inclure le générateur
Mettons à jour le schéma pour ajouter les propriétés nécessaires au générateur :
{ "$schema": "https://json-schema.org/schema", "$id": "tRPCProcedure", "title": "Adds a procedure to a tRPC API", "type": "object", "properties": { "project": { "type": "string", "description": "tRPC API project", "x-prompt": "Select the tRPC API project to add the procedure to", "x-dropdown": "projects", "x-priority": "important" }, "procedure": { "description": "The name of the new procedure", "type": "string", "x-prompt": "What would you like to call your new procedure?", "x-priority": "important", }, "type": { "description": "The type of procedure to generate", "type": "string", "x-prompt": "What type of procedure would you like to generate?", "x-priority": "important", "default": "query", "enum": ["query", "mutation"] } }, "required": ["project", "procedure"]}export interface TrpcProcedureSchema { project: string; procedure: string; type: 'query' | 'mutation';}Vous remarquerez que le générateur a déjà été connecté dans packages/nx-plugin/generators.json :
... "generators": { ... "ts#trpc-api#procedure": { "factory": "./src/trpc/procedure/generator", "schema": "./src/trpc/procedure/schema.json", "description": "Adds a procedure to a tRPC API" } },...Implémenter le Générateur
Section intitulée « Implémenter le Générateur »Pour ajouter une procédure à une API tRPC, nous devons faire deux choses :
- Créer un fichier TypeScript pour la nouvelle procédure
- Ajouter la procédure au routeur
Créer la Nouvelle Procédure
Section intitulée « Créer la Nouvelle Procédure »Pour créer le fichier TypeScript de la nouvelle procédure, nous utiliserons un utilitaire appelé generateFiles. Avec celui-ci, nous pouvons définir un modèle EJS que nous rendrons dans notre générateur avec des variables basées sur les options sélectionnées par l’utilisateur.
D’abord, définissons le modèle dans packages/nx-plugin/src/trpc/procedure/files/procedures/__procedureNameKebabCase__.ts.template :
import { publicProcedure } from '../init.js';import { z } from 'zod';
export const <%- procedureNameCamelCase %> = publicProcedure .input(z.object({ // TODO: define input })) .output(z.object({ // TODO: define output })) .<%- procedureType %>(async ({ input, ctx }) => { // TODO: implement! return {}; });Dans le modèle, nous avons référencé trois variables :
procedureNameCamelCaseprocedureNameKebabCaseprocedureType
Nous devons donc nous assurer de les passer à generateFiles, ainsi que le répertoire de génération des fichiers, à savoir l’emplacement des fichiers sources (c’est-à-dire sourceRoot) pour le projet tRPC sélectionné par l’utilisateur, que nous pouvons extraire de la configuration du projet.
Mettons à jour le générateur pour cela :
import { generateFiles, joinPathFragments, readProjectConfiguration, Tree,} from '@nx/devkit';import { TrpcProcedureSchema } from './schema';import { formatFilesInSubtree } from '../../utils/format';import camelCase from 'lodash.camelcase';import kebabCase from 'lodash.kebabcase';
export const trpcProcedureGenerator = async ( tree: Tree, options: TrpcProcedureSchema,) => { const projectConfig = readProjectConfiguration(tree, options.project);
const procedureNameCamelCase = camelCase(options.procedure); const procedureNameKebabCase = kebabCase(options.procedure);
generateFiles( tree, joinPathFragments(__dirname, 'files'), projectConfig.sourceRoot, { procedureNameCamelCase, procedureNameKebabCase, procedureType: options.type, }, );
await formatFilesInSubtree(tree);};
export default trpcProcedureGenerator;Ajouter la Procédure au Routeur
Section intitulée « Ajouter la Procédure au Routeur »Ensuite, nous voulons que le générateur connecte la nouvelle procédure au routeur. Cela implique de lire et modifier le code source de l’utilisateur !
Nous utilisons la manipulation d’AST TypeScript pour mettre à jour les parties pertinentes du fichier source. Il existe des helpers appelés replace et destructuredImport pour faciliter cela.
import { generateFiles, joinPathFragments, readProjectConfiguration, Tree,} from '@nx/devkit';import { TrpcProcedureSchema } from './schema';import { formatFilesInSubtree } from '../../utils/format';import camelCase from 'lodash.camelcase';import kebabCase from 'lodash.kebabcase';import { destructuredImport, replace } from '../../utils/ast';import { factory, ObjectLiteralExpression } from 'typescript';
export const trpcProcedureGenerator = async ( tree: Tree, options: TrpcProcedureSchema,) => { const projectConfig = readProjectConfiguration(tree, options.project);
const procedureNameCamelCase = camelCase(options.procedure); const procedureNameKebabCase = kebabCase(options.procedure);
generateFiles( tree, joinPathFragments(__dirname, 'files'), projectConfig.sourceRoot, { procedureNameCamelCase, procedureNameKebabCase, procedureType: options.type, }, );
const routerPath = joinPathFragments(projectConfig.sourceRoot, 'router.ts');
destructuredImport( tree, routerPath, [procedureNameCamelCase], `./procedures/${procedureNameKebabCase}.js`, );
replace( tree, routerPath, 'CallExpression[expression.name="router"] > ObjectLiteralExpression', (node) => factory.createObjectLiteralExpression([ ...(node as ObjectLiteralExpression).properties, factory.createShorthandPropertyAssignment(procedureNameCamelCase), ]), );
await formatFilesInSubtree(tree);};
export default trpcProcedureGenerator;Maintenant que nous avons implémenté le générateur, compilons-le pour qu’il soit disponible pour le tester dans notre projet d’aventure donjon.
pnpm nx run @aws/nx-plugin:compileTester le Générateur
Section intitulée « Tester le Générateur »Pour tester le générateur, nous allons lier notre Nx Plugin for AWS local à un codebase existant.
Créer un Projet de Test avec une API tRPC
Section intitulée « Créer un Projet de Test avec une API tRPC »Dans un répertoire séparé, créez un nouvel espace de travail de test :
npx create-nx-workspace@22.5.1 trpc-generator-test --pm=pnpm --preset=@aws/nx-plugin --ci=skip --aiAgentsnpx create-nx-workspace@22.5.1 trpc-generator-test --pm=yarn --preset=@aws/nx-plugin --ci=skip --aiAgentsnpx create-nx-workspace@22.5.1 trpc-generator-test --pm=npm --preset=@aws/nx-plugin --ci=skip --aiAgentsnpx create-nx-workspace@22.5.1 trpc-generator-test --pm=bun --preset=@aws/nx-plugin --ci=skip --aiAgentsEnsuite, générons une API tRPC à laquelle ajouter la procédure :
- Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
- Ouvrez la console Nx dans VSCode
- Cliquez sur
Generate (UI)dans la section "Common Nx Commands" - Recherchez
@aws/nx-plugin - ts#trpc-api - Remplissez les paramètres requis
- apiName: test-api
- Cliquez sur
Generate
pnpm nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactiveyarn nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactivenpx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactivebunx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactiveVous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
pnpm nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-runyarn nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-runnpx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-runbunx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-runLier notre Nx Plugin for AWS Local
Section intitulée « Lier notre Nx Plugin for AWS Local »Dans votre codebase, lions notre @aws/nx-plugin local :
cd path/to/trpc-generator-testpnpm link path/to/nx-plugin-for-aws/dist/packages/nx-plugincd path/to/trpc-generator-testyarn link path/to/nx-plugin-for-aws/dist/packages/nx-plugincd path/to/trpc-generator-testnpm link path/to/nx-plugin-for-aws/dist/packages/nx-plugincd path/to/nx-plugin-for-aws/dist/packages/nx-pluginbun linkcd path/to/trpc-generator-testbun link @aws/nx-pluginExécuter le Nouveau Générateur
Section intitulée « Exécuter le Nouveau Générateur »Essayons le nouveau générateur :
- Installez le Nx Console VSCode Plugin si ce n'est pas déjà fait
- Ouvrez la console Nx dans VSCode
- Cliquez sur
Generate (UI)dans la section "Common Nx Commands" - Recherchez
@aws/nx-plugin - ts#trpc-api#procedure - Remplissez les paramètres requis
- Cliquez sur
Generate
pnpm nx g @aws/nx-plugin:ts#trpc-api#procedureyarn nx g @aws/nx-plugin:ts#trpc-api#procedurenpx nx g @aws/nx-plugin:ts#trpc-api#procedurebunx nx g @aws/nx-plugin:ts#trpc-api#procedureVous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
pnpm nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-runyarn nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-runnpx nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-runbunx nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-runSi cela réussit, nous devrions avoir généré une nouvelle procédure et l’avoir ajoutée à notre routeur dans router.ts.
Exercices
Section intitulée « Exercices »Si vous êtes arrivé jusqu’ici et avez encore du temps pour expérimenter avec les générateurs Nx, voici quelques suggestions de fonctionnalités à ajouter au générateur de procédures :
1. Opérations Imbriquées
Section intitulée « 1. Opérations Imbriquées »Essayez de modifier le générateur pour supporter les routeurs imbriqués en :
- Acceptant une notation par points pour l’entrée
procedure(ex:games.query) - Générant une procédure avec un nom basé sur l’inversion de la notation par points (ex:
queryGames) - Ajoutant le routeur imbriqué approprié (ou le mettant à jour s’il existe déjà)
2. Validation
Section intitulée « 2. Validation »Notre générateur devrait se prémunir contre les problèmes potentiels, comme un utilisateur sélectionnant un project qui n’est pas une API tRPC. Consultez le générateur connection pour un exemple.
3. Tests Unitaires
Section intitulée « 3. Tests Unitaires »Écrivez des tests unitaires pour le générateur. Ceux-ci sont assez simples à implémenter et suivent généralement le flux suivant :
- Créer un arbre d’espace de travail vide avec
createTreeUsingTsSolutionSetup() - Ajouter les fichiers qui devraient déjà exister dans l’arbre (ex:
project.jsonetsrc/router.tspour un backend tRPC) - Exécuter le générateur sous test
- Valider que les modifications attendues sont apportées à l’arbre
4. Tests End-to-End
Section intitulée « 4. Tests End-to-End »Actuellement, nous avons un seul “smoke test” qui exécute tous les générateurs et vérifie que la compilation réussit. Celui-ci devrait être mis à jour pour inclure le nouveau générateur.
Orientation Générale pour Accélérer les Contributions
Section intitulée « Orientation Générale pour Accélérer les Contributions »Cette section contient des conseils généraux qui peuvent vous aider lors du travail sur le Nx Plugin for AWS.
Travailler en partant d’un projet réel
Section intitulée « Travailler en partant d’un projet réel »Une façon utile de créer de nouveaux générateurs ou d’ajouter des fonctionnalités/corrections à un générateur existant est de le construire d’abord pour de vrai. De cette façon, vous pouvez valider vos idées et itérer rapidement pour obtenir la fonctionnalité dont vous avez besoin. Une fois que vous avez déterminé le résultat souhaité, vous pouvez ensuite mettre à jour le générateur.
En pratique, ce processus pourrait ressembler à :
-
Créer un nouvel espace de travail
Terminal window npx create-nx-workspace@22.5.1 my-project --pm=pnpm --preset=@aws/nx-plugin --ci=skip --aiAgentsTerminal window npx create-nx-workspace@22.5.1 my-project --pm=yarn --preset=@aws/nx-plugin --ci=skip --aiAgentsTerminal window npx create-nx-workspace@22.5.1 my-project --pm=npm --preset=@aws/nx-plugin --ci=skip --aiAgentsTerminal window npx create-nx-workspace@22.5.1 my-project --pm=bun --preset=@aws/nx-plugin --ci=skip --aiAgents -
Exécuter tous les générateurs qui peuvent être des prérequis à votre nouveau générateur/fonctionnalité/correction
-
Valider vos modifications (
git commit) -
Effectuer les modifications souhaitées et les tester selon les besoins
-
Utiliser le
git diffde vos modifications pour déterminer quelles modifications doivent être apportées au Nx Plugin for AWS -
Effectuer un dernier test end-to-end (en liant votre
@aws/nx-plugin) pour vous assurer que votre générateur produit les modifications dont vous avez besoin