Listado de la etiqueta: vitest

Guía práctica: cómo migré un proyecto de Angular 19/20 a Angular 21.2 sin morir en el intento

Migrar un proyecto Angular de v19/20 a v21 puede sonar intimidante. En la práctica, si seguís el proceso correcto, es incremental: cada paso es reversible y el proyecto sigue funcionando en todo momento. Esta es la guía que apliqué en proyectos reales.

Antes de empezar: el inventario

# Ver versión actual y dependencias desactualizadas
ng version
ng update

# Verificar compatibilidad antes de actualizar
npx npm-check-updates -u --target minor

Paso 1: Actualizar el core

# Siempre de a una versión mayor a la vez
# Si estás en v19, primero actualizar a v20, luego a v21

# De v20 a v21:
ng update @angular/core@21 @angular/cli@21

# El comando aplica schematics automáticos:
# - Actualiza imports deprecated
# - Adapta APIs que cambiaron
# - Avisa sobre cambios manuales necesarios

# Verificar que compila
ng build --configuration production

Paso 2: Adoptar Zoneless

// app.config.ts
import { provideZonelessChangeDetection } from '@angular/core';

export const appConfig: ApplicationConfig = {
  providers: [
    provideZonelessChangeDetection(),
    provideRouter(routes)
  ]
};

// angular.json: "polyfills": []  // eliminar zone.js
// npm uninstall zone.js

Paso 3: Migrar de Karma a Vitest

ng generate @angular/build:vitest
ng test  # verificar que los tests pasan
npm uninstall karma karma-chrome-launcher karma-coverage karma-jasmine karma-jasmine-html-reporter

Paso 4: Standalone components

# Angular 21 asume standalone por defecto
# Migración automática:
ng generate @angular/core:standalone --mode=convert-to-standalone
ng generate @angular/core:standalone --mode=prune-ng-modules
ng generate @angular/core:standalone --mode=standalone-bootstrap

Checklist completo

PasoAcciónObligatorio
1ng update @angular/core@21 @angular/cli@21✅ Sí
2Verificar que la app compila y los tests pasan✅ Sí
3Activar provideZonelessChangeDetection()Recomendado
4Eliminar Zone.js de polyfillsCon paso 3
5Migrar a VitestRecomendado
6Nuevos formularios con Signal FormsGradual
7Componentes de nav con funciones standalone del RouterGradual
8Configurar ng mcp para integración con IAOpcional

Errores comunes y cómo resolverlos

// ERROR: El componente no se actualiza después de activar Zoneless
// → Convertir estado a Signals o llamar markForCheck()

// ERROR: Tests fallan con "No current Angular test" después de Vitest
// → Verificar imports de @angular/core/testing

// ERROR: "Cannot find module zone.js"
// → Buscar y eliminar import 'zone.js' en el proyecto:
// grep -r "import 'zone.js'" src/

// ERROR: ExpressionChangedAfterItHasBeenCheckedError en Zoneless
// → Usar signal.update() o signal.set() en lugar de mutación directa

Mi experiencia: cuánto tardó la migración

En un proyecto de tamaño medio (45 componentes, 12 servicios, 80 tests): el ng update tardó 10 minutos. Revisar avisos y corregir deprecaciones: media jornada. Migración a Zoneless con todos los tests adaptados a Vitest: un día. Adopción gradual de Signal Forms en los formularios principales: dos semanas, a medida que tocábamos cada módulo.

No es un proceso de un fin de semana, pero tampoco es una reescritura. Es una evolución incremental que podés hacer en paralelo con el trabajo normal del equipo.


Artículo anterior: Router Signals en Angular 21: navegación standalone sin cargar todo el Router | Fin de la Serie Angular 20 → 21.2

¿Tenés preguntas sobre la migración en tu proyecto específico? Dejá tu caso en los comentarios. 👇

Vitest reemplaza a Karma y Angular habla con tu IA: el nuevo ecosistema de herramientas

Karma murió. No es una exageración: Angular 21 lo retiró como runner por defecto y lo reemplazó con Vitest. Y junto con eso llegó algo que no esperaba: soporte nativo para que asistentes de IA entiendan la estructura de un proyecto Angular en tiempo real con el protocolo MCP.

Por qué Karma quedó obsoleto

Karma fue el runner de tests de Angular durante más de una década. Abre un browser real, corre los tests ahí y reporta los resultados. Funcional, pero lento, difícil de configurar en CI y sin soporte nativo para el modelo Zoneless. En el mundo actual de testing, donde queremos ejecución rápida y paralela, Karma no competía.

Vitest: el nuevo estándar

  • Ejecución en paralelo: múltiples workers, tests más rápidos
  • Sin browser real: usa jsdom o happy-dom — más rápido y estable en CI
  • Soporte nativo Zoneless: sin el overhead de Zone.js en los tests
  • Watch mode inteligente: solo re-ejecuta los tests afectados por cambios
  • API compatible con Jest: si venís de Jest, la curva es mínima
# Configurar Vitest en un proyecto Angular 21 existente
ng generate @angular/build:vitest

# O en angular.json
{
  "test": {
    "builder": "@angular/build:unit-test",
    "options": {
      "runner": "vitest"
    }
  }
}

Tests con Vitest + Signals

import { TestBed } from '@angular/core/testing';
import { provideZonelessChangeDetection } from '@angular/core';
import { describe, it, expect } from 'vitest';
import { ContadorComponent } from './contador.component';

describe('ContadorComponent', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ContadorComponent],
      providers: [provideZonelessChangeDetection()]
    });
  });

  it('debería incrementar el contador', () => {
    const fixture = TestBed.createComponent(ContadorComponent);
    const comp = fixture.componentInstance;

    expect(comp.contador()).toBe(0);
    comp.incrementar();
    // Sin detectChanges() manual — Signals actualizan sincrónicamente
    expect(comp.contador()).toBe(1);
    expect(comp.doble()).toBe(2);
  });

  it('debería renderizar el valor actualizado', async () => {
    const fixture = TestBed.createComponent(ContadorComponent);
    fixture.detectChanges();

    const button = fixture.nativeElement.querySelector('button');
    button.click();

    await fixture.whenStable();
    expect(fixture.nativeElement.querySelector('p').textContent).toContain('1');
  });
});

ng mcp: Angular habla con tu IA

La feature que más me sorprendió de Angular 21.2: soporte nativo para el Model Context Protocol (MCP). Con un solo comando, Angular expone la estructura del proyecto a asistentes de IA locales para que entiendan el contexto en tiempo real.

# Levantar el servidor MCP de Angular
ng mcp

# Configuración en .cursor/mcp.json o claude_desktop_config.json:
{
  "mcpServers": {
    "angular": {
      "command": "ng",
      "args": ["mcp"],
      "cwd": "/path/to/mi-proyecto-angular"
    }
  }
}

Con el servidor MCP activo, el asistente de IA tiene acceso al árbol de componentes, rutas del router, servicios y sus dependencias, grafo de Signals y configuración del proyecto. En la práctica: cuando le pedís al asistente que genere un componente, lo hace correctamente dentro del contexto de tu proyecto — no código genérico que hay que adaptar.

Migrar de Karma a Vitest

# 1. Desinstalar Karma
npm uninstall karma karma-chrome-launcher karma-jasmine karma-jasmine-html-reporter

# 2. Ejecutar el schematic de migración
ng generate @angular/build:vitest

# 3. Verificar tests
ng test

# Los tests de Jasmine son mayormente compatibles
# Solo ajustar: jasmine.SpyObj → vi.Mocked cuando sea necesario

Artículo anterior: Novedades del template en Angular 21: regex, spread, instanceof y más | Serie Angular 20 → 21.2 | Próximo: Router Signals en Angular 21: navegación standalone sin cargar todo el Router →