Contribuir con un Generador
Vamos a crear un nuevo generador para contribuir a @aws/nx-plugin
. Nuestro objetivo será generar un nuevo procedimiento para una API tRPC.
Clonar el Plugin
Sección titulada «Clonar el Plugin»Primero, clonemos el plugin:
git clone git@github.com:awslabs/nx-plugin-for-aws.git
Luego, instalar y construir:
cd nx-plugin-for-awspnpm ipnpm nx run-many --target build --all
Crear un Generador Vacío
Sección titulada «Crear un Generador Vacío»Creemos el nuevo generador en packages/nx-plugin/src/trpc/procedure
.
¡Proveemos un generador para crear nuevos generadores para que puedas estructurar rápidamente el tuyo! Puedes ejecutar este generador así:
- Instale el Nx Console VSCode Plugin si aún no lo ha hecho
- Abra la consola Nx en VSCode
- Haga clic en
Generate (UI)
en la sección "Common Nx Commands" - Busque
@aws/nx-plugin - ts#nx-generator
- Complete los parámetros requeridos
- pluginProject: @aws/nx-plugin
- name: ts#trpc-api#procedure
- directory: trpc/procedure
- description: Adds a procedure to a tRPC API
- Haga clic en
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 API
yarn 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
npx 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
bunx 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
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
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-run
yarn 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-run
npx 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-run
bunx 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-run
Notarás que se han generado los siguientes archivos:
Directorypackages/nx-plugin/src/trpc/procedure
- schema.json Define las entradas del generador
- schema.d.ts Interfaz TypeScript que coincide con el schema
- generator.ts Función que ejecuta Nx como generador
- generator.spec.ts Pruebas para el generador
Directorydocs/src/content/docs/guides/
- trpc-procedure.mdx Documentación del generador
- packages/nx-plugin/generators.json Actualizado para incluir el generador
Actualicemos el schema para añadir las propiedades necesarias:
{ "$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';}
Notarás que el generador ya está configurado en 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" } },...
Implementar el Generador
Sección titulada «Implementar el Generador»Para añadir un procedimiento a una API tRPC, necesitamos hacer dos cosas:
- Crear un archivo TypeScript para el nuevo procedimiento
- Añadir el procedimiento al enrutador
Crear el Nuevo Procedimiento
Sección titulada «Crear el Nuevo Procedimiento»Para crear el archivo TypeScript, usaremos una utilidad llamada generateFiles
. Con esta, definimos una plantilla EJS que podemos renderizar en nuestro generador con variables basadas en las opciones del usuario.
Primero, definamos la plantilla en packages/nx-plugin/src/trpc/procedure/files/procedures/__procedureNameKebabCase__.ts.template
:
import { publicProcedure } from '../init.js';import { z } from 'zod/v4';
export const <%- procedureNameCamelCase %> = publicProcedure .input(z.object({ // TODO: define input })) .output(z.object({ // TODO: define output })) .<%- procedureType %>(async ({ input, ctx }) => { // TODO: implement! return {}; });
En la plantilla, usamos tres variables:
procedureNameCamelCase
procedureNameKebabCase
procedureType
Debemos asegurarnos de pasarlas a generateFiles
, junto con el directorio destino (el sourceRoot
del proyecto seleccionado), que podemos extraer de la configuración del proyecto.
Actualicemos el generador:
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;
Añadir el Procedimiento al Enrutador
Sección titulada «Añadir el Procedimiento al Enrutador»Ahora actualizaremos el código fuente para incluir el nuevo procedimiento en el enrutador. Usamos manipulación de AST de TypeScript para esto:
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;
Compilemos el generador para probarlo:
pnpm nx run @aws/nx-plugin:compile
Probar el Generador
Sección titulada «Probar el Generador»Para probar, vincularemos nuestro plugin local a un proyecto existente.
Crear Proyecto de Prueba con API tRPC
Sección titulada «Crear Proyecto de Prueba con API tRPC»En otro directorio, crea un workspace:
npx create-nx-workspace@~21.0.3 trpc-generator-test --pm=pnpm --preset=@aws/nx-plugin --ci=skip
npx create-nx-workspace@~21.0.3 trpc-generator-test --pm=yarn --preset=@aws/nx-plugin --ci=skip
npx create-nx-workspace@~21.0.3 trpc-generator-test --pm=npm --preset=@aws/nx-plugin --ci=skip
npx create-nx-workspace@~21.0.3 trpc-generator-test --pm=bun --preset=@aws/nx-plugin --ci=skip
Genera una API tRPC:
- Instale el Nx Console VSCode Plugin si aún no lo ha hecho
- Abra la consola Nx en VSCode
- Haga clic en
Generate (UI)
en la sección "Common Nx Commands" - Busque
@aws/nx-plugin - ts#trpc-api
- Complete los parámetros requeridos
- apiName: test-api
- Haga clic en
Generate
pnpm nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive
yarn nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive
npx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive
bunx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
pnpm nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-run
yarn nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-run
npx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-run
bunx nx g @aws/nx-plugin:ts#trpc-api --apiName=test-api --no-interactive --dry-run
Vincular el Plugin Local
Sección titulada «Vincular el Plugin Local»En tu proyecto, vincula @aws/nx-plugin
:
cd path/to/trpc-generator-testpnpm link path/to/nx-plugin-for-aws/dist/packages/nx-plugin
cd path/to/trpc-generator-testyarn link path/to/nx-plugin-for-aws/dist/packages/nx-plugin
cd path/to/trpc-generator-testnpm link path/to/nx-plugin-for-aws/dist/packages/nx-plugin
cd path/to/nx-plugin-for-aws/dist/packages/nx-pluginbun linkcd path/to/trpc-generator-testbun link @aws/nx-plugin
Ejecutar el Nuevo Generador
Sección titulada «Ejecutar el Nuevo Generador»Prueba el generador:
- Instale el Nx Console VSCode Plugin si aún no lo ha hecho
- Abra la consola Nx en VSCode
- Haga clic en
Generate (UI)
en la sección "Common Nx Commands" - Busque
@aws/nx-plugin - ts#trpc-api#procedure
- Complete los parámetros requeridos
- Haga clic en
Generate
pnpm nx g @aws/nx-plugin:ts#trpc-api#procedure
yarn nx g @aws/nx-plugin:ts#trpc-api#procedure
npx nx g @aws/nx-plugin:ts#trpc-api#procedure
bunx nx g @aws/nx-plugin:ts#trpc-api#procedure
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
pnpm nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-run
yarn nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-run
npx nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-run
bunx nx g @aws/nx-plugin:ts#trpc-api#procedure --dry-run
Si tiene éxito, se habrá generado un nuevo procedimiento y se habrá añadido al enrutador en router.ts
.
Ejercicios
Sección titulada «Ejercicios»Si llegaste hasta aquí y quieres explorar más, aquí algunas sugerencias:
1. Operaciones Anidadas
Sección titulada «1. Operaciones Anidadas»Modifica el generador para soportar enrutadores anidados:
- Aceptar notación de puntos para
procedure
(ej:games.query
) - Generar nombres basados en la notación inversa (ej:
queryGames
) - Crear/actualizar enrutadores anidados
2. Validación
Sección titulada «2. Validación»Añade validación para prevenir selección de proyectos no tRPC. Revisa el generador api-connection
como referencia.
3. Pruebas Unitarias
Sección titulada «3. Pruebas Unitarias»Escribe pruebas unitarias que:
- Creen un workspace vacío con
createTreeUsingTsSolutionSetup()
- Añadan archivos necesarios (ej:
project.json
,src/router.ts
) - Ejecuten el generador
- Verifiquen los cambios en el árbol
4. Pruebas End-to-End
Sección titulada «4. Pruebas End-to-End»Actualiza las pruebas existentes para incluir este nuevo generador. Actualmente hay una prueba básica que verifica que el build funciona.