驴Qu茅 trae nuevo Angular 17 馃挒? Novedades, instalar y migrar

Publicado el 11.11.2023 a las 00:24

驴Qu茅 trae nuevo Angular 17 馃挒? Novedades, instalar y migrar

  1. 驴Novedades de la versi贸n 17 de Angular? 馃挘

    • Bienvenido SSR a Angular 馃槏

    • Compiladores en Angular 17

    • 驴C贸mo eligo el compilador en Angular 17?

    • 驴C贸mo configuro el SSR?

    • Nueva sintaxis if else

    • Nueva sintaxis switch

    • Nueva sintaxis for

    • Vistas diferidas o defer views (lazy loading)

    • Defer triggers en Angular 17

    • Migrar a la nueva sintaxis autom谩ticamente

    • Nueva web y documentaci贸n

  2. 驴C贸mo sabemos con qu茅 versi贸n de Angular estamos trabajando?

    • Con el package.json

    • Ejecutando la aplicaci贸n

    • Con el CLI

  3. 驴C贸mo actualizar/migrar a Angular 17?

  4. Actualizar Angular CLI globalmente

  5. Posibles errores

    • Package '@angular/core' is not a dependency

  6. Cuando todo falla

驴Qu茅 trae nuevo Angular 17 馃挒? Novedades, instalar y migrar

Esta semana han liberado la versi贸n 17 de Angular, y si me gust贸 la 16 te adelanto que la 17 es una locura 馃挘. Te cuento c贸mo instalar la versi贸n 17, c贸mo migrar tus proyectos de la versi贸n 16 a la 17 y la novedades de la versi贸n 17 de Angular


Hac铆a mucho tiempo que no me encontraba ansioso por programar y la nueva versi贸n de Angular, la 17, ha conseguido que me vuelva esa pasi贸n 馃挊


驴No me crees? Estoy escribiendo este art铆culo y probando la versi贸n 17 de Angular un viernes por la noche.

Como dec铆a mi abuelo...

Para muestra, un bot贸n

Me gusta mucho programar, un pasatiempo que tengo es resolver peque帽os ejercicios de algoritmia tipo advent of code.


Cuando me tocaba programar con Angular hab铆a cosillas que se me atravesaban.

Esta nueva versi贸n ha conseguido que todas esas cosillas que me molestaban dejen de estar 馃く


驴C贸mo Angular sab铆a lo que me molestaba?


Angular nos hizo una encuesta a su comunidad y por lo visto... lo que a m铆 me molestaba tambi茅n le molestaba a la mayor铆a.


Te cuento 馃憞

驴Qu茅 trae nuevo Angular 17?

Si en mi art铆culo de Angular 16 te dec铆a que era la versi贸n de Angular que m谩s ilusi贸n me hac铆a...

Imagen del art铆culo

Angular 16, una super versi贸n 馃Ω鈥嶁檪锔

驴Por qu茅 para m铆 Angular 16 es una super versi贸n?, 驴Quieres instalar Angular 16?, 驴quieres actualizar o migrar a Angular 16?, 驴quieres saber qu茅 trae esta s煤per versi贸n de Angular?

En este art铆culo te digo que la versi贸n que m谩s ilusi贸n me ha hecho de Angular hasta ahora sin ninguna duda es la 17 馃挒


Vamos al l铆o 馃У

Bienvenido SSR a Angular 馃槏

Hasta ahora Angular utilizaba Webpack para compilar, s贸lo Webpack.


En la versi贸n 16 ya pod铆amos usar el compilador browser-esbuild que utilizaba VITEJS lo que nos otrogaba un mayor rendimiento en nuestras aplicaciones de Angular pero... no ten铆a server side rendering (SSR) 馃槧


Browser-esbuild es compatible con Webpack.


Antes de entrar a fondo con el SSR necesito que comprendas los compiladores que utiliza Angular.

Compiladores en Angular 17

En la versi贸n 17 tendremos dos compiladores nuevos, el dev-server y el application


En realidad el dev-server es un browser-esbuild tuneado que tiene retrocompatibilidad con los compilares anteriores.


El nuevo compilador application que S脥 TIENE SSR 馃く馃挘


El compilador application ser谩 el que utilice Angular 17 por defecto.


Antes de explicarte c贸mo configurar tu aplicaci贸n para que tenga SSR te tengo que explicar c贸mo configurar en tu aplicaci贸n Angular que compile con application, si no, no ser谩 posible.


RECOMENDACI脫N: si vas a crear un proyecto desde cero y quieres que tenga SSR utiliza el comando ng new --ssr y Angular configurar谩 todo por ti 馃槏

驴C贸mo eligo el compilador en Angular 17?

Es est煤pidante sencillo:

  1. Abres tu fichero angular.json
  2. Buscas el campo architect
  3. Dentro buscas el campo build
  4. Y en el campo builder escribes cu谩l quieres

    • browser
    • browser-esbuild
    • application
builder browser en angular.json con angular 17

Para elegir el compilador application adem谩s tienes que cambiar el campo main de options por un campo que se llamar谩 browser

a帽adiendo builder application en angular.json con angular 17

驴C贸mo configuro el SSR en Angular 17?

No me voy a entretener en explicarte c贸mo se hac铆a antes, es muy tarde.

Te voy a contar c贸mo se hace a partir de ahora con Angular 17 que me resulta incre铆blemente r谩pido.


Lo 煤nico que tienes que hacer es a帽adir un nuevo campo que se llamar谩 ssr a las options del build de tu angular.json y cuyo valor ser谩 el siguiente objeto "entry":"server.ts" 馃く


Sencillamente fant谩stico

a帽adiendo ssr en angular.json con angular 17

Listo, ya tendr铆as SSR 馃敟

Nueva sintaxis en Angular 17 para el if else

La sintaxis de Angular es una de las cosillas que no me terminaba de gustar.


De hecho, creo que es lo que al principio m谩s inclina la curva de aprendizaje de Angular, que su sintaxis no es muy intuitiva.


Por ejemplo, para hacer un simple if en el template ten铆as que saber qu茅 era una directiva estructural, en este caso el *ngIf, despu茅s c贸mo referenciar a una plantilla (un ng-template usando el #)... uf... es de locos la cantidad de cosas que tienes que saber para hacer un simple if else en el HTML


De la forma tradicional ser铆a:

<div *ngIf="producto; else no_hay_producto">Renderizo el producto</div>

<ng-template #no_hay_producto>Renderizo que no hay producto</ng-template>
      

Ahora Angular apuesta por una forma m谩s declarativa.


Con la nueva sint谩xis 馃槏

@if (producto) 
  { Renderizo el producto }
  @else 
  { Renderizo que no hay producto }
      

Para el *ngFor y el *ngSwitch era otro drama.

Nueva sintaxis en Angular 17 para el switch

De la forma tradicional ser铆a:

<div [ngSwitch]="mostrar_imagen_producto">
  <div *ngSwitchCase="1">Imagen 1</div>
  <div *ngSwitchCase="2">Imagen 2</div>
  <div *ngSwitchDefault>Imagen default</div>
      

Con la nueva sint谩xis 馃槏

@switch (mostrar_imagen_producto) 
  @case 1: {Imagen 1}
  @case 2: {Imagen 2}
  @default: {Imagen default}
      

Nueva sintaxis en Angular 17 para el for

Con la nueva sint谩xis 馃槏

@for (producto of productos; track producto.id) {
  <div>{ { producto.nombre } }</div>
} @empty } 馃憟// si el array est谩 vac铆o
  La lista de productos est谩 vac铆a
}
      

Lo m谩s importante es c贸mo se declara ahora el trackBy.

De hecho, lo que m谩s destacar铆a es que ahora es obligatorio declararlo, porque antes no, y si no lo hac铆as ten铆a un impacto en el rendimiento de la aplicaci贸n muy serio.


El motivo es que el trackBy es como la key de una tabla de hash, identificada de forma 煤nica y sin error a cada item.


Si no declaramos el trackBy y por ejemplo, eliminar un item, tendr铆amos que volver a recorrer todo el array para ver qu茅 item se ha eliminado.

Creo que se entiende.

Vistas diferidas o defer views o vista aplazable (lazy loading) en Angular 17

Imagina que quieres renderizar din谩micamente y condicionalmente un componente, por ejemplo, una lista de productos.

Pero adem谩s, hacerlo s贸lo cuando el scroll de la p谩gina llegue a la lista de productos usando el interceptor observer o lo que viene siendo lo mismo, una carga de componentes diferida (de ah铆 el t茅rmino defer) o lazy loading.

Ahora se puede... y muy simple 馃拑


Adem谩s, mientras se est谩 cargando la lista que se renderize un loading y si falla la petici贸n al servidor que cargue un template de error 馃槱


Me da pereza escribir c贸mo se hac铆a hasta ahora, as铆 que directamente te digo c贸mo se hace a partir la versi贸n 17

<div #mi_componente> 
  @defer (on viewport(mi_componente); prefetch on idle) { //lazy loading a nivel de componente
    <lista_productos/>
  } <loading {
    mi_loading
  } <error {
    Fall贸 la carga de la lista 
  }
</div>
        

Con esto se consigue que los componentes se carguen de forma granular, es decir, que s贸lo se cargar谩n cuando se muestren en pantalla.


Me suena de algo... QuickJS? 馃し鈥嶁檧锔


En la versi贸n 17 de Angular conseguimos hacer una carga diferida de componentes.

Hasta ahora, s贸lo la pod铆amos hacer de m贸dulos.

Si no sabes lo que es el lazy loading de los m贸dulos de Angular te dejo un art铆culo en el que te digo qu茅 es y c贸mo se hace.

Imagen del art铆culo

Lazy loading en Angular

En este art铆culo te cuento c贸mo realizar lazy load o carga as铆ncrona, diferida o perezosa con Angular


Defer triggers en Angular 17

Las palabras reservadas on idle en el ejemplo anterior, son un trigger o disparador y con 茅l le estamos indicando que queremos que se cargue el componente cuando el navegador no est谩 haciendo ning煤n trabajo intensivo.

Con componente me refiero a cualquier elemento HTML o componente personalizado.


Puedes usar dos tipos de triggers para indicar cuando cargar un componente aplazable.

Con when y con on


Usaremos when con alguna condici贸n, es decir, con algo que devuelva true o false.

Es similar a lo que utilizar铆amos para un @if

@defer (when mi_condicion){
  <app-mi-componente />
}
      

Por otro lado usaremos on con triggers como:

  • on idle; el componente se cargar谩 cuando el navegador no est茅 haciendo ning煤n trabajo intensivo, es decir, est茅 inactivo (idle)
  • on viewport; el componente se renderizar谩 cuando entre en el viewport, es decir, cuando sea visible por el usuario
  • on immediate; el componente se renderizar谩 sin bloquear el navegador tan pronto como el navegador finalize de renderizar la p谩gina
  • on timer(ms); el renderizado comenzar谩 despu茅s de los milisegundos que especifiques
  • on interaction; se dispara cuando el usuario interact煤a con un elemento espec铆fico haciendo clic o keydown
  • on hover; se dispara cuando el cursor del rat贸n para sobre el elemento

Te dejo aqu铆 enlace a la documentaci贸n oficial

驴C贸mo migrar autom谩ticamente a la nueva sintaxis de Angular 17?

S铆, el equipo de Angular ha pensado en todo.


En un mismo template puedes usar las directivas estructurales de Angular (*ngIf...) combinadas con la nueva sintaxis de Angular 17, pero te perder谩s las mejoras de rendimiento que implica el hacerlo todo con la nueva sintaxis.


Si quieres migrar a la nueva sintaxis autom谩ticamente usa el schematicng g @angular/core:control-flow

Nueva web y documentaci贸n para Angular 17

La nueva web de Angular est谩 chul铆sima.


Y no me refiero s贸lo a la est茅tica, que tambi茅n, si no sobre todo a que tiene un playground para hacer pruebas agilizando mucho el trabajo.

驴C贸mo sabemos con qu茅 versi贸n de Angular estamos trabajando?

Podemos ver qu茅 versi贸n de Angular es con la que estamos trabajando de las varias formas 馃搩

Con el package.json

Abriendo el package.json, en la secci贸n de las dependencias encontraremos el Angular Core y ah铆 podremos ver la versi贸n de Angular

  "@angular/animations": "~16.0.0",
  "@angular/cdk": "^16.0.3",
  "@angular/common": "~16.0.0",
  "@angular/compiler": "~16.0.0",
  "@angular/core": "~16.0.0"

Ejecutando la aplicaci贸n

Ejecutando la aplicaci贸n y en con las herramientas de depuraci贸n del navegador, podremos ver en la inspecci贸n de elementos el ng-version

<app-root _nghost-serverapp-c136="" ng-version="16.0.0">...

Con el CLI

Ejecutando el comando ng version en la consola en el directorio de trabajo, ello te facilitar谩 toda la informaci贸n de tu proyecto de Angular

驴C贸mo actualizar/migrar a Angular 17?

Voy a seguir las recomendaciones del equipo de Angular en su documentaci贸n


Para actualizar mi aplicaci贸n de Angular 16 a Angular 17 que incluye Angular Material seguir茅 los siguiente pasos:

  1. ng update @angular/core @angular/cli
  2. ng update @angular/material

Actualizar Angular CLI globalmente

Te recomiendo actualizar tu Angular CLI de manera global y as铆, cada vez que crees un proyecto nuevo lo har谩s con la 煤ltima versi贸n de Angular

    Para actualizar Angular CLI de forma global sigue los siguientes pasos:
  1. Desinstala Angular CLI

    npm uninstall -g @angular/cli
  2. Limpia el cache de npm, y as铆 cuando instalemos la nueva versi贸n de Angular CLI nos aseguramos de que est谩 limpia

    npm cache clean --force
  3. Instala la 煤ltima versi贸n estable de Angular CLI

    npm i -g @angular/cli
  4. Comprueba que se ha instalado la 煤ltima versi贸n

    ng version

Puedes encontrar m谩s informaci贸n acerca de Angular CLI en su p谩gina oficial de npm

Posibles errores

Package '@angular/core' is not a dependency

Es posible que no tengas la carpeta node_modules debido a que has clonado el repositorio. Para solventarlo instala las depencias de proyecto con:

npm install

Cuando todo falla

Cuando todo falla, el procedimiento que uso es:

  1. Crear un nuevo proyecto con el Angular CLI actualizado a la versi贸n de Angular que quiero
  2. Eliminar la carpeta node_modules
  3. Eliminar el fichero package-lock.json
  4. Modificar las dependencias de mi proyecto de Angular que quiero migrar copiando las versiones del proyecto creado nuevo
  5. Instalar dependencias con npm install

No es lo m谩s r谩pido, pero funciona.


Las depencias que te recomiendo para Angular 17 son:

  "dependencies": {
    "@angular/animations": "^17.1.0",
    "@angular/cdk": "^17.1.5",
    "@angular/common": "^17.1.0",
    "@angular/compiler": "^17.1.0",
    "@angular/core": "^17.1.0",
    "@angular/forms": "^17.1.0",
    "@angular/material": "^17.1.5",
    "@angular/platform-browser": "^17.1.0",
    "@angular/platform-browser-dynamic": "^17.1.0",
    "@angular/router": "^17.1.0",
    "rxjs": "~7.8.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.13.0"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^17.1.4",
    "@angular/cli": "~17.1.4",
    "@angular/compiler-cli": "^17.1.0",
    "@types/jasmine": "~4.3.0",
    "jasmine-core": "~4.6.0",
    "karma": "~6.4.0",
    "karma-chrome-launcher": "~3.2.0",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.1.0",
    "karma-jasmine-html-reporter": "~2.1.0",
    "typescript": "~5.1.3"
  }
              

Hasta luego 馃枛