Pular para o conteúdo

Gerador de Migração Nx

Adiciona uma Migração Nx a um Plugin Nx. As migrações permitem que o nx migrate atualize automaticamente projetos que foram gerados por uma versão anterior do seu plugin quando você faz uma mudança incompatível — alvos renomeados, configuração fornecida alterada ou uma atualização de dependência que requer mudanças de código correspondentes.

O gerador cria o scaffold da migração, registra-a no migrations.json do seu plugin e conecta o campo nx-migrations no package.json do seu plugin (criando ambos se eles ainda não existirem).

  1. Instale o Nx Console VSCode Plugin se ainda não o fez
  2. Abra o console Nx no VSCode
  3. Clique em Generate (UI) na seção "Common Nx Commands"
  4. Procure por @aws/nx-plugin - ts#nx-migration
  5. Preencha os parâmetros obrigatórios
    • Clique em Generate
    ParâmetroTipoPadrãoDescrição
    project Obrigatóriostring-O projeto Nx Plugin ao qual adicionar a migração. Recomendamos usar o gerador ts#nx-plugin para criá-lo.
    name Obrigatóriostring-Nome da migração, em kebab-case (ex: rename-foo-target)
    description string-Uma descrição do que a migração faz, exibida por nx migrate
    kind deterministic | agentic | hybriddeterministicO tipo de migração: deterministic (um codemod), agentic (um prompt aplicado por IA para código de propriedade do usuário), ou hybrid (um codemod que faz a parte mecânica e depois passa para um agente)
    preferInstallDependencies booleantrueSe deve preferir instalar dependências após a execução do gerador. Defina como false para adiar a instalação ao agrupar vários geradores (uma instalação ainda é executada se necessário para que os geradores subsequentes possam calcular o grafo de projetos Nx); instale uma vez no final.

    As migrações do Nx 23 vêm em três formas, discriminadas por quais campos a entrada migrations.json carrega. Passe --kind para escolher (padrão deterministic):

    • Determinística (implementation) — um codemod com um antes/depois exato. Executa sem supervisão, incluindo em CI e terminais não interativos. Este é o tipo preferido: prefira-o sempre que o arquivo de destino for um que seus geradores possuem totalmente e a edição puder ser expressa mecanicamente.
    • Agêntica (prompt) — um arquivo de instrução markdown aplicado pelo agente de codificação local do usuário através do fluxo agêntico nx migrate do Nx. Use para mudanças em código de propriedade do usuário onde a edição correta depende do que o usuário construiu. Quando nenhum agente é executado (CI, nenhum agente instalado, consentimento recusado), o Nx apresenta o prompt como instruções manuais — então escreva prompts como passos autocontidos e acionáveis por humanos.
    • Híbrida (implementation + prompt) — uma mudança incompatível com uma metade mecânica e uma metade de julgamento. A implementation faz tudo que você possui deterministicamente e retorna agentContext descrevendo o que mudou ou pulou; o Nx passa esse contexto para o prompt pareado, que direciona o agente para os locais de chamada de propriedade do usuário.

    O gerador cria os seguintes arquivos sob a pasta de origem do seu projeto de plugin, dependendo do kind escolhido:

    • Directorysrc/migrations/<name>/
      • migration.ts Implementação do codemod (determinística e híbrida)
      • migration.spec.ts Testes para sua migração (determinística e híbrida)
      • prompt.md Instruções para agente/humano (agêntica e híbrida)
    • migrations.json Criado ou atualizado para registrar sua migração
    • package.json Criado ou atualizado para adicionar uma entrada “nx-migrations”

    Uma nova migração é colocada em latest/. Agrupar migrações pelo release que as envia mantém sua ordem visível rapidamente à medida que a coleção cresce — mova uma migração para uma pasta v<x.y.z>/ (e atualize seus caminhos em migrations.json) quando você atribuir sua versão.

    Ele registra a migração em migrations.json com os campos para seu tipo e sem version — veja Versionamento abaixo. A chave registrada é prefixada com a pasta em que a migração reside (latest-<name>), então reutilizar um nome para uma mudança posterior não pode sobrescrever silenciosamente uma migração que já foi enviada.

    Uma migração determinística (ou híbrida) é uma função que muta o sistema de arquivos virtual (a Tree), retornando um MigrationReturnObject. Aqui está uma híbrida, que retorna 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 — notas em todo o workspace apresentadas ao usuário após a execução do nx migrate. Use-as para relatar arquivos que você pulou (veja as proteções abaixo) ou acompanhamento manual que a migração não pôde realizar.
    • agentContext (apenas híbrida) — um resumo do que o codemod mudou, passado para o prompt pareado quando ele é executado sob o fluxo agêntico do Nx para que o agente possa focar nas partes de propriedade do usuário.

    Para alguns exemplos de operações que você pode realizar em sua migração (gerar arquivos, modificar arquivos existentes usando GritQL, ler e atualizar JSON), consulte o guia do Gerador Nx.

    As migrações são executadas em workspaces que você não controla, então é recomendado aderir ao seguinte (o esqueleto gerado incorpora isso):

    • Corresponda padrões antes de escrever. Se um arquivo de destino divergiu da forma que seus geradores produzem, pule-o e relate-o via nextSteps em vez de sobrescrever as mudanças do usuário.
    • Idempotente. Re-executar a migração deve ser uma operação sem efeito.
    • Formate o que você escreve. Finalize com formatFilesInSubtree(tree) para que os arquivos que sua migração escreveu sejam formatados corretamente.

    O migration.spec.ts gerado usa createTreeUsingTsSolutionSetup() para construir um workspace virtual correspondente à forma que nosso preset gera. Teste que a migração leva um workspace do estado “antes” para o estado alvo, pula (e relata) arquivos personalizados, e é 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');
    });
    });

    O Nx executa uma migração quando a versão do plugin instalado do usuário é menor que a version da migração. Este gerador não escreve nenhum campo version — atribua-o (ou carimbe-o do seu processo de release) quando você cortar o release que envia a migração, para que ela seja executada para todos que estão atualizando de uma versão anterior.

    Uma vez que você atribui versões, um migrations.json registrando uma migração de cada tipo se parece com isto:

    {
    "$schema": "http://json-schema.org/schema",
    "name": "my-plugin",
    "generators": {
    "rename-foo-target": {
    "version": "2.0.0",
    "description": "Rename the foo target to bar",
    "implementation": "./src/migrations/rename-foo-target/migration"
    },
    "migrate-custom-handlers": {
    "version": "3.0.0",
    "description": "Update custom handlers for the new API",
    "prompt": "./src/migrations/migrate-custom-handlers/prompt.md"
    },
    "upgrade-framework": {
    "version": "4.0.0",
    "description": "Upgrade the framework and reconcile call sites",
    "implementation": "./src/migrations/upgrade-framework/migration",
    "prompt": "./src/migrations/upgrade-framework/prompt.md"
    }
    }
    }

    Os usuários aplicam as migrações do seu plugin com o fluxo de duas etapas nx migrate — gerar as migrações pendentes, instalar e então executá-las:

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

    Migrações agênticas e híbridas são aplicadas pelo agente de codificação local do usuário durante nx migrate --run-migrations quando um está disponível.

    Para o fluxo completo da perspectiva do usuário que está atualizando — incluindo exemplos de saída para migrações determinísticas e agênticas — veja Atualizando Seu Workspace.