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

Migración de Angular de v10 a v21: La guía completa versión por versión

Migrar una aplicación de Angular 10 a Angular 21 significa pasar por once versiones principales, cada uno con sus propios cambios importantes. Hacerlo de un salto nunca es una opción realista: el equipo El propio Angular recomienda actualizaciones secuenciales, una importante a la vez, utilizando ng actualización en cada pasada. Esta guía cubre todo el viaje: qué cambia en cada uno versión, los comandos exactos a ejecutar, los problemas más comunes encontrados en migraciones reales, el impacto sobre rendimiento y paquetes, y un plan operativo de 30/60/90 días para gestionar el riesgo en un proyecto empresa.

Nota importante: algunos detalles de la versión (especialmente para Angular 19, 20 y 21, el más reciente en el momento de escribir este artículo) siempre debe cotejarse con la documentación oficial antes de planificar una actualización en producción, con npm ver @angular/core versiones y versión ng en proyecto real.

Matriz de compatibilidad

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 y 21, siempre verifique los requisitos exactos antes de planificar: npm view @angular/core@21 peerDependencies devuelve las versiones mínimas requeridas actualmente de instalación, más fiable que cualquier mesa estática.

ng comandos de actualización: el patrón secuencial

# 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

El indicador --force omite las comprobaciones de compatibilidad de dependencia de pares cuando un La biblioteca de terceros aún no ha lanzado soporte para la nueva especialidad; úsela solo una vez que haya Comprobó manualmente que la biblioteca funciona de todos modos, nunca de forma predeterminada. --migrate-only ejecuta solo los esquemas de migración sin tocar las versiones del paquetes (útil para volver a ejecutar una migración específica después de una corrección manual), mientras --from/--to le permite apuntar a un rango de versión específico cuando ng update no detecta automáticamente la versión inicial correcta.

Angular 11 → 12: De View Engine a Ivy en todas partes

Descripción general y cambios importantes

  • Angular 11 (noviembre de 2020): TypeScript 4.0, seguimientos de pila más legibles, reemplazo de módulo en caliente opcional.
  • Angular 12 (mayo de 2021): Ivy se convierte en el compilador/tiempo de ejecución predeterminado también para publicar bibliotecas (formato de paquete Angular actualizado), modo estricto habilitado de forma predeterminada en proyectos nuevos, obsolescencia formal de View Engine.
  • API obsoletas: entryComponents ya no son necesarias con Ivy, relativeLinkResolution en el enrutador están obsoletas.
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: Adiós a View Engine e IE11

Descripción general y cambios importantes

  • View Engine se eliminó por completo: solo Ivy a partir de esta versión, ngcc ya no es necesario para las bibliotecas publicadas con el nuevo formato de paquete Angular.
  • Se eliminó la compatibilidad con Internet Explorer 11: si su audiencia aún incluye IE11, este es un punto importante que debe evaluar cuidadosamente.
  • Nueva API para componentes dinámicos (ViewContainerRef.createComponent sin 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 independientes en la vista previa del desarrollador

Descripción general y cambios importantes

  • Se introdujeron componentes/directivas/canalizaciones independientes (vista previa para desarrolladores, aún no recomendada para producción).
  • Formas reactivas mecanografiadas: FormControl y similares se vuelven genéricos, lo que genera errores de tipografía en el código existente que asumía any.
  • Los diagnósticos extendidos del compilador informan patrones riesgosos en plantillas que ya se encuentran en la fase de compilación.
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: Estable independiente y NgOptimizedImage

Descripción general y cambios importantes

  • La API independiente se vuelve estable y recomendada para nuevos proyectos.
  • Directiva NgOptimizedImage estable: carga diferida automática y tamaño de imagen con impacto directo en LCP.
  • Angular Material cambia a la nueva arquitectura basada en MDC (Material Design Components), con posibles diferencias visuales menores en los 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: Señales en la vista previa del desarrollador

Descripción general y cambios importantes

  • Señales introducidas en la vista previa del desarrollador: reactividad granular alternativa/complementaria a Zone.js.
  • Builder esbuild en la vista previa del desarrollador para ng build: tiempos de compilación significativamente más rápidos.
  • Entradas requeridas (@Input({ require: true })) y etiquetas de cierre automático en plantillas ().
  • Soporte experimental para Jest como corredor de prueba alternativo a 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: Nuevo flujo de control y Vite/esbuild predeterminado

Descripción general y cambios importantes

  • Nueva sintaxis de flujo de control en plantillas (@if, @for, @switch) estable, reemplaza *ngIf/*ngFor con mejor rendimiento de renderizado.
  • El constructor basado en esbuild/Vite se convierte en el predeterminado para nuevos proyectos (desarrollo de servidor drásticamente más rápido).
  • @defer para carga diferida declarativa de bloques de plantilla (vistas diferibles).
<!-- 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 y material sin zonas 3

Descripción general y cambios importantes

  • Detección experimental de cambios sin zona: capacidad de eliminar Zone.js del paquete para aplicaciones basadas en Signal.
  • Angular Material 3 (Material Design 3) estable, con nuevos diseños de tokens temáticos.
  • Reproducción de eventos para aplicaciones con SSR/hidratación: los eventos del usuario durante la hidratación ya no se pierden.
// main.ts — opt-in sperimentale a zoneless (rimuove la dipendenza da Zone.js)
bootstrapApplication(AppComponent, {
  providers: [provideExperimentalZonelessChangeDetection()],
});

Angular 19: independiente por defecto e hidratación incremental

Descripción general y cambios importantes

  • Los nuevos proyectos generados por ng new son independientes de forma predeterminada: NgModule ya no es el andamio predeterminado.
  • Hidratación incremental: hidratación selectiva de partes de la página en lugar de toda la aplicación de forma masiva, con beneficios directos en Time to Interactive.
  • Nuevas primitivas basadas en señales (linkedSignal, resource) para la recuperación de datos reactivos y de estado derivado.
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 y 21: Consulta siempre la documentación oficial

Para estas dos versiones, las más recientes al momento de escribir esta guía, los detalles exactos de Los cambios importantes y los requisitos de dependencia siempre deben confirmarse con los comandos oficiales antes. planificar la actualización: la dirección general es la consolidación de señales y sin zonas hacia el Estabilidad total, mayor reducción del paquete predeterminado y evolución continua del constructor. esbuild/Vite, pero las fechas exactas y los detalles específicos de la API deben verificarse caso por 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 a Eliminación

En proyectos iniciados desde Angular 10, es común encontrar todavía rxjs-compat instalado para Admite sintaxis con operadores concatenados previamente canalizables. Debe eliminarse lo antes posible: además de Inflar el paquete oculta desaprobaciones que, de otro modo, el compilador informaría de inmediato.

// 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

Prueba: de Karma/Protractor a Jest/Cypress

El propio equipo de Angular ha dejado de utilizar el transportador desde 2022 y debería reemplazarse independientemente Versión de destino angular. Karma permanece funcional por más tiempo, pero Jest (apoyado experimentalmente Angular 16 en adelante) ofrece tiempos de ejecución significativamente más rápidos en 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 automatización para actualizaciones secuenciales

#!/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 y pnpm Espacio de trabajo

En un monorepo con bibliotecas internas compartidas, el orden de actualización importa: actualizar primero bibliotecas compartidas (verificando que cada peerDependencies declare un rango compatible con la nueva especialidad), vuelva a compilarlos y luego actualice las aplicaciones de consumo. Con Nx, nx migra Latest organiza automáticamente este orden para los paquetes administrados por el espacio de trabajo.

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

CI/CD: Actualización de canalizaciones

# 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

Actualice siempre la versión del nodo en proceso antes ejecutando ng update localmente: una falta de coincidencia entre el nodo local y el nodo CI es una causa frecuente de "funciona en mi computadora" durante las actualizaciones.

Impacto en el rendimiento y el paquete

  • Ivy vs View Engine: paquetes más pequeños en promedio y agitación de árboles más efectiva desde la transición a Ivy (Angular 9-13).
  • Eliminación de ngcc: compilaciones más rápidas después de Angular 13, cuando todas las bibliotecas se publican en el formato de paquete nativo Angular Ivy.
  • esbuild/Vite: reduce drásticamente los tiempos de compilación y desarrollo del servidor en comparación con el constructor de paquetes web heredado, comenzando en Angular 16-17.
  • Componentes independientes: elimina el texto estándar de NgModules y mejora la agitación de árboles de grano fino por componente.
  • Signals y Zoneless: Posible eliminación de Zone.js del paquete final, lo que resulta en una reducción de tamaño y bucles de detección de cambios innecesarios.
  • Carga diferencial: eliminado en versiones más recientes porque la compatibilidad con navegadores modernos ha dejado obsoleta la necesidad de paquetes ES5/ES2015+ separados.

Problemas conocidos y soluciones comunes

  • Errores de tipo después de habilitar el modo estricto: habilítelo gradualmente archivo por archivo con // @ts-strict-ignore temporal en lugar de bloquear toda la actualización.
  • Bibliotecas de terceros obsoletas: verifique primero con npm obsoleto y considere bifurcaciones o parches temporales a través de patch-package si la biblioteca está abandonada.
  • Conflicto de dependencia entre pares con --force: documente siempre por qué fue necesario, para no perder de vista la deuda técnica oculta.
  • @for sin track: el nuevo flujo de control requiere track obligatorio, un error de compilación común al migrar desde *ngPara.

Lista de verificación previa a la actualización

  • Rama dedicada para actualización, nunca directamente en principal.
  • Cobertura de prueba existente medida como punto de referencia antes de comenzar.
  • Rastreador de problemas limpios: ya no se han abierto errores conocidos que puedan confundirse con una regresión de actualización.
  • Etiqueta Backup/Git de la versión de trabajo actual, lista para reversión inmediata.

Lista de verificación de reversión

  • La etiqueta Git de la versión previa a la actualización siempre se crea antes de comenzar (etiqueta git pre-upgrade-v10).
  • package-lock.json confirmado en cada paso, para restaurar exactamente el gráfico de dependencia anterior.
  • Canalización de CI/CD capaz de implementar la versión etiquetada anterior sin cambios manuales.
  • Si el proyecto tiene migraciones de datos vinculadas a una función en la nueva versión, verifique que sean reversibles antes de implementarlas.

Plan operativo de 30/60/90 días

Días 1-30: Angular 10 → 14

  • Actualización secuencial 10→11→12→13→14 en rama dedicada — KPI: construcción ecológica en cada paso, 0 regresiones funcionales conocidas.
  • Eliminación de rxjs-compat y ViewEngine residual — KPI: 0 advertencias de desuso en la compilación.

Días 31-60: Angular 15 → 18

  • Adopción de componentes independientes en nuevos módulos, migración E2E a Cypress — KPI: 0 pruebas de transportador residuales.
  • Actualización secuencial 15→16→17→18, adopción de un nuevo flujo de control en las plantillas más visitadas — KPI: tiempo de construcción reducido medido antes/después.

Días 61-90: Angular 19 → 21

  • Actualización final hasta la versión de destino, verificada con la documentación oficial en cada paso: KPI: tasa de aprobación de compilación y prueba al 100% en la versión final.
  • Evaluación de señales/zonas en los componentes de mayor tráfico: KPI: tamaño del paquete final en comparación con la línea base previa a la actualización.

Estudio de caso 1: Aplicación empresarial con Monorepo Nx

Se ha completado una aplicación empresarial en monorepo Nx (8 bibliotecas internas compartidas, Angular 10) actualización a Angular 18 en 14 semanas con 1,5 desarrolladores dedicados (~420 horas persona totales). Problemas principales: 3 bibliotecas de terceros sin soporte nativo de Ivy, solucionadas con ngcc forzó hasta Angular 12 y posterior reemplazo con alternativas retenidas. Resultado: paquete inicial reducido en un 28 % (componentes independientes + compilación electrónica), tiempo de compilación de CI reducido de 9 a 3 minutos.

Estudio de caso 2: Comercio electrónico con Angular Material

Un sitio de comercio electrónico con gran dependencia de Angular Material (Angular 11) ha completado la actualización a Angular 17 en 8 semanas con 2 desarrolladores a tiempo parcial (~180 horas persona). La transición al Material 3 (basado en MDC) requirió una auditoría visual completa de los componentes de estilo personalizado, el mayor problema cara de toda la migración. Resultado: 12 errores de diseño latentes corregidos durante la auditoría. El tiempo de interacción mejoró un 22 % gracias al nuevo flujo de control y @defer en widgets no críticos en la mitad superior de la página.

Preguntas frecuentes

¿Puedes omitir una versión principal al actualizar?

No recomendado: ng actualización aplique esquemas de migración específicos para cada uno de los principales, omitir uno corre el riesgo de transformaciones de código incompletas.

¿Cuánto tiempo tarda en promedio una actualización de Angular 10 a 21?

Depende en gran medida del tamaño del proyecto y de las bibliotecas de terceros involucradas; Los proyectos empresariales reales suelen requerir de 2 a 4 meses con un esfuerzo dedicado parcial.

¿Necesita reescribir todos los componentes independientes?

No, el módulo independiente y NgModule pueden coexistir durante mucho tiempo; la migración puede ser bienvenida y oportunista en módulos afectados por otros motivos.

¿Qué hacer si una biblioteca de terceros no es compatible con la nueva especialidad?

Compruebe las alternativas mantenidas, considere una bifurcación temporal con parches mínimos o aísle la biblioteca detrás de un adaptador para reemplazarla más fácilmente en el futuro.

¿Es segura

ng update --force?

Solo después de verificar manualmente que las bibliotecas afectadas aún funcionan; no es una bandera que se utilice como valor predeterminado automático.

¿Se debe eliminar Zone.js inmediatamente?

No, el sistema sin zonas todavía está evolucionando en versiones más nuevas; considere la eliminación solo después de una auditoría completa de los componentes que implícitamente dependen del resumen automático.

¿Cómo ocurren las vulnerabilidades de seguridad durante la actualización?

Con npm audit en cada paso y, para proyectos empresariales, un escáner dedicado como Snyk integrado en CI.

¿Realmente necesitas migrar de Karma a Jest?

No, Karma permanece soportado por más tiempo; Jest es una opción para acelerar la CI, no un requisito obligatorio para las nuevas especialidades.

¿Qué sucede con las pruebas de transportador existentes?

Deben reemplazarse con Cypress o Playwright, independientemente de la versión de destino, porque el propio equipo de Angular desaprueba Protractor.

¿Cómo estima el esfuerzo de una actualización importante?

La suma del esfuerzo para cada uno de los principales (compilación, corrección de cambios importantes, prueba) más un búfer para bibliotecas de terceros no actualizadas, suele ser el mayor riesgo.

¿Es necesario actualizar Node con cada Angular major?

No siempre para todas las especialidades, pero se debe verificar en la matriz de compatibilidad: algunas especialidades aumentan el requisito mínimo de Node.

¿Es mejor actualizar en un PR grande o en muchos pequeños?

Muchos RP pequeños, uno para la versión principal, para aislar el riesgo y facilitar la reversión de un solo paso en caso de regresión.

Errores comunes que se deben evitar

  • Omita la versión principal para "hacerlo primero": los esquemas de migración deben aplicarse secuencialmente, omitir uno provoca transformaciones incompletas.
  • No lea el registro de cambios de cada uno de los principales: algunos cambios importantes no tienen un esquema automático y requieren intervención manual.
  • Ignora las advertencias de obsolescencia: se convierten en errores de bloqueo en el siguiente importante, es mejor resolverlos cuando todavía son solo advertencias.
  • --force usado sin verificación: Oculta incompatibilidades reales que emergen más adelante en la producción.
  • No actualice Node en CI antes del código local: provoca compilaciones que solo funcionan en una máquina.
  • Retrasar la eliminación de rxjs-compat: Ocultar las obsolescencias de RxJS que de otro modo el compilador informaría.
  • Sin etiquetas Git antes de iniciar la actualización: hace que la reversión sea mucho más lenta y riesgosa en caso de regresión.
  • Las pruebas E2E en Protractor se mantienen "por ahora": Protractor está obsoleto, cada mes de retraso en la migración aumenta la deuda técnica.
  • Habilite el modo estricto de TypeScript en todo el proyecto de una sola vez: genere cientos de errores simultáneos, preferiblemente módulo por módulo.
  • No mida el tamaño del paquete antes/después: sin una línea base, no es posible verificar si la actualización realmente trajo los beneficios de rendimiento esperados.
  • Actualizar bibliotecas internas de monorepo después de las aplicaciones de consumo: causa incompatibilidades temporales, el orden correcto es siempre las bibliotecas primero, las aplicaciones después.
  • Sin plan de reversión para canalizaciones de CI/CD: una actualización que interrumpe la compilación de producción sin una ruta de reversión rápida convierte un problema técnico en un incidente.

Cómo comprobar

  • Verifique la versión actual y disponible: ng versión y npm ver @angular/core versiones.
  • Realice un ensayo antes de cada actualización real: ng update @angular/core@X --dry-run.
  • Compruebe las vulnerabilidades después de cada paso: npm audit.
  • Compruebe la compilación de producción: ng build --configuration production.
  • Ejecute todo el conjunto de pruebas: npm test -- --watch=false y el conjunto E2E Cypress.
  • Mida el tamaño del paquete antes/después con npx webpack-bundle-analyzer o la salida de compilación de Angular CLI.

Conclusión

Una actualización de Angular 10 a 21 no es un evento único, sino un programa de varios meses con once etapas. secuencial, cada uno con sus propios riesgos y beneficios. El patrón que funciona en la práctica es siempre lo mismo: una especialidad a la vez, ng actualización seguida de versiones y pruebas ecológicas antes continuar, Git etiqueta en cada paso para una reversión rápida y una verificación sistemática de documentación oficial para versiones más recientes donde los detalles aún no están consolidados en el Memoria colectiva del equipo.

¿Quiere un plan de migración detallado para su proyecto específico o una evaluación? del esfuerzo requerido? Solicite una auditoría técnica: en unas pocas horas de análisis de la base del código es Puede estimar tiempos, riesgos clave y bibliotecas de terceros para monitorear durante la actualización.

💬 Notas de los lectores

0 notas

Escribe una nota

Comparte tu opinión, una sugerencia o un cumplido

Últimas notas

Aún no hay notas. ¡Sé el primero en comentar!