DEV Community

Cover image for El cambio declarativo de Angular

El cambio declarativo de Angular

Cómo la Nueva Estructura de Carpetas lo Cambia Todo

Si no has actualizado a la versión 20, la primera y segunda parte de esta guía te pueden ayudar a comprender qué cambia y actualizar.

Parte 1: La actualización en Sí Misma 🛠️

Primero, resolvamos lo básico. Antes de ejecutar cualquier comando, asegúrate de que tu entorno esté listo.

Prerrequisitos

  • Node.js: v20.11.1 o posterior.
  • TypeScript: v5.8 o posterior.
  • **Copia de seguridad del proyecto: Asegúrate de confirmar todos tus cambios actuales en Git. En serio.

El Comando de Actualización

Una vez que hayas confirmado tu versión de Node.js, ejecuta el comando que se ajuste a tu proyecto.

Para un proyecto estándar de Angular:

ng update @angular/cli @angular/core 
Enter fullscreen mode Exit fullscreen mode

Si utilizas Angular Material:

ng update @angular/cli @angular/core @angular/material 
Enter fullscreen mode Exit fullscreen mode

El proceso de actualización se ejecutará, pero es probable que te encuentres con tu primer obstáculo de inmediato.

Parte 2: Lo que se rompe inmediatamente 🛑

A diferencia de las actualizaciones anteriores, Angular 20 introduce un cambio significativo que detendrá tu compilación.

1. La Historia Completa Detrás de la Eliminación de Karma

Lo primero que notarás es que ng test fallará. Esto no es solo un error; es un cambio fundamental en las herramientas de compilación de Angular. Con Angular 20, el paquete de compilación predeterminado cambia de @angular-devkit/build-angular al nuevo @angular/build. Este nuevo paquete no incluye Karma. El ecosistema web ha avanzado hacia ejecutores de pruebas más rápidos y modernos como Vitest y Jest, y Karma se había convertido en un cuello de botella.

La solución temporal:

Para que tus pruebas se ejecuten sin migrar todo hoy, debes reinstalar manualmente la antigua herramienta de compilación. Esto obliga a la CLI a usar el antiguo compilador que aún es compatible con Karma.

npm install @angular-devkit/build-angular --save-dev 
Enter fullscreen mode Exit fullscreen mode

Este es un puente de compatibilidad. El mensaje del equipo de Angular es claro: comienza a planificar tu migración a Jest o Vitest pronto.

2. browserslist y soporte de Navegadores

Aquí hay un detalle menor que podría sorprenderte. Angular 20 oficialmente ya no es compatible con Opera. Si tienes "Opera" listado en tu archivo .browserslistrc, tu compilación puede fallar o arrojar advertencias. Quítalo para resolver el problema.

Parte 3: La Nueva Arquitectura 🏛️

Más allá de los cambios importantes, Angular 20 impulsa una arquitectura más moderna, explícita y escalable.

1. Componentes standalone por defecto.

Los nuevos proyectos generados con ng new ahora son standalone (independientes) por defecto. Esto marca un cambio arquitectónico fundamental que se aleja de los NgModules. Al listar las dependencias directamente en el array imports de un componente, cada componente se vuelve autocontenido.

¿Qué implica este cambio?:

  • Arquitectura más clara y definida: Sabes exactamente lo que necesita cada componente.
  • Mejora el *tree-shaking*: Conduce a paquetes más pequeños y optimizados.

Para migrar tus proyectos existentes, puedes ejecutar el schematic de migración standalone:

ng generate @angular/core:standalone 
Enter fullscreen mode Exit fullscreen mode

2. Una estructura de carpetas que cuenta una historia

Una buena estructura de carpetas no solo contiene archivos, sino que te dice lo que hace la aplicación. Vale la pena hacer énfasis en la guía de estilo oficial de Angular, ya que sus recomendaciones se basan en años de experiencia comunitaria. Esta filosofía, detallada en su página de referencia de estructura de archivos, a menudo se resume con el acrónimo LIFT (por sus siglas en inglés: Localizar, Identificar, Plano, Tratar de ser DRY):

  • Locate (Localiza) tu código fácilmente.
  • Identify (Identifica) lo que hace un archivo de un vistazo.
  • Flat Flat (Plano): Mantén estructura plana tanto como puedas.
  • Try to be DRY: Don't Repeat Yourself (Trata de no repetirte).

La conclusión principal es organizar por característica, no por tipo. En lugar de una carpeta components y una carpeta services, crea carpetas para características como user-profile o product-list.

Usemos un ejemplo práctico para una aplicación de comercio electrónico:

src/app/
├── core/
│   ├── auth/          # Lógica de autenticación usada en todas partes
│   │   ├── auth-store.ts
│   │   └── auth-interceptor.ts
│   └── layout/        # El shell de la aplicación: barra de navegación, pie de página
│       ├── navbar.ts
│       └── footer.ts
│
├── features/
│   ├── products/      # Todo para navegar por los productos
│   │   ├── product-list.ts
│   │   ├── product-details.ts
│   │   └── product-search.ts
│   │
│   └── cart/          # La característica del carrito de compras
│       ├── cart-store.ts
│       ├── cart-view.ts
│       └── add-to-cart.ts
│
└── shared/            # Componentes "tontos" reutilizables y utilidades
    └── ui/
        ├── button.ts
        ├── spinner.ts
        └── price.pipe.ts 
Enter fullscreen mode Exit fullscreen mode

¿Por qué funciona esto?

  1. core 🏛️ (Proporcionar una vez): Servicios y componentes que la aplicación necesita para ejecutarse, cargados solo una vez (AuthStore, Navbar).
  2. Features ✨ (Lo que hace tu aplicación): El corazón de tu aplicación. Cada carpeta es una característica autocontenida.
  3. shared ♻️ (Bloques de construcción reutilizables): Componentes "tontos", pipes y directivas que no saben nada sobre las características en las que se utilizan (Button, Spinner). Son importados por los módulos de características.

3. La Nueva Convención de Nombres

Angular 20 introduce una nueva convención oficial de nombres que elimina los sufijos tradicionales como .component.ts o .service.ts.

Nomenclatura Antigua Nueva Nomenclatura Intención
user-profile.component.ts user-profile.ts Componente de Interfaz de Usuario
auth.service.ts auth-store.ts Gestión de estado
highlight.directive.ts highlight.ts Directiva
user-api.service.ts user-api.ts Cliente HTTP

El objetivo es centrarse en la intención del archivo en lugar de su tipo técnico. Una clase que maneja el estado es un "store" (almacén), y una que realiza peticiones HTTP es una "api". Esto hace que el propósito de tu código sea mucho más claro, especialmente en una estructura de carpetas basada en características.

Parte 4: Las nuevas herramientas y sintaxis 🚀

Finalmente, veamos las nuevas herramientas que mejorarán tu desarrollo diario.

1. El flujo de control es más que syntactic sugar (azúcar sintáctico).

El nuevo bloque @for reemplaza a *ngFor y es una mejora importante.

Sintaxis antigua:

<div *ngFor="let item of items; trackBy: trackItemById">
  {{ item.name }}
</div> 
Enter fullscreen mode Exit fullscreen mode

Nueva sintaxis:

@for (item of items; track item.id) {
  <div>{{ item.name }}</div>
} @empty {
  <div>No hay elementos para mostrar.</div>
} 
Enter fullscreen mode Exit fullscreen mode

Mejoras clave:

  • track es obligatorio, lo que impone una mejor práctica de rendimiento que a menudo se olvidaba.
  • El bloque @empty incorporado limpia las plantillas al eliminar la necesidad de un *ngIf separado.

Puedes usar la CLI para refactorizar automáticamente tus plantillas:

ng generate @angular/core:control-flow 
Enter fullscreen mode Exit fullscreen mode

2. Zoneless: Escapando de la "magia de la detección de cambios".

Aunque todavía es experimental, el camino hacia un Angular sin zonas (zoneless) se está volviendo más claro. En un mundo sin zonas, la interfaz de usuario solo se actualiza cuando se lo indicas explícitamente.

Los signals (señales) son la herramienta principal para esto.

mySignal.set(newValue); 
Enter fullscreen mode Exit fullscreen mode

Esta línea le indica directamente a Angular que actualice solo las partes específicas del DOM que dependen de esa señal. Es un enfoque quirúrgico, predecible y de alto rendimiento que elimina la sobrecarga y la imprevisibilidad de Zone.js.

Conclusión

Angular 20 es una versión significativa. La actualización requiere intervención manual para las pruebas, pero impulsa el framework hacia un futuro más moderno, explícito y de alto rendimiento. Al adoptar componentes standalone, una arquitectura basada en características y el nuevo flujo de control, no solo estás actualizando, sino que estás preparando tu aplicación para la próxima era del desarrollo web.

Top comments (0)