Contenido del curso

Nuevas Funcionalidades en Angular

Optimización de Rendimiento

Migración automática de @Input a signals en Angular

Resumen

Migrar tu aplicación Angular al nuevo modelo de input signals mejora la reactividad granular en runtime sin reescribir tu code base a mano. Con un solo comando, Angular analiza tus componentes y transforma cada @Input en un signal input, ideal para equipos con proyectos grandes que buscan adoptar la nueva API sin fricción.

¿Qué gana tu app al migrar inputs a signals?

El cambio no acelera la carga inicial, pero sí afina lo que ocurre mientras la app corre. La reactividad pasa a ser más precisa: solo se actualiza lo que realmente depende de un valor, no ramas enteras del árbol de componentes.

¿Qué es un signal input? Es un input que en lugar de exponer su valor como propiedad directa, lo entrega a través de una función reactiva. Para leerlo ejecutas miInput() y Angular sabe exactamente qué partes de la vista dependen de ese valor.

Esa diferencia importa cuando tu app tiene muchos componentes anidados, listas largas o vistas que se redibujan con frecuencia. La detección de cambios deja de ser un barrido general y se vuelve quirúrgica.

¿Cómo ejecutar la migración automática de input signals?

Angular incluye una schematic dedicada que recorre tu proyecto y reemplaza cada decorador @Input() por su equivalente con input(). Solo necesitas la terminal y elegir el alcance.

El comando base es:

bash ng generate @angular/core:signal-input-migration

Al ejecutarlo, la CLI te pregunta sobre qué carpeta correr la migración. Tienes dos caminos claros:

  • Usar . para migrar toda la aplicación de una sola pasada.
  • Indicar una ruta específica, por ejemplo el módulo de productos, para una migración progresiva componente por componente.

Esa segunda opción es la que recomiendan muchos equipos cuando el proyecto ya está en producción. Pruebas en una carpeta, validas que todo siga funcionando, y avanzas con confianza.

¿Qué cambia exactamente en tu código tras la migración?

La schematic no solo reemplaza el decorador. Ajusta también las lecturas dentro de la clase y del template. Por ejemplo, un @Input() audioUrl!: string con required se convierte en un signal input tipado, y cada this.audioUrl pasa a ser this.audioUrl() para suscribirse al valor.

En los templates ocurre lo mismo: donde antes leías product.stock, ahora ves product().stock. Si necesitas usar ese valor varias veces en el mismo bloque, conviene apoyarte en un @let para no ejecutar la función repetidamente:

html @let data = product();

<p>{{ data.stock }}</p>

Ojo con el naming: no puedes nombrar la variable product si ya existe la función con ese nombre, por eso el ejemplo usa data.

¿Cómo distinguir signals de funciones normales en el código?

Aquí aparece una ambigüedad real. Como un signal se lee ejecutándolo, visualmente se confunde con una función plana de la clase. Leyendo message() no sabes si es un método o un signal.

¿Por qué usar el prefijo $ en signals? Es una convención no oficial que muchos equipos adoptan para identificar de un vistazo qué variables son reactivas. Viene del mundo de los observables, donde se usa el sufijo $ con la misma intención.

La idea es declarar tus signals así:

  • $counter para un signal contador.
  • $message para un signal de mensaje.
  • $product para un signal input de producto.

Con solo mirar el nombre, cualquier persona del equipo entiende que esa ejecución es una suscripción a un valor reactivo, no una llamada a un método cualquiera. La lectura del código se vuelve más declarativa.

¿Qué hacer cuando el alias choca con ESLint?

Si renombras tu input con $product, los componentes padre estarían obligados a enviar el atributo como [$product]="...". Para mantener la API limpia hacia afuera, los signal inputs aceptan un alias, de modo que el padre siga enviando [product]="..." mientras internamente lo manejas como $product.

El detalle: ESLint marca el uso de alias como mala práctica, porque permite que el nombre interno y el externo difieran arbitrariamente. Y tiene razón, podrías llamar duration por fuera y price por dentro, lo cual sería un caos.

Sin embargo, en este caso el alias cumple un propósito de legibilidad acordado por el equipo. Para desactivar la regla, la agregas en tu configuración de ESLint con valor "off" y documentas el porqué. Romper una regla está bien cuando sabes exactamente cuál rompes y por qué lo haces.

Si tu equipo ya migró a signal inputs, cuéntame en los comentarios qué convención de naming adoptaron y cómo les fue con la migración progresiva.