CONTACT
arrow_left Back to blog

Angular v13 Is Out!

It's been six months since the last major version of the Angular framework was released. A completely new version of Angular has just been released.

In this article we'll look at some features and updates that will help you create amazing applications. We will go through a few optimizations of the Ivy engine. We will also talk about what is being deprecated and briefly discuss the process of migrating the application to Angular v13.

So let's get started!

Upgrade to Angular v13

With the release of the new version, the Angular team provides a complete guide to upgrade from previous versions. By following the guide, you shouldn't have any problems with getting migrated to the latest version.

If you are using Nx, please follow the guidelines provided by the Nwrl team. By running nx migrate latest, you will also update Angular and all its dependencies.

Angular dependency updates

In the latest release of Angular, there are also changes in the dependencies of the framework. Angular v13 introduces TypeScript 4.4 support, which means that we can now use its new features. Support for older versions of TypeScript has been dropped.

Moreover, version 7.4 is now the default version for RxJs. To learn more about the changes from version 6 to version 7, please read this article.

Additionally, Angular v13 has dropped support for NodeJS versions below v12.20.0 and has introduced support for NodeJS >=16.10.

IE11 support dropped

And it happened. IE11 is no longer supported by Angular v13. This is one of the most important pieces of news for this release. Dropping support for IE11 is a good thing - it means Angular gets to fully embrace the Web APIs of modern browsers. It also means that we no longer have to include polyfills for IE, which makes applications lighter and load faster than in previous versions of Angular. It is worth noting that the migration process described previously will automatically remove polyfills for IE.

The Angular team put out an RFC (request for comments) about dropping IE11 support, and the feedback they received was overwhelmingly in favor of doing so.

Emote responses to the RFC on GitHub

Note that Angular 12 will continue to support IE11 until November 2022.

Ivy FTW

Ivy FTW View Engine

As promised in past announcements, Angular version 13 no longer supports the old rendering View Engine. For the average Angular dev, this doesn't mean much (other than reaping the benefits of a more performant framework). For library builders in Angular, though, this is a big deal.

As mentioned in the official announcement, removing View Engine also means that Angular can reduce its reliance on ngcc (Angular compatibility compiler) in the future, and teams can look forward to faster compilation because metadata and summary files are no longer included.

Angular Package Format (APF)

As mentioned in the official announcement, the Angular Package Format (APF) has been streamlined and modernized to better serve developers. To streamline the APF in Angular v13, older output formats such as CommonJS (CJS) and UMD have been removed. Thanks to this change, the whole Web community will be better off once ES Modules (ESM) are used everywhere.

The Angular team has also updated the APF to support Node Package Exports. This will help developers from inadvertently relying on internal APIs that may change.

It is now time for Angular library authors to stop using enableIvy: false, and to instead use compilationMode: partial (in tsconfig.prod.json), as recommended by Younes.

The partial compilation mode is a partial-Ivy code format that is stable between different versions of Angular, and thus safe to publish to npm. Angular code that uses this partial format is processed during the build of the application using the same version of the Angular compiler. The benefit is that both the application and its libraries rely on a single version of Angular, removing potential compatibility issues.

Existing libraries will be automatically migrated to use “partial” compilation mode and some metadata previously required for the legacy View engine will be removed.

To learn more check out the official guidelines for library authors.

Create components dynamically from API updates

Ivy enables a simpler way to create dynamic components. Angular no longer requires component factories to dynamically create components. Ivy creates the opportunity to instantiate the component with ViewContainerRef.createComponent without creating an associated factory. So, instead of:

@Directive({...})
export class CustomyDirective {
  constructor(
    private viewContainerRef: ViewContainerRef,
    private componentFactoryResolver: ComponentFactoryResolver
  ) {
  }

  createCustomComponent() {
    const componentFactory = this.componentFactoryResolver.resolveComponentFactory(CustomComponent);
    this.viewContainerRef.createComponent(componentFactory);
  }
}

We can now write:

@Directive({...})
export class CustomDirective {
  constructor(private viewContainerRef: ViewContainerRef) {
  }

  createCustomComponent() {
    this.viewContainerRef.createComponent(CustomComponent)
  }
}

As we can see, the new approach requires much less boilerplate code!

Angular CLI improvements

With this release, Angular supports the use of persistent build cache by default, as requested by the community. The persistent build cache is a feature that caches build results on disk (under the .angular/cache folder). This results in up to 68% improvement in compilation speed.

In order to enable this feature in existing projects that have been upgrading to v13, we need to add the following configuration to angular.json:

{
  "$schema": "...",
  "cli": {
    "cache": {
      "enabled": true,
      "path": ".cache",
      "environment": "all"
      // other supported values: "ci" and "local"
    }
  }
}

We can also disable this feature (which is not recommended) with ng config cli.cache.enabled false.

If we need to clear the cache, we should delete the .angular / cache folder.

For those who use esbuild as a build tool, there is good news as well. The performance has been improved. The Angular team has introduced esbuild, which now works with terser to optimize global scripts. In addition, ESBuild supports CSS sourcemaps and can optimize global CSS, as well as optimizing all style sheets.

Router improvements

Setting the routerLink directive value to null or undefined will completely disable navigation. Recall that in the previous version, the null and undefined inputs for the routerLink directive were interpreted as an empty string.

A new output for the routerLinkActive directive called isActiveChange has been added. It emits whenever the link becomes active or inactive.

Lazy load modules

The loadChildren property in the route definition no longer supports string values. It's been deprecated for a while now. This has been replaced by the ESM dynamic import statement.

Restore history

A new property has been added to Router public API

RouterModule.forRoot(routes, {canceledNavigationResolution: 'computed'});

New events when an outlet gets attached/detached

Router now also provides new outputs for subscribing when an outlet gets attached/detached.

Other improvements and changes

  • Support for question marks in query param values
  • Custom route reuse strategy through dependency injection for the RouterTestingModule
    TestBed.configureTestingModule({
      imports: [RouterTestingModule],
      providers: [{provide: RouteReuseStrategy, useClass: AttachDetachReuseStrategy}]
    });
    

Form improvements

In this version, a little more attention is paid to Angular Forms, improving the security of reactive forms. Let's take a look at the changes.

Better type checking for form status

A specific type called FormControlStatus has been introduced, which is the union type of all possible status strings for form controls: 'VALID' | 'INVALID' | 'WAITING' | 'OFF'. Until now, we could not use Typescript checking because AbstractControl.status was entered as a string and AbstractControl.statusChanges was Observable<any>.

This is a breaking change! As mentioned in the release notes, this can break applications if an invalid form status string is used or if statusChanges events were something other than strings.

New methods to manage validators

New form methods have been added to AbstractControl:

  • addValidators: Add one or more synchronous validator(s) to the control, without affecting other validators
  • setValidators: Sets one or multiple validators by overriding the registered ones. For removing all registered validators we can pass a value of null
  • hasValidator: Determines whether a validator or validators array has a given validator
  • removeValidators: Remove synchronous validators from this control

All of these methods also have an async version: addAsyncValidators, setAsyncValidators , removeAsyncValidators, and hasAsyncValidator.

These new methods provide us with more control over the validation process. We can now easily add/remove synchronous and asynchronous validators.

Templates improvements

Angular now supports autocompletion for string literal union types . The language service of Angular is now able to automatically insert the optional chaining operator (i.e., ?.) when property access (i.e., .) is done on a nullable symbol.

Also, the fullTemplateTypeCheck compiler option has been deprecated. Instead, we should use strictTemplates .

Components improvements

Accessibility

The new version of Angular has also resulted in significant improvements and changes to the components of Angular Material.

All MDC-based components have been assessed to meet elevated a11y standards in areas such as contrast, tactile targets, ARIA, and more. For example let’s compare touch target sizes. The sizes on the right are the new sizes.

Comparison of touch target sizes

or for better support for high contrast mode for many components:

Material Components in high contrast mode

It’s always a pleasure to see large organizations put energy into improving accessibility.

Angular Material

There are also a few changes for Angular Material.

It is now possible to define content sections in test harnesses for the Dialog component. Also, a new injection token called MAT_PROGRESS_BAR_DEFAULT_OPTIONS has been added to the progress bar. It can be used to configure the default options as follows:

provide: MAT_PROGRESS_BAR_DEFAULT_OPTIONS,
useValue: {
  mode: 'buffer',
  color: 'warn'
}

Tests improvements

Together with Angular v13, TestBed has also been improved. It now takes better care of tearing down test modules and environments after each test. The DOM is now cleaned up after every test, avoiding side effects. Overall, tests should execute faster, use less memory, and be less interdependent.

The automatic teardown functionality was an opt-in feature since Angular v12.1.0 and is now enabled by default. As mentioned in the announcement, this behavior can be configured for the entire test suite via the TestBed.initTestEnvironment method:

beforeEach(() => {
  TestBed.resetTestEnvironment();
  TestBed.initTestEnvironment(
    BrowserDynamicTestingModule,
    platformBrowserDynamicTesting(),
    {
      teardown: {destroyAfterEach: true}
    }
  );
});

Or it can be configured per module by updating the TestBed.configureTestingModule method:

beforeEach(() => {
  TestBed.resetTestEnvironment();
...
  TestBed.configureTestingModule({
    declarations: [TestComp],
    teardown: {destroyAfterEach: true}
  });
});

This allows us to approach testing differently depending on the situation.

Summary

The new release of Angular introduced a lot of new improvements and minor changes, but also unlocked the way to the critical ones, such as the optional NgModules. ViewEngine is gone for good and Ivy has become ubiquitous.

This is another release that improves runtime performance, shortens build time, simplifies API, and improves tests.

Finally, I encourage you to check the full list of changes.

Until next time!

Transamerica Pyramid