<link rel="stylesheet" href="/assets/fonts/jetbrains-mono/jetbrains-mono.css" />
All posts

Migração do Angular de v10 para v21: O guia completo versão a versão

Migrar um aplicativo do Angular 10 para o Angular 21 significa passar por onze versões principais, cada um com suas próprias alterações importantes. Fazer isso de uma só vez nunca é uma opção realista: a equipe O próprio Angular recomenda atualizações sequenciais, uma importante de cada vez, usando ng update em cada passagem. Este guia cobre toda a jornada: o que muda em cada versão, os comandos exatos a serem executados, os problemas mais comuns encontrados em migrações reais, o impacto sobre desempenho e pacotes, e um plano operacional de 30/60/90 dias para gerenciar riscos em um projeto empreendimento.

Nota importante: Alguns detalhes da versão (especialmente para Angular 19, 20 e 21, o mais recente no momento da redação) deve sempre ser verificado em relação à documentação oficial antes de planejar uma atualização em produção, com npm visualize versões @angular/core e ng versão em projeto real.

Matriz de compatibilidade

AngularTypeScriptRxJSNodeAngular CLIAngular Material
103,96,5 / 6,610,13 / 12.111010
114.06.5.310.13 / 12.111111
124.26.5.3 / 712.14 / 141212
134.46.5.3 / 712.20 / 141313
144.6 / 4.76.5.3 / 714.15 / 161414
154.8 / 4.96.5.3 / 714.20 / 161515
164.9 / 5.16.5.3 / 716 / 181616
175.26.5.3 / 718.13 / 201717
185.4/5.56.5.3/718.19/20/ 221818
195.5/5.66.5.3/718.19/20/ 221919
205.6+ (verificar)720/22 (verificar)2020
21para verificar7de verificar2121

Para Angular 20 e 21, sempre verifique os requisitos exatos antes de planejar: npm view @angular/core@21 peerDependencies retorna as versões mínimas atualmente exigidas de instalação, mais confiável do que qualquer mesa estática.

ng comandos de atualização: o Padrão Sequencial

# Pattern generale per ogni step (mai saltare una major)
ng update @angular/core@X @angular/cli@X --force
npm install
ng build
npm test

# Esempio concreto: da 10 a 11
ng update @angular/core@11 @angular/cli@11

O sinalizador --force ignora as verificações de compatibilidade de dependência de pares quando um biblioteca de terceiros ainda não lançou suporte para a nova versão principal - use-a apenas quando tiver verificou manualmente se a biblioteca funciona de qualquer maneira, nunca como padrão automático. --migrate-only executa apenas os esquemas de migração sem tocar nas versões do pacotes (úteis para executar novamente uma migração específica após uma correção manual), enquanto --de/--a permitem que você atinja um intervalo de versões específico quando ng update não detecta automaticamente a versão inicial correta.

Angular 11 → 12: Do View Engine ao Ivy Everywhere

Visão geral e alterações significativas

  • Angular 11 (novembro de 2020): TypeScript 4.0, rastreamentos de pilha mais legíveis, substituição opcional de módulo ativo.
  • Angular 12 (maio de 2021): Ivy se torna o compilador/tempo de execução padrão também para publicação de bibliotecas (formato de pacote Angular atualizado), modo estrito habilitado por padrão em novos projetos, descontinuação formal do View Engine.
  • APIs obsoletas: entryComponents não são mais necessárias com Ivy, relativeLinkResolution no roteador obsoleto.
ng update @angular/core@12 @angular/cli@12
// tsconfig.json — strict mode raccomandato da Angular 12 in poi
{
  "compilerOptions": { "strict": true },
  "angularCompilerOptions": { "strictTemplates": true }
}

Angular 13: Adeus ao View Engine e ao IE11

Visão geral e alterações significativas

  • View Engine completamente removido: apenas Ivy desta versão em diante, ngcc não é mais necessário para bibliotecas publicadas com o novo formato de pacote Angular.
  • Suporte ao Internet Explorer 11 removido — se o seu público ainda inclui o IE11, este é um item importante a ser avaliado com cuidado.
  • Nova API para componentes dinâmicos (ViewContainerRef.createComponent sem ComponentFactoryResolver).
// Prima (Angular 12 e precedenti)
constructor(private resolver: ComponentFactoryResolver) {}
createDynamic() {
  const factory = this.resolver.resolveComponentFactory(MyComponent);
  this.container.createComponent(factory);
}

// Dopo (Angular 13+) — nessun ComponentFactoryResolver necessario
createDynamic() {
  this.container.createComponent(MyComponent);
}

Angular 14: Componentes autônomos na visualização do desenvolvedor

Visão geral e alterações recentes

  • Componentes/diretivas/pipes independentes introduzidos (visualização do desenvolvedor, ainda não recomendado para produção).
  • Formulários reativos digitados: FormControl e similares tornam-se genéricos, resultando em erros de tipo no código existente que assumia any.
  • Os diagnósticos estendidos do compilador relatam padrões arriscados em modelos já na fase de construção.
ng update @angular/core@14 @angular/cli@14
// Typed forms — il compilatore ora rileva errori prima invisibili
const form = new FormGroup({ email: new FormControl('', { nonNullable: true }) });
// form.value.email è ora tipizzato string, non any

Angular 15: Estável independente e NgOptimizedImage

Visão geral e alterações recentes

  • API autônoma torna-se estável e recomendada para novos projetos.
  • Directive NgOptimizedImage estável: carregamento lento automático e dimensionamento de imagem com impacto direto no LCP.
  • Angular Material muda para a nova arquitetura baseada em MDC (Material Design Components), com possíveis pequenas diferenças visuais nos componentes existentes.
// Componente standalone — nessun NgModule richiesto
@Component({ selector: 'app-widget', standalone: true, imports: [CommonModule], template: `...` })
export class WidgetComponent {}
<img ngSrc="hero.jpg" width="800" height="400" priority />

Angular 16: Sinais na visualização do desenvolvedor

Visão geral e alterações significativas

  • Sinais introduzidos na visualização do desenvolvedor: reatividade granular alternativa/complementar para Zone.js.
  • Builder esbuild na visualização do desenvolvedor para ng build: Tempos de construção significativamente mais rápidos.
  • Entradas obrigatórias (@Input({ obrigatório: verdadeiro })) e tags de fechamento automático em modelos ().
  • Suporte experimental para Jest como um executor de testes alternativo ao Karma.
ng update @angular/core@16 @angular/cli@16
# Opt-in al builder esbuild (developer preview in questa versione)
// Signal — reattività granulare senza dipendere dal digest di Zone.js
count = signal(0);
doubled = computed(() => this.count() * 2);

Angular 17: Novo fluxo de controle e Vite/esbuild padrão

Visão geral e alterações significativas

  • Nova sintaxe de fluxo de controle em modelos (@if, @for, @switch) estável, substitui *ngIf/*ngFor com melhor desempenho de renderização.
  • Builder baseado em esbuild/Vite torna-se padrão para novos projetos (desenvolvimento de servidor drasticamente mais rápido).
  • @defer para carregamento lento declarativo de blocos de modelo (visualizações adiáveis).
<!-- Prima: *ngFor/*ngIf -->
<div *ngIf="user">{{ user.name }}</div>
<li *ngFor="let item of items; trackBy: trackById">{{ item.name }}</li>

<!-- Dopo: nuovo control flow, track obbligatorio in @for -->
@if (user) { <div>{{ user.name }}</div> }
@for (item of items; track item.id) { <li>{{ item.name }}</li> }
<!-- @defer — carica il blocco solo quando entra in viewport -->
@defer (on viewport) {
  <heavy-chart />
} @placeholder {
  <div class="skeleton"></div>
}

Angular 18: Experimental e Material Sem Zona 3

Visão geral e alterações significativas

  • Detecção experimental de alterações sem zona: capacidade de remover Zone.js do pacote para aplicativos baseados em Signal.
  • Angular Material 3 (Material Design 3) estável, com novos designs de tokens temáticos.
  • Repetição de eventos para aplicações com SSR/hidratação: os eventos do usuário durante a hidratação não são mais perdidos.
// main.ts — opt-in sperimentale a zoneless (rimuove la dipendenza da Zone.js)
bootstrapApplication(AppComponent, {
  providers: [provideExperimentalZonelessChangeDetection()],
});

Angular 19: autônomo por padrão e hidratação incremental

Visão geral e alterações significativas

  • Novos projetos gerados por ng new são independentes por padrão: NgModule não é mais o andaime padrão.
  • Hidratação incremental: hidratação seletiva de partes da página em vez de todo o aplicativo em massa, com benefícios diretos no Time to Interactive.
  • Novas primitivas baseadas em sinal (linkedSignal, resource) para estado derivado e busca de dados reativos.
ng update @angular/core@19 @angular/cli@19
// resource() — data fetching reattivo basato su Signal (verificare API esatta nella versione installata)
userResource = resource({
  request: () => this.userId(),
  loader: ({ request }) => fetchUser(request),
});

Angular 20 e 21: Sempre verifique a documentação oficial

Para esses dois lançamentos, os mais recentes no momento da redação deste guia, os detalhes exatos de mudanças significativas e requisitos de dependência devem sempre ser confirmados com os comandos oficiais antes planeje a atualização - a direção geral é a consolidação de sinais e sem zonas em direção ao estabilidade total, redução adicional do pacote padrão e evolução contínua do construtor esbuild/Vite, mas datas exatas e detalhes específicos da API devem ser verificados caso a caso.

# Verifica sempre versione corrente, changelog e requisiti prima di procedere
npm view @angular/core versions --json | tail -20
ng version
npx ng update @angular/core@21 @angular/cli@21 --dry-run

RxJS: de rxjs-compat para remoção

Em projetos iniciados a partir do Angular 10, é comum ainda encontrar o rxjs-compat instalado para sintaxe de suporte com operadores concatenados pré-pipeable. Deve ser removido o mais rápido possível: além de o inchaço do pacote oculta descontinuações que, de outra forma, o compilador reportaria imediatamente.

// Prima — operatori concatenati (richiede rxjs-compat)
source.map(x => x * 2).filter(x => x > 10).subscribe();

// Dopo — pipeable operators, nessuna dipendenza da rxjs-compat
source.pipe(map(x => x * 2), filter(x => x > 10)).subscribe();
npm uninstall rxjs-compat

Testes: de Karma/Transferidor a Jest/Cypress

O transferidor foi descontinuado pela própria equipe Angular desde 2022 e deve ser substituído independentemente Versão de destino angular. Karma permanece funcional por mais tempo, mas Jest (suportado experimentalmente Angular 16 em diante) oferece tempos de execução significativamente mais rápidos em CI.

# Migrazione E2E: rimuovi Protractor, installa Cypress
ng g @angular/cli:e2e-e2e-schematic-removal 2>/dev/null || echo "rimuovi manualmente e2e/ e protractor.conf.js"
npm install --save-dev cypress
npx cypress open
// Test aggiornato — Jest invece di Jasmine/Karma
describe('UserCardComponent', () => {
  it('mostra il nome utente', () => {
    const fixture = TestBed.createComponent(UserCardComponent);
    fixture.componentRef.setInput('user', { name: 'Mario' });
    fixture.detectChanges();
    expect(fixture.nativeElement.textContent).toContain('Mario');
  });
});

Scripts de automação para atualizações sequenciais

#!/bin/bash
# upgrade-sequenziale.sh — esegue ng update versione per versione con report
set -e
VERSIONS=(11 12 13 14 15 16 17 18 19)
for v in "${VERSIONS[@]}"; do
  echo "=== Upgrade a Angular $v ==="
  ng update @angular/core@$v @angular/cli@$v --force
  npm install
  npm run build > "report-build-v$v.log" 2>&1 || { echo "❌ Build fallita su v$v"; exit 1; }
  npm test -- --watch=false > "report-test-v$v.log" 2>&1 || echo "⚠️  Test falliti su v$v, controllare report-test-v$v.log"
  git add -A && git commit -m "chore: upgrade Angular a v$v"
done
echo "✅ Upgrade sequenziale completato fino a v${VERSIONS[-1]}"

Monorepo: Nx, Lerna e pnpm Workspace

Em um monorepo com bibliotecas internas compartilhadas, a ordem de atualização é importante: atualize primeiro bibliotecas compartilhadas (verificando se cada peerDependencies declara um intervalo compatível com o novo principal), recompile-os e atualize os aplicativos de consumo. Com Nx, nx migra Latest orquestra automaticamente esse pedido para pacotes gerenciados pelo espaço de trabalho.

# Nx — migrazione orchestrata dell'intero workspace
npx nx migrate latest
npx nx migrate --run-migrations

CI/CD: Atualizando Pipelines

# GitHub Actions — matrice Node/Angular coerente con la versione target
jobs:
  build:
    strategy:
      matrix:
        node-version: [20.x]
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npm run build -- --configuration production
      - run: npm test -- --watch=false --browsers=ChromeHeadless

Sempre atualize a versão do Node no pipeline before executando ng update localmente: uma incompatibilidade entre o nó local e o nó CI é uma causa frequente de "funciona no meu computador" durante as atualizações.

Impacto no desempenho e no pacote

  • Ivy vs View Engine: pacotes menores em média e agitação de árvores mais eficaz já desde a transição para Ivy (Angular 9-13).
  • Removendo ngcc: Compilações mais rápidas após Angular 13, quando todas as bibliotecas são publicadas no formato de pacote Angular nativo Ivy.
  • esbuild/Vite: Reduza drasticamente os tempos de construção e desenvolvimento do servidor em comparação com o construtor Webpack legado, começando em Angular 16-17.
  • Componentes autônomos: elimine o padrão de NgModules e melhore o tremor de árvore refinado por componente.
  • Sinais e sem zona: Potencial remoção de Zone.js do pacote final, resultando em redução de tamanho e loops desnecessários de detecção de alterações.
  • Carregamento diferencial: Removido nas versões mais recentes porque o suporte ao navegador moderno tornou obsoleta a necessidade de pacotes ES5/ES2015+ separados.

Problemas conhecidos e soluções alternativas comuns

  • Erros de tipo após ativar o modo estrito: habilite-o gradualmente arquivo por arquivo com // @ts-strict-ignore temporário em vez de bloquear toda a atualização.
  • Bibliotecas de terceiros desatualizadas: Verifique primeiro com npm desatualizado e considere bifurcações ou patches temporários via patch-package se a biblioteca for abandonada.
  • Conflito de dependência de pares com --force: Sempre documente por que isso foi necessário, para não perder o controle da dívida técnica oculta.
  • @for sem track: novo fluxo de controle requer track obrigatório, um erro de compilação comum ao migrar de *ngFor.

Lista de verificação de pré-atualização

  • Ramo dedicado para atualização, nunca diretamente no principal.
  • Cobertura de teste existente medida como linha de base antes de iniciar.
  • Limpe o rastreador de problemas: nenhum bug conhecido já aberto que possa ser confundido com uma regressão de atualização.
  • Tag Backup/Git da versão de trabalho atual, pronta para reversão imediata.

Lista de verificação de reversão

  • Tag Git da versão pré-atualização sempre criada antes de iniciar (git tag pre-upgrade-v10).
  • package-lock.json confirmado em cada etapa, para restaurar o gráfico de dependência anterior exato.
  • Pipeline CI/CD capaz de implantar a versão anterior marcada sem alterações manuais.
  • Se o projeto tiver migrações de dados vinculadas a um recurso da nova versão, verifique se elas são reversíveis antes de implantar.

Plano Operacional de 30/60/90 dias

Dias 1-30: Angular 10 → 14

  • Atualização sequencial 10→11→12→13→14 na filial dedicada — KPI: construção verde em cada etapa, 0 regressões funcionais conhecidas.
  • Remoção de rxjs-compat e ViewEngine residual — KPI: 0 avisos de descontinuação em build.

Dias 31-60: Angular 15 → 18

  • Adoção de componentes independentes em novos módulos, migração E2E para Cypress — KPI: 0 testes residuais do transferidor.
  • Atualização sequencial 15→16→17→18, adoção de novo fluxo de controle nos templates mais visitados — KPI: tempo de construção reduzido medido antes/depois.

Dias 61-90: Angular 19 → 21

  • Atualização final até a versão de destino, verificada em relação à documentação oficial em cada etapa — KPI: taxa de aprovação de construção e teste de 100% na versão final.
  • Avaliação Zoneless/Signals nos componentes de maior tráfego — KPI: tamanho final do pacote em comparação com a linha de base pré-atualização.

Estudo de caso 1: aplicativo empresarial com Monorepo Nx

Um aplicativo corporativo no monorepo Nx (8 bibliotecas internas compartilhadas, Angular 10) foi concluído atualizando para Angular 18 em 14 semanas com 1,5 desenvolvedores dedicados (~420 horas-pessoa totais). Principais problemas: 3 bibliotecas de terceiros sem suporte nativo ao Ivy, corrigidas com ngcc forçado até Angular 12 e subsequente substituição por alternativas retidas. Resultado: pacote inicial reduzido em 28% (componentes autônomos + esbuild), tempo de construção de CI reduzido de 9 para 3 minutos.

Estudo de caso 2: E-commerce com material angular

Um site de comércio eletrônico com forte dependência de Angular Material (Angular 11) concluiu a atualização para Angular 17 em 8 semanas com 2 desenvolvedores em meio período (~180 horas-pessoa). A transição para o Material 3 (baseado em MDC) exigia uma auditoria visual completa dos componentes com estilo personalizado, o mais problemático caro de toda a migração. Resultado: 12 bugs de layout latentes corrigidos durante a auditoria, O tempo para interação melhorou 22% graças ao novo fluxo de controle e @defer ativado widgets acima da dobra não críticos.

FAQ

Você pode pular uma versão principal ao atualizar?

Não recomendado: ng update aplique esquemas de migração específicos para cada principal, pulando um corre o risco de transformações de código incompletas.

Quanto tempo leva em média uma atualização do Angular 10 para 21?

Depende muito do tamanho do projeto e das bibliotecas de terceiros envolvidas; Projetos empresariais reais normalmente requerem de 2 a 4 meses com esforço dedicado parcial.

Você precisa reescrever todos os componentes independentes?

Não, autônomo e NgModule podem coexistir por um longo tempo; a migração pode ser bem-vinda e oportunista em módulos tocados por outros motivos.

O que fazer se uma biblioteca de terceiros não suportar a nova especialização?

Verifique as alternativas mantidas, considere uma bifurcação temporária com patches mínimos ou isole a biblioteca atrás de um adaptador para substituí-la mais facilmente no futuro.

ng update --force é seguro?

Somente após verificar manualmente se as bibliotecas afetadas ainda funcionam; não é um sinalizador a ser usado como padrão automático.

O Zone.js deve ser removido imediatamente?

Não, zoneless ainda está evoluindo em versões mais recentes; considere a remoção somente após uma auditoria completa dos componentes que dependem implicitamente do resumo automático.

Como ocorrem as vulnerabilidades de segurança durante a atualização?

Com auditoria npm em cada etapa e, para projetos empresariais, um scanner dedicado como o Snyk integrado ao CI.

Você realmente precisa migrar do Karma para o Jest?

Não, o Karma permanece suportado por mais tempo; Jest é uma opção para acelerar o IC, não um requisito obrigatório para novos cursos.

O que acontece com os testes do Transferidor existentes?

Eles devem ser substituídos por Cypress ou Playwright, independentemente da versão de destino, pois o Protractor está obsoleto pela própria equipe Angular.

Como você estima o esforço de uma atualização multi-grande?

Somando o esforço para cada principal (construção, correção de alterações significativas, teste) mais um buffer para bibliotecas de terceiros não atualizadas, normalmente o maior risco.

É necessário atualizar o Node com cada especialização Angular?

Nem sempre para todos os cursos, mas deve ser verificado na matriz de compatibilidade: alguns cursos aumentam o requisito mínimo de Node.

É melhor atualizar em um PR grande ou em vários PR pequenos?

Muitos PRs pequenos, um para a versão principal, para isolar o risco e facilitar a reversão de uma única etapa em caso de regressão.

Erros comuns a serem evitados

  • Pular a versão principal para "fazer primeiro": os esquemas de migração devem ser aplicados sequencialmente, pular um causa transformações incompletas.
  • Não leia o changelog de cada principal: algumas alterações importantes não possuem um esquema automático e requerem intervenção manual.
  • Ignorar avisos de descontinuação: eles se tornam erros de bloqueio no próximo grande, é melhor resolvê-los quando ainda são apenas avisos.
  • --force usado sem verificação: Oculta incompatibilidades reais que surgem posteriormente na produção.
  • Não atualize o Node no CI antes do código de localidade - causa compilações que funcionam apenas em uma máquina.
  • Atraso na remoção de rxjs-compat: oculta descontinuações de RxJS que o compilador reportaria de outra forma.
  • Nenhuma tag Git antes de iniciar a atualização: Torna a reversão muito mais lenta e arriscada em caso de regressão.
  • Testes E2E no Transferidor mantidos "por enquanto": O Transferidor está obsoleto, cada mês de atraso na migração aumenta a dívida técnica.
  • Ative o modo estrito TypeScript em todo o projeto de uma só vez: gere centenas de erros simultâneos, de preferência módulo por módulo.
  • Não medir o tamanho do pacote antes/depois: sem uma linha de base, não é possível verificar se a atualização realmente trouxe os benefícios de desempenho esperados.
  • Atualizar bibliotecas monorepo internas após aplicativos de consumo: causa incompatibilidades temporárias, a ordem correta é sempre as bibliotecas primeiro, os aplicativos depois.
  • Nenhum plano de reversão para pipelines de CI/CD: Uma atualização que interrompe a construção de produção sem um caminho de reversão rápido transforma um problema técnico em um incidente.

Como verificar

  • Verifique a versão atual e disponível: ng version e npm view @angular/coreversões.
  • Faça um teste antes de cada atualização real: ng update @angular/core@X --dry-run.
  • Verifique as vulnerabilidades após cada etapa: auditoria npm.
  • Verifique a compilação de produção: ng build --configuration production.
  • Execute todo o conjunto de testes: npm test -- --watch=false e o conjunto E2E Cypress.
  • Meça o tamanho do pacote antes/depois com npx webpack-bundle-analyzer ou saída de compilação Angular CLI.

Conclusão

Uma atualização do Angular 10 para o 21 não é um evento único, mas um programa de vários meses com onze etapas sequencial, cada um com seus próprios riscos e benefícios. O padrão que funciona na prática é sempre o mesmo: um importante de cada vez, ng update seguido por versões verdes e testes antes prossiga, tags Git em cada etapa para reversão rápida e verificação sistemática de documentação oficial para versões mais recentes onde os detalhes ainda não estão consolidados no memória coletiva da equipe.

Você deseja um plano de migração detalhado para seu projeto específico ou uma avaliação do esforço necessário? Solicite uma auditoria técnica: em poucas horas de análise da base de código é Você pode estimar tempos, principais riscos e bibliotecas de terceiros para monitorar durante a atualização.

💬 Notas dos leitores

0 notas

Escreva uma nota

Partilhe a sua opinião, uma sugestão ou um elogio

Notas recentes

Ainda não há notas. Seja o primeiro a comentar!