Generador de Generadores de Nx
Agrega un Generador de Nx a un proyecto TypeScript para ayudarte a automatizar tareas repetitivas como la creación de componentes o la aplicación de estructuras de proyecto específicas.
Generar un generador
Sección titulada «Generar un generador»Puedes generar un generador de dos formas:
- 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
- Haga clic en
Generate
pnpm nx g @aws/nx-plugin:ts#nx-generator
yarn nx g @aws/nx-plugin:ts#nx-generator
npx nx g @aws/nx-plugin:ts#nx-generator
bunx nx g @aws/nx-plugin:ts#nx-generator
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 --dry-run
yarn nx g @aws/nx-plugin:ts#nx-generator --dry-run
npx nx g @aws/nx-plugin:ts#nx-generator --dry-run
bunx nx g @aws/nx-plugin:ts#nx-generator --dry-run
Opciones
Sección titulada «Opciones»Parámetro | Tipo | Predeterminado | Descripción |
---|---|---|---|
project Requerido | string | - | TypeScript project to add the generator to. We recommend using the ts#nx-plugin generator to create this. |
name Requerido | string | - | Generator name |
description | string | - | A description of your generator |
directory | string | - | The directory within the plugin project's source folder to add the generator to (default: <name>) |
Salida del generador
Sección titulada «Salida del generador»El generador creará los siguientes archivos en el project
seleccionado:
Directorysrc/<nombre>/
- schema.json Esquema para la entrada del generador
- schema.d.ts Tipos TypeScript para tu esquema
- generator.ts Implementación base del generador
- generator.spec.ts Pruebas para tu generador
- README.md Documentación del generador
- generators.json Configuración de Nx para definir tus generadores
- package.json Creado o actualizado para agregar entrada “generators”
- tsconfig.json Actualizado para usar CommonJS
Este generador actualizará el project
seleccionado para usar CommonJS, ya que los generadores de Nx actualmente solo soportan CommonJS (consulta este issue de GitHub para soporte ESM).
Generadores locales
Sección titulada «Generadores locales»Selecciona tu proyecto local nx-plugin
al ejecutar el generador ts#nx-generator
, y especifica un nombre junto con directorio y descripción opcionales.
Definir el esquema
Sección titulada «Definir el esquema»El archivo schema.json
define las opciones que acepta tu generador. Sigue el formato JSON Schema con extensiones específicas de Nx.
Estructura básica
Sección titulada «Estructura básica»Un archivo schema.json tiene la siguiente estructura básica:
{ "$schema": "https://json-schema.org/schema", "$id": "YourGeneratorName", "title": "Your Generator Title", "description": "Description of what your generator does", "type": "object", "properties": { // Tus opciones del generador van aquí }, "required": ["requiredOption1", "requiredOption2"]}
Ejemplo simple
Sección titulada «Ejemplo simple»Aquí un ejemplo simple con algunas opciones básicas:
{ "$schema": "https://json-schema.org/schema", "$id": "ComponentGenerator", "title": "Create a Component", "description": "Crea un nuevo componente React", "type": "object", "properties": { "name": { "type": "string", "description": "Nombre del componente", "x-priority": "important" }, "directory": { "type": "string", "description": "Directorio donde se creará el componente", "default": "src/components" }, "withTests": { "type": "boolean", "description": "Generar archivos de prueba", "default": true } }, "required": ["name"]}
Prompts interactivos (CLI)
Sección titulada «Prompts interactivos (CLI)»Puedes personalizar los prompts mostrados al ejecutar tu generador vía CLI agregando la propiedad x-prompt
:
"name": { "type": "string", "description": "Nombre del componente", "x-prompt": "¿Cuál es el nombre de tu componente?"}
Para opciones booleanas, puedes usar un prompt sí/no:
"withTests": { "type": "boolean", "description": "Generar archivos de prueba", "x-prompt": "¿Deseas generar archivos de prueba?"}
Selecciones en dropdown
Sección titulada «Selecciones en dropdown»Para opciones con un conjunto fijo de opciones, usa enum
para que los usuarios puedan seleccionar:
"style": { "type": "string", "description": "Enfoque de estilos a usar", "enum": ["css", "scss", "styled-components", "none"], "default": "css"}
Dropdown de selección de proyectos
Sección titulada «Dropdown de selección de proyectos»Un patrón común es permitir seleccionar entre proyectos existentes:
"project": { "type": "string", "description": "Proyecto donde agregar el componente", "x-prompt": "¿A qué proyecto deseas agregar el componente?", "x-dropdown": "projects"}
La propiedad x-dropdown: "projects"
indica a Nx poblar el dropdown con todos los proyectos del workspace.
Argumentos posicionales
Sección titulada «Argumentos posicionales»Puedes configurar opciones para recibirse como argumentos posicionales:
"name": { "type": "string", "description": "Nombre del componente", "x-priority": "important", "$default": { "$source": "argv", "index": 0 }}
Esto permite ejecutar el generador como nx g your-generator mi-componente
en lugar de nx g your-generator --name=mi-componente
.
Establecer prioridades
Sección titulada «Establecer prioridades»Usa la propiedad x-priority
para indicar opciones importantes:
"name": { "type": "string", "description": "Nombre del componente", "x-priority": "important"}
Las prioridades pueden ser "important"
o "internal"
. Esto ayuda a Nx a ordenar propiedades en la extensión VSCode y CLI.
Valores predeterminados
Sección titulada «Valores predeterminados»Puedes proveer valores por defecto:
"directory": { "type": "string", "description": "Directorio para el componente", "default": "src/components"}
Más información
Sección titulada «Más información»Para más detalles sobre esquemas, consulta la documentación de Opciones de Generadores Nx.
Tipos TypeScript con schema.d.ts
Sección titulada «Tipos TypeScript con schema.d.ts»Junto con schema.json
, el generador crea un archivo schema.d.ts
con tipos TypeScript:
export interface YourGeneratorSchema { name: string; directory?: string; withTests?: boolean;}
Esta interfaz se usa en la implementación para seguridad de tipos:
import { YourGeneratorSchema } from './schema';
export default async function (tree: Tree, options: YourGeneratorSchema) { // TypeScript conoce los tipos de las opciones const { name, directory = 'src/components', withTests = true } = options; // ...}
Implementar un generador
Sección titulada «Implementar un generador»Tras crear el generador, puedes escribir su implementación en generator.ts
.
Un generador es una función que muta un sistema de archivos virtual (Tree
). Los cambios se escriben al disco al finalizar, a menos que se ejecute en modo “dry-run”. Un generador vacío:
export const myGenerator = async (tree: Tree, options: MyGeneratorSchema) => { // Usa el tree para aplicar cambios};
export default myGenerator;
Operaciones comunes en generadores:
Leer y escribir archivos
Sección titulada «Leer y escribir archivos»// Leer archivoconst content = tree.read('ruta/al/archivo.ts', 'utf-8');
// Escribir archivotree.write('ruta/nuevo-archivo.ts', 'export const hola = "mundo";');
// Verificar existenciaif (tree.exists('ruta/al/archivo.ts')) { // Hacer algo}
Generar archivos desde plantillas
Sección titulada «Generar archivos desde plantillas»Usa generateFiles
de @nx/devkit
con plantillas EJS:
import { generateFiles, joinPathFragments } from '@nx/devkit';
generateFiles( tree, joinPathFragments(__dirname, 'files'), // Directorio de plantillas 'ruta/de/salida', // Directorio de salida { name: options.name, nameCamelCase: camelCase(options.name), nameKebabCase: kebabCase(options.name), },);
Manipulación de AST TypeScript
Sección titulada «Manipulación de AST TypeScript»Usa tsAstReplace
del Plugin Nx para AWS para modificar AST:
import { tsAstReplace } from '@aws/nx-plugin/sdk/utils/ast';import * as ts from 'typescript';
// Ejemplo: Incrementar versióntsAstReplace( tree, 'ruta/version.ts', 'VariableDeclaration:has(Identifier[name="VERSION"]) NumericLiteral', (node: ts.NumericLiteral) => ts.factory.createNumericLiteral(Number(node.text) + 1));
Agregar dependencias
Sección titulada «Agregar dependencias»import { addDependenciesToPackageJson } from '@nx/devkit';
addDependenciesToPackageJson( tree, { 'nueva-dependencia': '^1.0.0' }, { 'nueva-dev-dependencia': '^2.0.0' },);
Formatear archivos
Sección titulada «Formatear archivos»import { formatFilesInSubtree } from '@aws/nx-plugin/sdk/utils/format';
await formatFilesInSubtree(tree, 'ruta/opcional');
Leer y actualizar JSON
Sección titulada «Leer y actualizar JSON»import { readJson, updateJson } from '@nx/devkit';
// Leer JSONconst packageJson = readJson(tree, 'package.json');
// Actualizar JSONupdateJson(tree, 'tsconfig.json', (json) => { json.compilerOptions.strict = true; return json;});
Extender generadores del Plugin Nx para AWS
Sección titulada «Extender generadores del Plugin Nx para AWS»Importa y extiende generadores existentes:
import { tsProjectGenerator } from '@aws/nx-plugin/sdk/ts';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { const callback = await tsProjectGenerator(tree, { ... }); // Extiende aquí return callback;};
Generadores OpenAPI
Sección titulada «Generadores OpenAPI»Puedes usar generadores para clientes TypeScript:
import { openApiTsClientGenerator } from '@aws/nx-plugin/sdk/open-api';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { await openApiTsClientGenerator(tree, { ... }); // Agregar archivos};
También puedes generar datos desde especificaciones OpenAPI:
import { buildOpenApiCodeGenerationData } from '@aws/nx-plugin/sdk/open-api.js';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { const data = await buildOpenApiCodeGenerationData(tree, 'ruta/espec.json'); generateFiles(tree, __dirname + '/files', 'ruta/salida', data);};
Ejemplo de plantilla EJS:
export const myOperationNames = [<%_ allOperations.forEach((op) => { _%> '<%- op.name %>',<%_ }); _%>];
Consulta el repositorio en GitHub para ejemplos complejos.
Ejecutar tu generador
Sección titulada «Ejecutar tu generador»Ejecuta tu generador de dos formas:
- 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
@my-project/nx-plugin - my-generator
- Complete los parámetros requeridos
- Haga clic en
Generate
pnpm nx g @my-project/nx-plugin:my-generator
yarn nx g @my-project/nx-plugin:my-generator
npx nx g @my-project/nx-plugin:my-generator
bunx nx g @my-project/nx-plugin:my-generator
También puede realizar una ejecución en seco para ver qué archivos se cambiarían
pnpm nx g @my-project/nx-plugin:my-generator --dry-run
yarn nx g @my-project/nx-plugin:my-generator --dry-run
npx nx g @my-project/nx-plugin:my-generator --dry-run
bunx nx g @my-project/nx-plugin:my-generator --dry-run
Probar tu generador
Sección titulada «Probar tu generador»Pruebas unitarias típicas:
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';import { yourGenerator } from './generator';
describe('tu generador', () => { let tree;
beforeEach(() => { tree = createTreeWithEmptyWorkspace(); tree.write('project.json', JSON.stringify({ name: 'test-project' })); });
it('debe generar archivos esperados', async () => { await yourGenerator(tree, { name: 'test' }); expect(tree.exists('src/test/file.ts')).toBeTruthy(); expect(tree.read('src/test/file.ts', 'utf-8')).toMatchSnapshot(); });
it('debe manejar errores', async () => { await expect(yourGenerator(tree, { name: 'invalido' })) .rejects.toThrow('Mensaje de error esperado'); });});
Puntos clave:
- Usa
createTreeWithEmptyWorkspace()
- Prueba creación y actualización de archivos
- Usa snapshots para contenido complejo
- Prueba condiciones de error
Contribuir generadores a @aws/nx-plugin
Sección titulada «Contribuir generadores a @aws/nx-plugin»Usa ts#nx-generator
para crear generadores dentro de @aws/nx-plugin
.
Al ejecutarlo en nuestro repositorio, genera:
Directorypackages/nx-plugin/src/<nombre>/
- schema.json
- schema.d.ts
- generator.ts
- generator.spec.ts
Directorydocs/src/content/docs/guides/
- <nombre>.mdx
- packages/nx-plugin/generators.json Actualizado