Générateur de Générateur Nx
Ajoute un Nx Generator à un projet TypeScript pour vous aider à automatiser des tâches répétitives comme la création de composants ou l’application de structures de projet spécifiques.
Utilisation
Générer un générateur
Vous pouvez générer un générateur de deux manières :
- 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
- Cliquez sur
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
Vous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
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
Options
Paramètre | Type | Par défaut | Description |
---|---|---|---|
pluginProject Requis | string | - | TypeScript project to add the generator to. We recommend creating a ts#project in a top-level 'tools' directory. |
name Requis | 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>) |
Résultat du générateur
Le générateur créera les fichiers suivants dans le pluginProject
spécifié :
Répertoiresrc/<name>/
- schema.json Schéma pour les entrées de votre générateur
- schema.d.ts Types TypeScript pour votre schéma
- generator.ts Implémentation de base du générateur
- generator.spec.ts Tests pour votre générateur
- generators.json Configuration Nx pour définir vos générateurs
- package.json Créé ou mis à jour pour ajouter une entrée “generators”
- tsconfig.json Mis à jour pour utiliser CommonJS
Ce générateur mettra à jour le pluginProject
sélectionné pour utiliser CommonJS, car les générateurs Nx ne prennent actuellement en charge que CommonJS (voir cette issue GitHub pour le support ESM).
Générateurs locaux
Sélectionnez votre projet local nx-plugin
lors de l’exécution du générateur ts#nx-generator
, puis spécifiez un nom ainsi qu’un répertoire et une description optionnels.
Définition du schéma
Le fichier schema.json
définit les options acceptées par votre générateur. Il suit le format JSON Schema avec des extensions spécifiques à Nx.
Structure de base
Un fichier schema.json a la structure de base suivante :
{ "$schema": "https://json-schema.org/schema", "$id": "YourGeneratorName", "title": "Your Generator Title", "description": "Description of what your generator does", "type": "object", "properties": { // Vos options de générateur ici }, "required": ["requiredOption1", "requiredOption2"]}
Exemple simple
Voici un exemple simple avec quelques options basiques :
{ "$schema": "https://json-schema.org/schema", "$id": "ComponentGenerator", "title": "Create a Component", "description": "Creates a new React component", "type": "object", "properties": { "name": { "type": "string", "description": "Component name", "x-priority": "important" }, "directory": { "type": "string", "description": "Directory where the component will be created", "default": "src/components" }, "withTests": { "type": "boolean", "description": "Whether to generate test files", "default": true } }, "required": ["name"]}
Invites interactives (CLI)
Vous pouvez personnaliser les invites affichées lors de l’exécution de votre générateur via la CLI en ajoutant la propriété x-prompt
:
"name": { "type": "string", "description": "Component name", "x-prompt": "What is the name of your component?"}
Pour les options booléennes, utilisez une invite oui/non :
"withTests": { "type": "boolean", "description": "Whether to generate test files", "x-prompt": "Would you like to generate test files?"}
Sélections déroulantes
Pour les options avec un ensemble fixe de choix, utilisez enum
pour permettre aux utilisateurs de sélectionner une option.
"style": { "type": "string", "description": "The styling approach to use", "enum": ["css", "scss", "styled-components", "none"], "default": "css"}
Liste déroulante de sélection de projet
Un modèle courant consiste à laisser les utilisateurs sélectionner parmi les projets existants :
"project": { "type": "string", "description": "The project to add the component to", "x-prompt": "Which project would you like to add the component to?", "x-dropdown": "projects"}
La propriété x-dropdown: "projects"
indique à Nx de peupler la liste avec tous les projets de l’espace de travail.
Arguments positionnels
Vous pouvez configurer des options à passer comme arguments positionnels via la ligne de commande :
"name": { "type": "string", "description": "Component name", "x-priority": "important", "$default": { "$source": "argv", "index": 0 }}
Cela permet d’exécuter le générateur comme nx g your-generator my-component
au lieu de nx g your-generator --name=my-component
.
Définition des priorités
Utilisez la propriété x-priority
pour indiquer les options les plus importantes :
"name": { "type": "string", "description": "Component name", "x-priority": "important"}
Les priorités peuvent être "important"
ou "internal"
. Cela aide Nx à ordonner les propriétés dans l’extension VSCode et la CLI.
Valeurs par défaut
Vous pouvez fournir des valeurs par défaut :
"directory": { "type": "string", "description": "Directory where the component will be created", "default": "src/components"}
Plus d’informations
Pour plus de détails sur les schémas, consultez la documentation Nx sur les options de générateur.
Types TypeScript avec schema.d.ts
En plus de schema.json
, le générateur crée un fichier schema.d.ts
fournissant des types TypeScript pour vos options :
export interface YourGeneratorSchema { name: string; directory?: string; withTests?: boolean;}
Cette interface est utilisée dans votre implémentation pour la sécurité des types et l’autocomplétion :
import { YourGeneratorSchema } from './schema';
export default async function (tree: Tree, options: YourGeneratorSchema) { // TypeScript connaît les types de toutes vos options const { name, directory = 'src/components', withTests = true } = options; // ...}
Implémentation d’un générateur
Après avoir créé le générateur, vous pouvez écrire son implémentation dans generator.ts
.
Un générateur est une fonction qui modifie un système de fichiers virtuel (Tree
), lisant et écrivant des fichiers pour effectuer les changements. Les modifications ne sont écrites sur le disque qu’après l’exécution du générateur, sauf en mode “dry-run”.
Voici des opérations courantes dans un générateur :
Lecture et écriture de fichiers
// Lire un fichierconst content = tree.read('path/to/file.ts', 'utf-8');
// Écrire un fichiertree.write('path/to/new-file.ts', 'export const hello = "world";');
// Vérifier l'existence d'un fichierif (tree.exists('path/to/file.ts')) { // Faire quelque chose}
Génération de fichiers à partir de modèles
Utilisez generateFiles
de @nx/devkit
pour générer des fichiers avec des modèles EJS.
import { generateFiles, joinPathFragments } from '@nx/devkit';
// Générer des fichiers à partir de modèlesgenerateFiles( tree, joinPathFragments(__dirname, 'files'), // Répertoire des modèles 'path/to/output', // Répertoire de sortie { // Variables de substitution name: options.name, nameCamelCase: camelCase(options.name), nameKebabCase: kebabCase(options.name), },);
Manipulation d’AST TypeScript
Utilisez tsAstReplace
du plugin Nx pour AWS pour modifier l’AST TypeScript :
import { tsAstReplace } from '@aws/nx-plugin/sdk/utils/ast';import * as ts from 'typescript';
// Exemple : Incrémenter un numéro de versiontsAstReplace( tree, 'path/to/version.ts', 'VariableDeclaration:has(Identifier[name="VERSION"]) NumericLiteral', (node: ts.NumericLiteral) => ts.factory.createNumericLiteral(Number(node.text) + 1));
Ajout de dépendances
import { addDependenciesToPackageJson } from '@nx/devkit';
// Ajouter des dépendances à package.jsonaddDependenciesToPackageJson( tree, { 'new-dependency': '^1.0.0', }, { 'new-dev-dependency': '^2.0.0', },);
Formatage des fichiers générés
import { formatFilesInSubtree } from '@aws/nx-plugin/sdk/utils/format';
// Formater tous les fichiers modifiésawait formatFilesInSubtree(tree, 'optional/path/to/format');
Lecture et mise à jour de fichiers JSON
import { readJson, updateJson } from '@nx/devkit';
// Lire un fichier JSONconst packageJson = readJson(tree, 'package.json');
// Mettre à jour un fichier JSONupdateJson(tree, 'tsconfig.json', (json) => { json.compilerOptions = { ...json.compilerOptions, strict: true, }; return json;});
Extension d’un générateur du plugin Nx pour AWS
Vous pouvez importer et étendre des générateurs existants :
import { tsProjectGenerator } from '@aws/nx-plugin/sdk/ts';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { const callback = await tsProjectGenerator(tree, { ... });
// Étendre le générateur de projet TypeScript ici
return callback;};
Générateurs OpenAPI
Vous pouvez utiliser les générateurs pour les clients TypeScript et les hooks :
import { openApiTsClientGenerator } from '@aws/nx-plugin/sdk/open-api';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { await openApiTsClientGenerator(tree, { ... });
// Ajouter des fichiers supplémentaires ici};
Nous exposons aussi une méthode pour générer des structures de données à partir de spécifications OpenAPI :
import { buildOpenApiCodeGenerationData } from '@aws/nx-plugin/sdk/open-api.js';
export const myGenerator = async (tree: Tree, schema: MyGeneratorSchema) => { const data = await buildOpenApiCodeGenerationData(tree, 'path/to/spec.json');
generateFiles( tree, joinPathFragments(__dirname, 'files'), 'path/to/output', data, );};
Exemple de template EJS :
export const myOperationNames = [<%_ allOperations.forEach((op) => { _%> '<%- op.name %>',<%_ }); _%>];
Consultez le dépôt GitHub pour des exemples complexes.
Exécution de votre générateur
Deux méthodes pour exécuter votre 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
@my-project/nx-plugin - my-generator
- Remplissez les paramètres requis
- Cliquez sur
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
Vous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
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
Tests de votre générateur
Les tests unitaires suivent ce modèle :
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';import { yourGenerator } from './generator';
describe('your generator', () => { let tree;
beforeEach(() => { tree = createTreeWithEmptyWorkspace(); tree.write('src/existing-file.ts', 'export const existing = true;'); });
it('should generate expected files', 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('should handle errors', async () => { await expect(yourGenerator(tree, { name: 'invalid' })) .rejects.toThrow('Expected error message'); });});
Points clés pour les tests :
- Utilisez
createTreeWithEmptyWorkspace()
pour un système de fichiers virtuel - Testez la création de fichiers et les mises à jour
- Utilisez des snapshots pour le contenu complexe
- Testez les cas d’erreur
Contribution de générateurs à @aws/nx-plugin
Le générateur ts#nx-generator
peut aussi scaffold un générateur dans @aws/nx-plugin
.
Dans notre dépôt, il génèrera :
Répertoirepackages/nx-plugin/src/<name>/
- schema.json Schéma d’entrée
- schema.d.ts Types TypeScript
- generator.ts Implémentation
- generator.spec.ts Tests
Répertoiredocs/src/content/docs/guides/
- <name>.mdx Page de documentation
- packages/nx-plugin/generators.json Mis à jour