Angular 15 ya disponible
Tags: angular, frontend, spanish, news
Published: 2022-11-17 00:26:38

Traducción del artículo del [Angular Blog:](https://blog.angular.io/angular-v15-is-now-available-df7be7f2f4c8) 

por: [Minko Gechev](https://medium.com/@mgechev)

Durante el año pasado, Angular a pasado por muchos cambios como ser el deprecar el soporte al compilador legacy o el pipeline de renderizado, lo que permitió el desarrollo de una serie de mejoras en la experiencia del desarrollador en los últimos meses. **Angular v15 es la culminación de esto con docenas de mejoras que conducen a una mejor experiencia y rendimiento del desarrollador.**

## ¡Las API independientes ahora son estables!
En la v14 presentamos nuevas API independientes que permiten a los desarrolladores crear aplicaciones sin usar NgModules. Nos complace compartir que estas API se graduaron de la versión preliminar para desarrolladores y ahora forman parte de la superficie API estable. De aquí en adelante los evolucionaremos gradualmente siguiendo el versionado semántico.

Como parte de asegurarnos de que las API independientes estuvieran listas para usarse de manera estable, nos aseguramos de que los componentes independientes funcionen en Angular, y ahora funcionan completamente en HttpClient, Angular Elements, el router y más.

Las API independientes le permiten arrancar una aplicación usando un solo componente:

```typescript
import {bootstrapApplication} from  '@angular/platform-browser' ; 
import { ImageGridComponent } from './image-grid' ; 

@Component ({ 
  standalone : true , 
  selector : 'photo-gallery' , 
  imports : [ ImageGridComponent ], 
  template : ` 
    … <image-grid [images]="imageList"></image-grid> 
  ` , 
}) 
export  class  PhotoGalleryComponent { 
  // lógica del componente
 } 
bootstrapApplication(PhotoAppComponent);
```

## APIs independientes de routing y HttpClient al cual se le puede aplicar tree-shaking

¡Puede crear una aplicación de múltiples rutas utilizando las nuevas API independientes del enrutador! Para declarar la ruta raíz puedes usar lo siguiente:

```typescript
export const appRoutes: Routes = [{
  path: 'lazy',
  loadChildren: () => import('./lazy/lazy.routes')
    .then(routes => routes.lazyRoutes)
}];
```

Donde `lazyRoutes` se declaran en:

```typescript
import {Routes} from '@angular/router';

import {LazyComponent} from './lazy.component';

export const lazyRoutes: Routes = [{path: '', component: LazyComponent}];
```

y finalmente, registrar el appRoutes en la bootstrapApplication llamada:

```typescript
bootstrapApplication(AppComponent, {
  providers: [
    provideRouter(appRoutes)
  ]
});
```

¡Otro beneficio de la API provideRouter es que se puede hacer tree-shaking! Los empaquetadores pueden eliminar las funciones no utilizadas del enrutador en el momento de la compilación. En nuestras pruebas con la nueva API, descubrimos que eliminar estas funciones no utilizadas del paquete resultó en una reducción del 11 % en el tamaño del código del enrutador en el paquete de la aplicación.

## API de composición de directivas

¡La API de composición de directivas lleva la reutilización de código a otro nivel! Esta función se inspiró en la solicitud de función más popular en GitHub que solicita la funcionalidad para agregar directivas a un elemento de host.
La API de composición de directivas permite a los desarrolladores mejorar los elementos del host con directivas y equipa a Angular con una poderosa estrategia de reutilización de código, eso solo es posible gracias a nuestro compilador. La API de composición de directivas solo funciona con directivas independientes.

Veamos un ejemplo rápido:

```typescript
@Component({
  selector: 'mat-menu',
  hostDirectives: [HasColor, {
    directive: CdkMenu,
    inputs: ['cdkMenuDisabled: disabled'],
    outputs: ['cdkMenuClosed: closed']
  }]
})
class MatMenu {}
```

En el fragmento de código anterior, mejoramos `MatMenu` con dos directivas: `HasColory` `CdkMenu`. `MatMenu` reutiliza todas las entradas, salidas y la lógica asociada con `HasColors`y solo la lógica y las entradas seleccionadas de `CdkMenu`.

Esta técnica puede recordarle herencia múltiple o rasgos en algunos lenguajes de programación, con la diferencia de que tenemos un mecanismo para la resolución de conflictos de nombres y es aplicable a las primitivas de la interfaz de usuario.

## ¡La directiva de imagen ahora es estable!
Anunciamos una vista previa para desarrolladores de la directiva de imagen Angular que desarrollamos en colaboración con Chrome Aurora en v14.2.


![Image](https://cdn-images-1.medium.com/max/800/0*m6YKijbBz3y3-ypU)

¡Estamos emocionados de compartir que ahora es estable! Land's End experimentó con esta característica y observó una mejora del 75% en LCP en una prueba de laboratorio de Lighthouse.

La versión v15 también incluye algunas características nuevas para la directiva de imágenes:


- `**srcset**` de Generación automática: la directiva garantiza que se solicite una imagen del tamaño adecuado al generar el `srcset` determinado por usted. Esto puede reducir los tiempos de descarga de sus imágenes.

- **Modo de relleno [experimental]**: este modo hace que la imagen llene su contenedor principal, eliminando el requisito de declarar el ancho y el alto de la imagen. Es una herramienta útil si no conoce los tamaños de sus imágenes o si desea migrar imágenes de fondo CSS para usar la directiva.

Puede usar la `NgOptimizedImage` directiva independiente directamente en su componente o NgModule:

```typescript
importar {NgOptimizedImage} desde '@angular/common' ; 

// Incluirlo en el NgModule 
@NgModule({ 
  imports: [NgOptimizedImage], 
}) 
class  AppModule {} 
// ... o un componente independiente 
@Component({ 
  standalone: ​​true 
  imports: [NgOptimizedImage], 
}) 
class  MyStandaloneComponent {}
``` 

Para usarlo dentro de un componente, simplemente reemplacé el atributo `src` de la imagen con `ngSrc` y asegúrese de especificar el atributo `priority` para sus imágenes LCP.

Puede encontrar más información en nuestra [documentación](https://angular.io/guide/image-directive).


## Protectores de ruta funcionales (Router Guards)

Junto con las API de rutas independientes al que se puede aplicar three-shaking, trabajamos para reducir la redundancia de código en los protectores. Veamos un ejemplo donde definimos un protector que verifica si el usuario ha iniciado sesión:

```typescript
@Injectable({ providedIn: 'root' })
export class MyGuardWithDependency implements CanActivate {
  constructor(private loginService: LoginService) {}

  canActivate() {
    return this.loginService.isLoggedIn();
  }
}

const route = {
  path: 'somePath',
  canActivate: [MyGuardWithDependency]
};
```
`LoginService` implementa la mayor parte de la lógica y en el protector solo invocamos `isLoggedIn()`. Aunque la protección es bastante simple, tenemos mucho código repetitivo.

Con los nuevos protectores de enrutadores funcionales, puede refactorizar este código a:


```typescript
const route = {
  path: 'admin',
  canActivate: [() => inject(LoginService).isLoggedIn()]
};
```

Escribimos todos los parámetros para la protección dentro de la declaración de protección. Las protecciones funcionales también se pueden componer - puede crear funciones similares a las de fábrica que aceptan una configuración y devuelven una función de protección o resolución. Puede encontrar un ejemplo para ejecutar guardias de enrutador en serie en GitHub.


## El enrutador(router) desenvuelve las importaciones predeterminadas

Para hacer que el enrutador sea más simple y reducir aún más el texto estándar, el enrutador ahora desenvuelve automáticamente las exportaciones predeterminadas cuando se realiza una carga diferida.

Supongamos que tiene lo siguiente `LazyComponent`:

```typescript
@Component({
  standalone: true,
  template: '...'
})
export default class LazyComponent { ... }
```

Antes de este cambio, para realizar la carga diferida de un componente independiente, tenía que:

```typescript
{
  path: 'lazy',
  loadComponent: () => import('./lazy-file').then(m => m.LazyComponent),
}
```

Ahora el enrutador buscará una exportación predeterminada y, si la encuentra, la usará automáticamente, lo que simplifica la declaración de la ruta a:

```typescript
{
  path: 'lazy',
  loadComponent: () => import('./lazy-file'),
}

```

## Mejores rastros de pila(Better stack traces)
Obtenemos mucha información de nuestras encuestas anuales para desarrolladores, por lo que queremos agradecerle por tomarse el tiempo para compartir sus pensamientos. Al profundizar en las dificultades con la experiencia de depuración que enfrentan los desarrolladores, descubrimos que los mensajes de error podrían mejorar.

![Comentarios sobre los desafíos de depuración](https://cdn-images-1.medium.com/max/800/0*cJ22oY__xw50JW4Z)

## Problemas de depuración para los desarrolladores de Angular

¡Nos asociamos con Chrome DevTools para arreglar esto! Veamos un seguimiento de pila de muestra que puede obtener trabajando en una aplicación Angular:

```json
ERROR Error: Uncaught (in promise): Error
Error
    at app.component.ts:18:11
    at Generator.next (<anonymous>)
    at asyncGeneratorStep (asyncToGenerator.js:3:1)
    at _next (asyncToGenerator.js:25:1)
    at _ZoneDelegate.invoke (zone.js:372:26)
    at Object.onInvoke (core.mjs:26378:33)
    at _ZoneDelegate.invoke (zone.js:371:52)
    at Zone.run (zone.js:134:43)
    at zone.js:1275:36
    at _ZoneDelegate.invokeTask (zone.js:406:31)
    at resolvePromise (zone.js:1211:31)
    at zone.js:1118:17
    at zone.js:1134:33
```


Este fragmento viene de dos problemas principales:

- Solo hay una línea que corresponde al código que ha creado el desarrollador. Todo lo demás proviene de dependencias de terceros (marco Angular, Zone.js, RxJS)

- No hay información sobre qué interacción del usuario causó el error.

El equipo de Chrome DevTools creó un mecanismo para ignorar los scripts que provienen `node_modules` al anotar los mapas de origen a través de la CLI de Angular. También colaboramos en una API de etiquetado de pila asíncrona que nos permitió concatenar tareas asíncronas programadas e independientes en un único seguimiento de pila. [Jia Li](https://twitter.com/Jialipassion) integró Zone.js con la API de etiquetado de pilas asíncronas, lo que nos permitió proporcionar seguimientos de pilas vinculadas.

Estos dos cambios mejoran drásticamente los seguimientos de pila que los desarrolladores ven en Chrome DevTools:

```json
ERROR Error: Uncaught (in promise): Error
Error
    at app.component.ts:18:11
    at fetch (async)  
    at (anonymous) (app.component.ts:4)
    at request (app.component.ts:4)
    at (anonymous) (app.component.ts:17)
    at submit (app.component.ts:15)
    at AppComponent_click_3_listener (app.component.html:4)
```

Aquí puede seguir la ejecución desde que se presiona el botón en `AppComponent` hasta el error. Puede leer más sobre las mejoras [aquí](https://medium.com/r/?url=https%3A%2F%2Fdeveloper.chrome.com%2Fblog%2Fdevtools-modern-web-debugging%2F).

## Liberaramos componentes basados ​​en MDC a estable
¡Nos complace anunciar que la refactorización de los componentes de material de Angular basados ​​en Componentes de diseño de materiales para Web (MDC) ya está lista! Este cambio permite que Angular se alinee aún más con la especificación de Material Design, reutilice el código de las primitivas desarrolladas por el equipo de Material Design y nos permita adoptar Material 3 una vez que finalicemos los tokens de estilo.

Para muchos de los componentes, hemos actualizado los estilos y la estructura DOM y otros los hemos reescrito desde cero. Mantuvimos la mayoría de las API de TypeScript y los selectores de componente/directiva para los nuevos componentes idénticos a la implementación anterior.

Migramos miles de proyectos de Google, lo que nos permitió simplificar la ruta de migración externa y documentar una lista completa de los cambios en todos los componentes.

Debido al nuevo DOM y CSS, es probable que descubra que es necesario ajustar algunos estilos en su aplicación, especialmente si su CSS anula estilos en elementos internos en cualquiera de los componentes migrados.

La implementación anterior de cada componente nuevo ahora está obsoleta, pero aún está disponible a partir de una importación "heredada". Por ejemplo, puede importar la `mat-button` anterior importando el módulo de botón  legacy.

```typescript 
import {MatLegacyButtonModule} from '@angular/material/legacy-button';Visite la guía de migración para obtener más información.
```

Movimos muchos de los componentes para usar tokens de diseño y variables CSS debajo del capó, lo que proporcionará un camino fluido para que las aplicaciones adopten los estilos de componentes de Material 3.

## Más mejoras en los componentes
Resolvimos el cuarto problema más votado: soporte de selección de rango en el control deslizante.

Para obtener un uso de entrada de rango:


```html 
<mat-slider> 
  <input matSliderStartThumb> 
  <input matSliderEndThumb> 
</mat-slider >
```
Además, todos los componentes ahora tienen una API para personalizar la densidad, lo que resolvió otro problema popular de [Github](https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fangular%2Fcomponents%2Fissues%2F4597).

Ahora puede especificar la densidad predeterminada en todos sus componentes al personalizar su tema:

```css
@use '@angular/material' as mat;

$theme: mat.define-light-theme((
  color: (
    primary: mat.define-palette(mat.$red-palette),
    accent: mat.define-palette(mat.$blue-palette),
  ),
  typography: mat.define-typography-config(),
  density: -2,
));

@include mat.all-component-themes($theme);
```

Las nuevas versiones de los componentes incluyen una amplia gama de mejoras de accesibilidad, que incluyen mejores relaciones de contraste, mayores tamaños de objetivos táctiles y semántica ARIA refinada.

## Listbox de CDK
El kit de desarrollo de componentes (CDK) ofrece un conjunto de primitivas de comportamiento para crear componentes de interfaz de usuario. En v15 presentamos otra primitiva que puede personalizar para su caso de uso: el listbox CDK:

![Experiencia de usuario del listbox de CDK](https://cdn-images-1.medium.com/max/800/0*cBcfjtH5tKhvC_8y)

El módulo `@angular/cdk/listbox` proporciona directivas para ayudar a crear interacciones de listbox personalizadas basadas en el patrón de listbox WAI ARIA.

Al usar `@angular/cdk/listbox`, obtienes todos los comportamientos esperados para una experiencia accesible, incluida la compatibilidad con el diseño bidi, la interacción del teclado y la gestión del enfoque. Todas las directivas aplican sus roles ARIA asociados a su elemento host.

## Mejoras en el soporte de esbuild experimental

![Página de destino de esbuild](https://cdn-images-1.medium.com/max/800/0*sotRPelZcrWaChn9)

En la v14, anunciamos el soporte experimental para esbuild en `ng build` para permitir tiempos de compilación más rápidos y simplificar nuestra pipeline.

¡En la v15 ahora tenemos Sass experimental, plantillas SVG, reemplazo de archivos y soporte para `ng build --watch` , Pruebe esbuild actualizando sus constructores `angular.json` desde:

```json 
"builder": "@angular-devkit/build-angular:browser"
```
a:

```json 
"builder": "@angular-devkit/build-angular:browser-esbuild"
```

Si encuentra algún problema con sus compilaciones de producción, infórmenos presentando el [problema en GitHub](https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fangular%2Fangular-cli%2Fissues%2Fnew%3Fassignees%3D%26labels%3D%26template%3D1-bug-report.yml).

## Importaciones automáticas en el servicio de idiomas
El servicio de idioma ahora puede importar automáticamente los componentes que está usando en una plantilla pero que no ha agregado a un componente independiente o un NgModule.

![Importaciones automáticas de servicios de idiomas](https://cdn-images-1.medium.com/max/800/0*HRd9c-1K6mSXjwIN)

## Mejoras en el CLI
En CLI de Angular introdujimos soporte para API estables independientes. Ahora puede generar un nuevo componente independiente a través de `ng g component --standalone`.

También tenemos la misión de simplificar la salida de `ng new`. Como primer paso, reducimos la configuración eliminando `test.ts`, `polyfills.ts` y `environments`. Ahora puede especificar sus polyfills directamente `angular.json` en la sección `polyfills`:

```json 
"polyfills" :  [ 
  "zone.js" 
]
```

Para reducir aún más la sobrecarga de configuración, ahora usamos `.browserlist` para permitirle definir la versión de destino de ECMAScript.

## Aspectos destacados de la contribución de la comunidad

¡Estamos agradecidos de compartir que **desde el lanzamiento de v14 recibimos contribuciones de más de 210 personas en el marco, los componentes y el CLI!** En este apartado me gustaría destacar dos de ellos.

[Proporcionar la capacidad de configurar las opciones predeterminadas para DatePipe](https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fangular%2Fangular%2Fpull%2F47157)

Esta función le permite cambiar globalmente la configuración de formato predeterminada para `DatePipe`. Aquí hay un ejemplo con la nueva `bootstrapApplication` API:

```typescript
bootstrapApplication (AppComponent, { 
  proveedores : [ 
    { 
      proporcionar : DATE_PIPE_DEFAULT_OPTIONS, 
      useValue : { dateFormat : 'shortDate' } 
    } 
  ] 
});
``` 

La configuración anterior habilitará `shortDate` el formato para todos los lugares que utilice `DatePipe`en su aplicación.

[Agregar etiqueta de precarga <link> para imágenes prioritarias durante SSR](https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fangular%2Fangular%2Fpull%2F47343)

Para asegurarse de que las imágenes prioritarias se carguen lo más rápido posible, [Jay Bell](https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fyharaskrik) agregó una funcionalidad a la directiva de imagen para incluir una etiqueta <link rel="preload"> para cuando se usa Angular Universal.

No se necesita ninguna acción de su parte si ya ha habilitado la directiva de imagen. Si ha especificado una imagen como prioridad, la directiva la precargará automáticamente.

## Deprecaciones
Los lanzamientos principales nos permiten evolucionar el framework hacia la simplicidad, una mejor experiencia del desarrollador y la alineación con la plataforma web.

Después de analizar miles de proyectos dentro de Google, encontramos algunos patrones poco utilizados que, en la mayoría de los casos, se utilizan incorrectamente. Como resultado, estamos descartando `providedIn: 'any'` una opción que tiene un uso muy limitado, aparte de un puñado de casos esotéricos internos del framework.

También estamos deprecando providedIn: `NgModule`. No tiene un uso generalizado, y en la mayoría de los casos se usa de forma incorrecta, en circunstancias en las que debería preferir `providedIn: 'root'`. Si realmente desea apuntar a un `NgModule`, utilíce `NgModule.providers`en su lugar.

Con la evolución del diseño en CSS, el equipo dejará de publicar nuevas versiones de `@angular/flex-layout`. Continuaremos brindando correcciones de seguridad y compatibilidad del navegador durante el próximo año. Puede obtener más información sobre esto en la [primera publicación de blog de nuestra serie](https://medium.com/r/?url=https%3A%2F%2Fblog.angular.io%2Fmodern-css-in-angular-layouts-4a259dca9127) "CSS moderno".

## ¡Emocionado por lo que viene a continuación!
El [lanzamiento de Ivy en 2020](https://medium.com/r/?url=https%3A%2F%2Fblog.angular.io%2Fversion-9-of-angular-now-available-project-ivy-has-arrived-23c97b63cfa3) permitió muchas mejoras en todos los ámbitos que puede encontrar que ya se están implementando. NgModules opcional es un gran ejemplo. Ayuda a reducir los conceptos con los que los principiantes deben lidiar como parte de su viaje de aprendizaje crítico y también admite funciones avanzadas como la API de composición de directivas a través de directivas independientes.

A continuación, abordaremos las mejoras en nuestra pipeline de renderizado del lado del servidor y la reactividad, al mismo tiempo que brindamos mejoras en la calidad de vida en todos los ámbitos.

¡No puedo esperar para compartir con ustedes lo que viene a continuación!