Ir al contenido

Generador de Migración Nx

Agrega una Migración Nx a un Plugin 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 vendida modificada, o una actualización de dependencia que requiere cambios de código acompañantes.

El generador crea el esqueleto 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).

  1. Instale el Nx Console VSCode Plugin si aún no lo ha hecho
  2. Abra la consola Nx en VSCode
  3. Haga clic en Generate (UI) en la sección "Common Nx Commands"
  4. Busque @aws/nx-plugin - ts#nx-migration
  5. Complete los parámetros requeridos
    • Haga clic en Generate
    ParámetroTipoPredeterminadoDescripción
    project Requeridostring-El proyecto Nx Plugin al que se agregará la migración. Recomendamos usar el generador ts#nx-plugin para crearlo.
    name Requeridostring-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 | hybriddeterministicEl 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 booleantrueSi 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.

    Las migraciones de Nx 23 vienen en tres formas, discriminadas por qué campos contiene la entrada de migrations.json. Pasa --kind para elegir (por defecto deterministic):

    • Determinista (implementation) — un codemod con un antes/después exacto. Se ejecuta sin supervisión, incluyendo en CI y terminales no interactivas. Este es el tipo preferido: úsalo siempre que el archivo objetivo sea uno que tus generadores posean completamente y la edición pueda expresarse mecánicamente.
    • Agéntica (prompt) — un archivo de instrucciones markdown aplicado por el agente de codificación local del usuario a través del flujo agéntico nx migrate de Nx. Úsalo para cambios en código propiedad del usuario donde la edición correcta depende de lo que el usuario haya construido. Cuando no se ejecuta ningún agente (CI, sin agente instalado, consentimiento rechazado), Nx muestra el prompt como instrucciones manuales — así que escribe prompts como pasos autocontenidos y accionables por humanos.
    • Híbrida (implementation + prompt) — un cambio incompatible con una mitad mecánica y una mitad de juicio. La implementation hace todo lo que posees de forma determinista y devuelve agentContext describiendo lo que cambió u omitió; Nx pasa ese contexto al prompt emparejado, que dirige al agente a los sitios de llamada propiedad del usuario.

    El generador crea los siguientes archivos bajo la carpeta fuente del proyecto de tu 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 aterriza 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 más abajo.

    Una migración determinista (o híbrida) es una función que muta el sistema de archivos virtual (el Tree), devolviendo un MigrationReturnObject:

    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[] = [];
    // Read and update the files your generators produce here.
    await formatFilesInSubtree(tree);
    return { nextSteps };
    }
    • nextSteps — notas a nivel de workspace mostradas al usuario después de que nx migrate se ejecuta. Úsalas para reportar archivos que omitiste (consulta las barreras de protección más abajo) o seguimiento manual que la migración no pudo realizar.
    • agentContext (solo híbrida) — un resumen de lo que el codemod cambió, pasado al prompt emparejado cuando se ejecuta bajo el flujo agéntico de Nx para que el agente pueda enfocarse en las partes propiedad del usuario.

    Para las mismas operaciones que usas en generadores (generateFiles, transformaciones GritQL, lectura y actualización de JSON), consulta la guía de Generador Nx.

    Las migraciones se ejecutan contra workspaces que no controlas, por lo que se recomienda adherirse a lo siguiente (el esqueleto generado incorpora estas reglas):

    • Coincidencia de patrones antes de escribir. Si un archivo objetivo ha divergido de la forma que tus generadores producen, omítelo y repórtalo vía nextSteps en lugar de sobrescribir los cambios del usuario.
    • Idempotente. Re-ejecutar la migración debe ser una operación sin efecto.
    • Formatea lo que escribes. Termina con formatFilesInSubtree(tree) para que los archivos que tu migración escribió estén formateados correctamente.

    El migration.spec.ts generado usa createTreeUsingTsSolutionSetup() para construir un workspace virtual que coincide con la forma que nuestro preset genera. Prueba que la migración lleva un workspace del estado “antes” al estado objetivo, omite (y reporta) archivos personalizados, y es 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');
    });
    });

    Las pruebas unitarias solo demuestran que la migración hace lo que escribiste que hiciera. También pruébala contra un workspace 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 workspace nuevo y compara, verifica que el workspace aún se construye, luego vuelve a ejecutar la migración para confirmar que no cambia nada. Repite con un workspace que hayas personalizado primero, para verificar que la migración deja tus ediciones intactas y las reporta en su lugar.

    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 estámpalo 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"
    }
    }
    }

    Los usuarios aplican las migraciones de tu plugin con el flujo de dos pasos nx migrate — generar las migraciones pendientes, instalar, y luego ejecutarlas:

    Terminal window
    pnpm nx migrate my-plugin@latest
    pnpm nx migrate --run-migrations

    Las 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 Workspace.