Angular 13!

Featured image

Migración Angular 13

Buenasss como andan? Volvemos con nueva migra de angular!!!

El post de hoy va dedicado a las experiencias durante una migración específica desde nuestro previo Angular 12 hacia Angular 13, con novedades, tips, errores, warnings y sus respectivos fixes para renovarnos y sacarlo con fritas!

enter image description here

Guía

Para empezar vamos a la guía oficial aquí. En este caso, viniendo de la versión 12, no necesitamos aplicar cambios en nuestro código ANTES de ejecutar el comando para poder migrar. Por lo tanto, podemos arrancar:

ng update @angular/core@13 @angular/cli@13

Nota: agregar el –force si es necesario! Hasta ahora en cada migra parece que lo pide a gritos! enter image description here

La mayoría de cambios requeridos los aplicamos con el comando. El resto de posibles cambios que tengas que hacer, dependerán como siempre del proyecto en el que estés trabajando y esta guía es para esos cambios manuales, allá vamos! También vas a ver diferencias en cuanto a si estás trabajando en una app, o en una librería publicable por el tipo de compilación, que vamos a ver más adelante.

ModuleWithProviders migration

Si tenés modulos con providers implementando ModuleWithProviders, puede que el schematic no pueda determinar el type, por lo cual es necesario migrar aquellos que requieran el type así:

    @NgModule({})
    export class MyModule {
      static forRoot(config: SomeConfig): ModuleWithProviders<SomeModule> {
        return {
          ngModule: SomeModule,
          providers: [
            {provide: SomeConfig, useValue: config }
          ]
        };
      }
    }

Más detalles e info acá!

Rxjs

enter image description here Si estabas usando RxJS v6.x, hay que instalar manualmente la 7.4:

    npm install rxjs@7.4

Para proyectos y apps fresh en esta versión de Angular, instalarán por defecto el rxjs 7.4. Qué hay de nuevo en Rxjs acá!

Por supuesto esto no termina acá, hay algunos breaking changes y algunas deprecaciones que pueden impactar en tu proyecto, suelen resolverse en poco tiempo. Ejemplo :

    RxJS 7 allow to call 'next' without parameters (Typescript checks).

Si estás haciendo un next en un Subject sin params así:

const updateSubject = new Subject();
updateSubject.next();

se puede resolver agregando el type en la declaración de ese Subject:

    private subject$ = new Subject<void>();

Más info acá!

Compilermode

Angular library

enter image description here Si estás trabajando en una library publicable npm, podes encontrar este error:

    Unsupported private class

> This class is visible to consumers via SomeModule -> SomeComponent,
> but is not exported from the top-level library entrypoint

Para resolverlo, tendrás que buscar los componentes y módulos que no están debidamente exportados en la public_api.ts.

Esto puede pasar porque con Ivy, es un requerimiento si queremos exportar un modulo desde una library endpoint, debemos re-exportar manualmente todos los elementos involucrados también (componentes, pipes, directivas, todooo!). Antes con View Engine, esto era automático. Pero con Ivy debemos explícitamente hacerlo, recordemos que Ivy llegó para quedarse y View Engine en esta versión ya queda oficialmente deprecado. Más info de estos errores acá! Info oficial sobre Angular libraries acá!

Error para Angular library: NG3003: Import cycles would need to be created to compile this component

O también conocido como

    One or more import cycles would need to be created to compile this component, which is not supported by the current compiler configuration.
    is used in the template but importing it would create a cycle

Si te topaste con este error cíclico, sólo se da en angular library, si no estás trabajando en una library publicable, safaste y te ganaste el pase directo a la próxima sección, fuera! Este error podría significar un cambio de complejidad baja/media según el caso, ya que deberemos tener en cuenta si se trata de un tema de imports con dependencias circulares (complejidad baja) o si necesitamos aplicar refactor (complejidad media no tan barata). Por ejemplo en un caso donde ante ciertas situaciones, componente A embebe a componente B, y donde componente B puede embeber a componente A. Lo más probable es que tengamos que refactorizar si tenemos este último caso. La explicación del error y posibles sugerencias para fixearlo desde Angular oficial acá!

Esto ocurre por el tipo de compilación, pudiendo ser “partial” o “full” en nuestra
tsconfig.lib.prod.json. Estando en una library, debemos usar “partial” ya que necesitamos la retrocompatibilidad de los consumidores con o sin Ivy. En una app (no library), el tipo de compilación será “full” y no verás este hermoso error jamás. Ahora, qué pasaría si estamos trabajando en una Angular library, y manualmente modificamos a modo compilación “full”? Engañamos al npm publish sí o no?

enter image description here

    ERROR: Trying to publish a package that has been compiled by Ivy in full compilation mode. This is not allowed.
    Please delete and rebuild the package with Ivy partial compilation mode, before attempting to publish.

La build te va a decir si si dale y cuando corras el npm publish te da la bienvenida con ese error de arriba… asi que no, ni lo intentes, compila en “partial” y no pierdas tiempo valioso en esto.

enter image description here

Salvo que quieras super investigar estos tipos de compilación y los por qué, te dejo este artículo que esta buenísimo, con gráficos y todo más que claro.

Errores/Warnings

Por lo general y en cada nueva versión de Angular, los errores y/o warnings cada vez son más restrictivos en varios puntos pero también son cada vez más descriptivos, por lo que podrían resolverse desde las mismas sugerencias que ellos nos ofrecen. Es por eso, que preferí enfocar este post a los errores que no son tan fáciles de resolver y también a aquellos que nos lleva más tiempo de análisis e investigación para su resolución. Recordá siempre correr y compilar el build de production para exterminar los errores que queden pendientes.

Storybook

enter image description here

Si en tu proyecto estás usando Storybook, hay una gran migra también con varios ajustes manuales para mantener Storybook actualizado. Lo más importante en esta versión: Habemus compilador de Angular para storybook, asi que desde nuestro angular.json lo vamos a dejar configurado. Como siempre sugiero la guía oficial de migración de Storybook:

Otra cuestión que me pasó, fue uno de los problemas en la compilación de storybook, de este estilo:

    preview.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property.

Por lo cual tuve que aplicar cambios en el .storybook/tsconfig.json para los includes, como acá!

Y si te surge este caso: can only be default-imported using the'allowSyntheticDefaultImports' flag

Podes resolverlo agregando esa flag en el tsconfig del proyecto raíz (no storybook como el anterior):

    "allowSyntheticDefaultImports": true,

Si los problemas de compilation persisten y vemos esto:

 UnhandledPromiseRejectionWarning: TypeError: The 'compilation' argument must be an instance of Compilation

podés revisar de no tener prendido el sourceMap para debugging, en el angular.json debería quedar así:

 "sourceMap": false,

Más info acá!

Si aún vemos este maldito:

 UnhandledPromiseRejectionWarning: TypeError: The 'compilation' argument must be an instance of Compilation

Vamos a tener que revisar y verificar las versiones de webpack de angular y webpack de storybook, para eso seguimos estos pasos:

  1. npm ls webpack
  2. Buscamos la version de webpack para @angular-devkit/build-angular
  3. npm install la version exacta en dev dependencies
  4. npm dedupe // WTF? si, esto intenta simplificar el arbol de dependencias de los paquetes cambiando su estructura y también elimina duplicados

Más info de este error y los pasos que vimos arriba acá!

Jest

enter image description here

Si te animaste a decirle adiós a Jasmine y Karma, y empezaste a indagar en el mágico mundo de Jest, ahí van los ajustes necesarios para esta versión!

enter image description here

Para empezar, en mi experiencia migré todo jest a estas nuevas versiones:

 "@types/jest": "27.4.1",
 "jest": "^27.4.7",
 "jest-preset-angular": "^11.0.1",
 "ts-jest": "^27.1.2",

Para migrar y actualizar nuestro jest.config.js por comando npm ejecutamos:

npx ts-jest config:migrate jest.config.js

Otras formas de ejecutarlo acá:

También, recomiendo seguir estos pasos para migrar los cambios según el changelog

En mi experiencia tuve este error:

Need to call TestBed.initTestEnvironment() first

y este otro:

 Zone is needed for the waitForAsync() test helper but could not be found. Please make sure that your environment includes zone.js

A ambos los resolví fixeando el test.ts (donde importamos el jest-preset-angular) así:

import "jest-preset-angular";
import "zone.js";
import "zone.js/testing";
import { TestBed } from "@angular/core/testing";
import {
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting,
} from "@angular/platform-browser-dynamic/testing";

TestBed.initTestEnvironment(
  BrowserDynamicTestingModule,
  platformBrowserDynamicTesting()
);

Más info de ese error acá!

Algunos cambios únicamente podrían afectarte según la versión de Jest y de jest-preset-angular que estés usando actualmente, por las dudas podés chequearlos acá.

Si encontrás este otro error:

    [Package subpath './src/ngtsc/reflection' is not defined by "exports" in /node_modules/@angular/compiler-cli/package.json](https://stackoverflow.com/questions/70306517/package-subpath-src-ngtsc-reflection-is-not-defined-by-exports-in-node-mo)

Podrías revisar si las versiones de jest necesitan otro cambio como indican acá.

Otro error que experimenté fue:

Cannot configure the test module when the test module has already been instantiated. Make sure you are not using `inject` before `R3TestBed.configureTestingModule`

Para fixearlo, es necesario agregar la opción de teardown en el configureTestingModule:

teardown: { destroyAfterEach: false },

Más info acá!

Ventajas y cambios en esta versión

enter image description here Desde el blog oficial tenemos toooda la data de los cambios que llegan con Angular 13, así que destaco y ultra resumo algunos puntos muy interesantes:

` { canceledNavigationResolution: ‘computed’ }`

Espero les haya servido, happy coding!!! enter image description here