Generador de Migración de Nx
Agrega una Migración de Nx a un Plugin de Nx. Las migraciones permiten que nx migrate actualice automáticamente los proyectos que fueron generados por una versión anterior de tu plugin cuando realizas un cambio incompatible — objetivos renombrados, configuración proporcionada modificada, o una actualización de dependencia que requiere cambios de código acompañantes.
El generador crea la estructura de la migración, la registra en el migrations.json de tu plugin, y conecta el campo nx-migrations en el package.json de tu plugin (creando ambos si aún no existen).
Generar una Migración
Sección titulada «Generar una Migración»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-migrationTambién puede realizar una ejecución en seco para ver qué archivos se cambiarían
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- 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-migration - Complete los parámetros requeridos
- Haga clic en
Generate
Opciones
Sección titulada «Opciones»| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
| project Requerido | string | - | El proyecto Nx Plugin al que se agregará la migración. Recomendamos usar el generador ts#nx-plugin para crearlo. |
| name Requerido | string | - | Nombre de la migración, en kebab-case (ej. rename-foo-target) |
| description | string | - | Una descripción de lo que hace la migración, mostrada por nx migrate |
| kind | deterministic | agentic | hybrid | deterministic | El tipo de migración: deterministic (un codemod), agentic (un prompt aplicado por IA para código propio del usuario), o hybrid (un codemod que realiza la parte mecánica y luego delega a un agente) |
| preferInstallDependencies | boolean | true | Si se prefiere instalar dependencias después de que el generador se ejecute. Establecer en false para diferir la instalación al agrupar múltiples generadores (la instalación aún se ejecuta si es necesaria para que los generadores subsiguientes puedan calcular el grafo de proyectos Nx); instalar una vez al final. |
Los tres tipos de migración
Sección titulada «Los tres tipos de migración»Las migraciones vienen en tres formas, discriminadas por qué campos lleva la entrada de migrations.json. Pasa --kind para elegir (por defecto deterministic):
- Determinista (
implementation) — un codemod con un antes/después exacto, y el primero al que recurrir. Se ejecuta sin supervisión, incluso en CI y terminales no interactivas, y se aplica de manera idéntica para cada usuario. Úsalo solo cuando el cambio tiene una forma que puedes hacer coincidir de manera confiable en todos los lugares donde aparece, reportando cualquier cosa que omitió a través denextSteps. - Híbrida (
implementation+prompt) — ambas mitades de un cambio. Úsala cuando un cambio es incompatible y no puede aplicarse completamente de manera mecánica: el codemod hace tanto como puede hacer coincidir de manera segura y devuelveagentContextdescribiendo qué cambió y qué omitió; Nx pasa ese contexto alpromptemparejado, que dirige al agente al resto. El prompt es lo que evita que un espacio de trabajo quede roto cuando las ediciones restantes abarcan demasiadas formas para hacer codemod. - Agéntica (
prompt) — un archivo de instrucciones en markdown aplicado por el agente de codificación local del usuario a través del flujo agénticonx migratede Nx. Úsala sola cuando no existe ningún antes/después mecánico en absoluto, porque la edición correcta depende de lo que el usuario ha construido. Cuando no se ejecuta ningún agente (CI, ningún agente instalado, consentimiento rechazado), Nx muestra el prompt como instrucciones manuales — así que escribe los prompts como pasos autocontenidos y ejecutables por humanos.
Salida del Generador
Sección titulada «Salida del Generador»El generador crea los siguientes archivos bajo la carpeta de origen de tu proyecto de plugin, dependiendo del kind elegido:
Directoriosrc/migrations/latest/<name>/
- migration.ts Implementación del codemod (determinista e híbrida)
- migration.spec.ts Pruebas para tu migración (determinista e híbrida)
- prompt.md Instrucciones para agente/humano (agéntica e híbrida)
- migrations.json Creado o actualizado para registrar tu migración
- package.json Creado o actualizado para agregar una entrada “nx-migrations”
Una nueva migración se coloca en latest/. Agrupar las migraciones por el lanzamiento que las envía mantiene su orden visible de un vistazo a medida que la colección crece — mueve una migración a una carpeta v<x.y.z>/ (y actualiza sus rutas en migrations.json) cuando asignes su versión.
Registra la migración en migrations.json con los campos para su tipo y sin version — consulta Versionado a continuación. La clave registrada tiene como prefijo la carpeta en la que vive la migración (latest-<name>), por lo que reutilizar un nombre para un cambio posterior no puede sobrescribir silenciosamente una migración que ya se ha enviado.
Implementar una Migración
Sección titulada «Implementar una Migración»Una migración determinista (o híbrida) es una función que muta el sistema de archivos virtual (el Tree), devolviendo un MigrationReturnObject. Aquí hay una híbrida, que devuelve ambos:
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— las acciones de seguimiento que Nx imprime para el usuario después de que se ejecutanx migrate. Cada entrada debe ser algo que necesiten hacer manualmente: reconciliar un archivo que omitiste (consulta las barreras de protección a continuación), o terminar algo más allá del alcance de la migración, como una instalación para actualizar un archivo de bloqueo. No son un registro de lo que cambiaste — cuando una transformación se aplica limpiamente, no agregues nada, de lo contrario las entradas que sí necesitan acción quedan enterradas.agentContext(solo híbrida) — un resumen de lo que cambió el codemod, pasado alpromptemparejado cuando se ejecuta bajo el flujo agéntico de Nx para que el agente pueda enfocarse en las partes propiedad del usuario.
Para algunos ejemplos de operaciones que puedes realizar en tu migración (generar archivos, modificar archivos existentes usando GritQL, leer y actualizar JSON), consulta la guía de Generador de Nx.
Barreras de Protección
Sección titulada «Barreras de Protección»Las migraciones se ejecutan contra espacios de trabajo que no controlas, por lo que se recomienda adherirse a lo siguiente (el esqueleto generado incorpora estos):
- Transforma el código fuente con GritQL. Usa los helpers de GritQL (
applyGritQL,matchGritQL) para editar el código fuente en lugar de expresiones regulares o reemplazos de cadenas. GritQL coincide con el AST, por lo que un patrón se mantiene a través del formato, espacios en blanco y comillas en los que la copia del usuario puede haberse desviado, donde la coincidencia de texto silenciosamente pierde código equivalente o corrompe el archivo. UsaupdateJsonpara JSON y el analizador correspondiente para otra configuración estructurada. - Haz coincidencia de patrones antes de escribir. Si un archivo de destino se ha desviado de la forma que producen tus generadores, omítelo y repórtalo a través de
nextSteps, o considera una migración híbrida, en lugar de sobrescribir los cambios del usuario.matchGritQLes una forma conveniente de hacer esa verificación. - Reporta solo lo que queda por hacer.
nextStepses para el trabajo que el usuario tiene que retomar, no un registro de las ediciones que hiciste — esas ya están en sugit diff. - Idempotente. Volver a ejecutar la migración debe ser una operación sin efecto. Protege las reescrituras de GritQL que inyectan código con una cláusula
where { ... <: not contains ... }para que una segunda ejecución no agregue un duplicado. - Formatea lo que escribes. Termina con
formatFilesInSubtree(tree)para que los archivos que escribió tu migración estén formateados correctamente.
Probar Tu Migración
Sección titulada «Probar Tu Migración»El migration.spec.ts generado usa createTreeUsingTsSolutionSetup() para construir un espacio de trabajo virtual que coincida con la forma que genera nuestro preset. Prueba que la migración lleva un espacio de trabajo del estado “antes” al estado objetivo, omite (y reporta) código que no reconoce, y es idempotente:
import type { Tree } from '@nx/devkit';import { createTreeUsingTsSolutionSetup } from '@aws/nx-plugin/sdk/utils/test';import migration from './migration.js';
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'); });});Las pruebas unitarias solo prueban que la migración hace lo que escribiste que hiciera. También pruébala contra un espacio de trabajo generado por la versión publicada de tu plugin — el estado desde el que tus usuarios actualizan — y confirma que el resultado coincide con lo que tus generadores producen hoy: inspecciona el diff, genera los mismos proyectos en un espacio de trabajo nuevo y compara, verifica que el espacio de trabajo aún se construye, luego vuelve a ejecutar la migración para confirmar que no cambia nada. Repite con un espacio de trabajo que hayas personalizado primero, para verificar que la migración deja tus ediciones solas y las reporta en su lugar.
Versionado
Sección titulada «Versionado»Nx ejecuta una migración cuando la versión del plugin instalado del usuario es menor que la version de la migración. Este generador no escribe ningún campo version — asígnalo (o márcalo desde tu proceso de lanzamiento) cuando cortes el lanzamiento que envía la migración, para que se ejecute para todos los que actualicen desde una versión anterior.
Una vez que asignes versiones, un migrations.json que registra una migración de cada tipo se ve así:
{ "$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" } }}Ejecutar Migraciones
Sección titulada «Ejecutar Migraciones»Los usuarios aplican las migraciones de tu plugin con el flujo de dos pasos nx migrate — genera las migraciones pendientes, instala, luego ejecútalas:
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-migrationsLas migraciones agénticas e híbridas son aplicadas por el agente de codificación local del usuario durante nx migrate --run-migrations cuando uno está disponible.
Para el flujo completo desde la perspectiva del usuario que actualiza — incluyendo salida de ejemplo para migraciones deterministas y agénticas — consulta Actualizar Tu Espacio de Trabajo.