Générateur de Migration Nx
Ajoute une Migration Nx à un Plugin Nx. Les migrations permettent à nx migrate de mettre à jour automatiquement les projets qui ont été générés par une version précédente de votre plugin lorsque vous effectuez un changement incompatible — cibles renommées, configuration fournie modifiée, ou mise à jour de dépendance nécessitant des modifications de code associées.
Le générateur crée l’échafaudage de la migration, l’enregistre dans le fichier migrations.json de votre plugin, et configure le champ nx-migrations dans le package.json de votre plugin (en créant les deux s’ils n’existent pas encore).
Utilisation
Section intitulée « Utilisation »Générer une Migration
Section intitulée « Générer une Migration »- 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-migration - Remplissez les paramètres requis
- Cliquez sur
Generate
pnpm nx g @aws/nx-plugin:ts#nx-migrationyarn nx g @aws/nx-plugin:ts#nx-migrationnpx nx g @aws/nx-plugin:ts#nx-migrationbunx nx g @aws/nx-plugin:ts#nx-migrationVous pouvez également effectuer une simulation pour voir quels fichiers seraient modifiés
pnpm nx g @aws/nx-plugin:ts#nx-migration --dry-runyarn nx g @aws/nx-plugin:ts#nx-migration --dry-runnpx nx g @aws/nx-plugin:ts#nx-migration --dry-runbunx nx g @aws/nx-plugin:ts#nx-migration --dry-run| Paramètre | Type | Par défaut | Description |
|---|---|---|---|
| project Requis | string | - | Le projet Nx Plugin auquel ajouter la migration. Nous recommandons d'utiliser le générateur ts#nx-plugin pour le créer. |
| name Requis | string | - | Nom de la migration, en kebab-case (par exemple rename-foo-target) |
| description | string | - | Une description de ce que fait la migration, affichée par nx migrate |
| kind | deterministic | agentic | hybrid | deterministic | Le type de migration : deterministic (un codemod), agentic (un prompt appliqué par IA pour du code appartenant à l'utilisateur), ou hybrid (un codemod qui effectue la partie mécanique puis délègue à un agent) |
| preferInstallDependencies | boolean | true | Indique s'il faut privilégier l'installation des dépendances après l'exécution du générateur. Définir à false pour différer l'installation lors de l'enchaînement de plusieurs générateurs (une installation s'exécute quand même si nécessaire pour que les générateurs suivants puissent calculer le graphe de projet Nx) ; installer une seule fois à la fin. |
Les trois types de migration
Section intitulée « Les trois types de migration »Les migrations se présentent sous trois formes, distinguées par les champs que l’entrée migrations.json contient. Passez --kind pour choisir (par défaut deterministic) :
- Déterministe (
implementation) — un codemod avec un avant/après exact. S’exécute sans surveillance, y compris en CI et dans les terminaux non interactifs. Utilisez-le seul lorsque le changement a une forme que vous pouvez faire correspondre de manière fiable partout où il apparaît. - Agentique (
prompt) — un fichier d’instructions markdown appliqué par l’agent de codage local de l’utilisateur via le fluxnx migrateagentique de Nx. Utilisez-le seul lorsqu’aucun avant/après mécanique ne tient, car la modification correcte dépend de ce que l’utilisateur a construit. Lorsqu’aucun agent ne s’exécute (CI, aucun agent installé, consentement refusé), Nx présente le prompt comme des instructions manuelles — écrivez donc les prompts comme des étapes autonomes et actionnables par un humain. - Hybride (
implementation+prompt) — les deux moitiés d’un changement, et généralement le bon choix. Tout ce que vos générateurs fournissent est du code que l’utilisateur possède et peut avoir modifié, donc le codemod fait autant qu’il peut faire correspondre en toute sécurité et retourne unagentContextdécrivant ce qu’il a changé et ce qu’il a ignoré ; Nx transmet ce contexte aupromptassocié, qui dirige l’agent vers le reste.
Sortie du Générateur
Section intitulée « Sortie du Générateur »Le générateur crée les fichiers suivants dans le dossier source de votre projet de plugin, selon le kind choisi :
Répertoiresrc/migrations/latest/<name>/
- migration.ts Implémentation du codemod (déterministe et hybride)
- migration.spec.ts Tests pour votre migration (déterministe et hybride)
- prompt.md Instructions pour l’agent/humain (agentique et hybride)
- migrations.json Créé ou mis à jour pour enregistrer votre migration
- package.json Créé ou mis à jour pour ajouter une entrée “nx-migrations”
Une nouvelle migration arrive dans latest/. Regrouper les migrations par la version qui les livre permet de garder leur ordre visible d’un coup d’œil à mesure que la collection s’agrandit — déplacez une migration dans un dossier v<x.y.z>/ (et mettez à jour ses chemins dans migrations.json) lorsque vous attribuez sa version.
Il enregistre la migration dans migrations.json avec les champs correspondant à son type et sans version — voir Versionnage ci-dessous. La clé enregistrée est préfixée par le dossier dans lequel vit la migration (latest-<name>), de sorte que réutiliser un nom pour un changement ultérieur ne peut pas écraser silencieusement une migration qui a déjà été livrée.
Implémenter une Migration
Section intitulée « Implémenter une Migration »Une migration déterministe (ou hybride) est une fonction qui modifie le système de fichiers virtuel (le Tree), retournant un MigrationReturnObject. Voici une migration hybride, qui retourne les deux :
import { type MigrationReturnObject, type Tree } from '@nx/devkit';import { formatFilesInSubtree } from '@aws/nx-plugin/sdk/utils/format';
export default async function migration( tree: Tree,): Promise<MigrationReturnObject> { const nextSteps: string[] = []; const agentContext: string[] = [];
// Read and update the files your generators produce here.
await formatFilesInSubtree(tree);
return { nextSteps, agentContext };}nextSteps— notes à l’échelle de l’espace de travail présentées à l’utilisateur après l’exécution denx migrate. Utilisez-les pour signaler les fichiers que vous avez ignorés (voir les garde-fous ci-dessous) ou les actions manuelles que la migration n’a pas pu effectuer.agentContext(hybride uniquement) — un résumé de ce que le codemod a modifié, transmis aupromptassocié lorsqu’il s’exécute dans le flux agentique de Nx afin que l’agent puisse se concentrer sur les parties appartenant à l’utilisateur.
Pour quelques exemples d’opérations que vous pouvez effectuer dans votre migration (générer des fichiers, modifier des fichiers existants en utilisant GritQL, lire et mettre à jour du JSON), consultez le guide du Générateur Nx.
Garde-fous
Section intitulée « Garde-fous »Les migrations s’exécutent sur des espaces de travail que vous ne contrôlez pas, il est donc recommandé de respecter les règles suivantes (le squelette généré les intègre) :
- Vérifier le motif avant d’écrire. Si un fichier cible a divergé de la forme que vos générateurs produisent, ignorez-le et signalez-le via
nextSteps, ou envisagez une migration hybride, plutôt que d’écraser les modifications de l’utilisateur. - Idempotent. Réexécuter la migration doit être une opération sans effet.
- Formater ce que vous écrivez. Terminez avec
formatFilesInSubtree(tree)afin que les fichiers écrits par votre migration soient formatés correctement.
Tester Votre Migration
Section intitulée « Tester Votre Migration »Le fichier migration.spec.ts généré utilise createTreeUsingTsSolutionSetup() pour construire un espace de travail virtuel correspondant à la forme que notre preset génère. Testez que la migration fait passer un espace de travail de l’état “avant” à l’état cible, ignore (et signale) le code qu’elle ne reconnaît pas, et est idempotente :
import type { Tree } from '@nx/devkit';import { createTreeUsingTsSolutionSetup } from '@aws/nx-plugin/sdk/utils/test';import migration from './migration';
describe('my migration', () => { let tree: Tree;
beforeEach(() => { tree = createTreeUsingTsSolutionSetup(); });
it('should update the generated shape', async () => { // Set up a tree with the "before" state tree.write('project.json', JSON.stringify({ targets: { foo: {} } }));
// Run the migration await migration(tree);
// Check that the tree matches the target state const projectJson = JSON.parse(tree.read('project.json', 'utf-8')); expect(projectJson.targets).toHaveProperty('bar'); expect(projectJson.targets).not.toHaveProperty('foo'); });});Les tests unitaires prouvent seulement que la migration fait ce que vous avez écrit qu’elle devait faire. Testez-la également sur un espace de travail généré par la version publiée de votre plugin — l’état depuis lequel vos utilisateurs effectuent la mise à niveau — et confirmez que le résultat correspond à ce que vos générateurs produisent aujourd’hui : inspectez le diff, générez les mêmes projets dans un nouvel espace de travail et comparez, vérifiez que l’espace de travail se construit toujours, puis réexécutez la migration pour confirmer qu’elle ne change rien. Répétez avec un espace de travail que vous avez d’abord personnalisé, pour vérifier que la migration laisse vos modifications intactes et les signale à la place.
Versionnage
Section intitulée « Versionnage »Nx exécute une migration lorsque la version du plugin installée par l’utilisateur est inférieure à la version de la migration. Ce générateur n’écrit aucun champ version — attribuez-le (ou tamponnez-le depuis votre processus de publication) lorsque vous publiez la version qui livre la migration, afin qu’elle s’exécute pour tous ceux qui mettent à niveau depuis une version antérieure.
Une fois que vous avez attribué des versions, un migrations.json enregistrant une migration de chaque type ressemble à ceci :
{ "$schema": "http://json-schema.org/schema", "name": "my-plugin", "generators": { "v2.0.0-rename-foo-target": { "version": "2.0.0", "description": "Rename the foo target to bar", "implementation": "./src/migrations/v2.0.0/rename-foo-target/migration" }, "v3.0.0-migrate-custom-handlers": { "version": "3.0.0", "description": "Update custom handlers for the new API", "prompt": "./src/migrations/v3.0.0/migrate-custom-handlers/prompt.md" }, "v4.0.0-upgrade-framework": { "version": "4.0.0", "description": "Upgrade the framework and reconcile call sites", "implementation": "./src/migrations/v4.0.0/upgrade-framework/migration", "prompt": "./src/migrations/v4.0.0/upgrade-framework/prompt.md" } }}Exécuter les Migrations
Section intitulée « Exécuter les Migrations »Les utilisateurs appliquent les migrations de votre plugin avec le flux nx migrate en deux étapes — générer les migrations en attente, installer, puis les exécuter :
pnpm nx migrate my-plugin@latestpnpm nx migrate --run-migrationsyarn nx migrate my-plugin@latestyarn nx migrate --run-migrationsnpx nx migrate my-plugin@latestnpx nx migrate --run-migrationsbunx nx migrate my-plugin@latestbunx nx migrate --run-migrationsLes migrations agentiques et hybrides sont appliquées par l’agent de codage local de l’utilisateur pendant nx migrate --run-migrations lorsqu’un agent est disponible.
Pour le flux complet du point de vue de l’utilisateur effectuant la mise à niveau — y compris des exemples de sortie pour les migrations déterministes et agentiques — voir Mise à Niveau de Votre Espace de Travail.