Angular v9 is here! Along with it, we now get Ivy, the default compiler that can reduce bundle size, improve debugging, and much more. It’s been almost three years since Angular released an update this large (ironic, since this update makes the code smaller!), and we can see it’s been worth the wait.

GitHub view of Angular v9

In this article, we are going to go over how to update from v8 to v9 and the most Magnificent Seven things that Angular v9 has given us. There are many things we can look forward to in this update, let’s talk about some of our favorites!

Angular 9 is Ready for its Closeup

This upgrade has been through extensive testing. With more developers and projects using it, the bugs have been reported, and over 300 have been fixed. Angular is used internally at Google for projects like Google Domains and Firebase. These projects will use new versions of Angular to test and validate before it goes beyond beta and RC. This upgrade is ready!

Version 9 is more about changes to the framework, not the code that we wrote. This makes it easy for developers. To upgrade to v9, we won’t have to dive into individual files or components and update any code ourselves. The new Ivy renderer works with all our current code!

{% include tweet_quote.html quote_text="Angular v9 is more about changes to the framework, not the code that we wrote." %}

How to Update from v8 to v9

We can find step-by-step instructions for updating from v8 to v9 on the official update.angular.io. Let’s go over exactly what needs to happen to upgrade from Angular v8 to Angular v9.

Note: Before starting the upgrade process, be sure to commit all changes to git. This will also be helpful to see how the upgrade modified certain files.

First, ensure we are using Node v10.13 or later. It’s recommended to use the Node 12.15.0 LTS version since it will be supported!

Once we confirm our Node version, we will want to run the following command in our project’s directory:

ng update @angular/core@8 @angular/cli@8

This command will update our @angular/core and @angular/cli in our package.json for our project.

Once we run that, we will want to run:

ng update @angular/core @angular/cli

Terminal - Updating to Angular 9 confirmation

During the update process, we should see numerous messages telling us exactly what the CLI is updating. It will also tell us which files were modified. At a minimum, we should see the following files modified:

VS Code view of files that were modified. tsconfig.app.json, angular.json, package-lock.json, package.json

We may see other files that get modified depending on where the project sits. For example, if the project has the older lazy load syntax or if the project is missing the @injectable() in a service file, those would also get updated.

Once complete, head to our package.json, and we will see that we are up-to-date with the latest Angular v9!

View of package.json showing v9 updates

We have now updated from Angular v8 to Angular v9! Let’s explore more of the features.

The Magnificent Seven

In this article, we are going to list the most “Magnificent Seven” features in Angular v9, all to the theme of movie titles. You get bonus points for spotting all the movie and television show references and listing them in the comments!

1 - Honey I Shrunk Our App

It wasn’t accidental that the Angular team focused on helping our apps become smaller and making our apps faster than they were in previous versions of Angular. Our users expect the app experience to be fast. The Ivy compiler focuses on targeting our code with laser-beam accuracy to find and remove unneeded code.

The Ivy compiler looks for parts of Angular that are not being used. It uses tree-shaking (a way of detecting unused code, also known as dead code removal), and it generates less code for each Angular component.

As the chart below shows, apps of all sizes can benefit from the Ivy compiler.

Graph showing how Ivy improves app size
(Image credit)

Once we update to Angular 9, we can run ng build --prod and notice how our file sizes shrink.

2 - Ivy Knows What You Did Last Summer, in that Template

That’s right. Last summer, we wrote some pretty tragic code that we mostly forgot about. But Angular 9 hasn’t forgotten. We made poor choices in our templates and those errors are now detected by Angular 9. Fortunately, Angular is friendly enough to share those template errors with us in a clear and helpful way.

When we reference a component in a template, Angular expects that the component exists in the app. Imagine that we have this template:

<div>
  <app-fake></app-fake>
  Hello {{hero.name}}
</div>

If no component exists that matches the app-fake selector, this is a problem. However, in Angular 9, when we run ng build, we get a very detailed error explaining that it knows exactly what we did wrong.

ng build error

The error message very clearly tells us that it cannot find the component, shows us which component it is referring to, and it shows us exactly where this reference appears in the code!

3 - Winter is Coming, and so is Our Angular Build

Ivy is so fast that we’ll have fewer opportunities to step away while waiting for our builds to complete. Prior to Angular 9, some of our app build times have felt like it would be a race to see what would come first: Winter or the completion of our Angular build.

Well, Ivy knows things about our apps and it always pays its debts. Ivy speeds up our build times significantly. Faster build times mean less stepping away from the computer while we build our apps.

4 - Back to the Future, with AOT!

Remember that time before Angular 9 when we found out we had an AOT error that surfaced only in Continuous Integration (CI) or, heaven forbid, in production? Hello McFly! That’s about when we want to go back in time and correct our mistakes by running ng build --prod.

Why did this happen? Because prior to Angular 9, the AOT compilation step only ran when we executed using the production flag ng build --prod. It seems that AOT compilation would have made the dev builds too slow to be a good experience, so the Angular team opted (thankfully) to only put AOT compilation in the production builds. While this was fine as long as we remembered to run it before pushing or merging (or whatever your CI process is), it certainly had its flaws.

What we wish is that in the future, we can see the AOT errors in all builds. Well, that future is here!

The good news is that Angular 9 brings AOT to the dev build, too! The Ivy compiler makes our builds much faster. So fast that it makes it reasonable to pull AOT into the dev builds (and of course, ng serve) without causing significant delays in build times.

The bottom line is that AOT is now dev and prod. Who cares? We do! AOT errors that never appeared in a dev build used to surprise us when we ran with a prod build. Now that dev and prod use AOT, we’ll find these errors early and we’ll see good error messages explaining how to fix them.

5 - The Phantom Template Variable Menace

There once was a time when we could create phantom variables in our templates - variables that had never been referenced in the template’s associated component. Creating these phantom variables can menace our applications. All of this changes in Angular 9 as we now get a compiler error when we create a template variable that has not been defined in a component.

Let’s take a look at what this means. Imagine we have a template and we set a villain variable when a user clicks on a <div>. Now, we may have intended for them to set the hero model, which exists in the templates’ component. But we might have made a copy and paste error. Or maybe we really wanted to create a villain model, in which case we should have defined the model in the component file.

<div (click)="villain = { id: 1, name: 'john' }">

When we build with Angular 9, this error will be displayed. Notice it tells us that the villain doesn’t exist in the component. It even shows us exactly where to find this code.

Error handling in Components

So what can we do about this? Well, if the intention was to set a hero, now we know we have to change it. If we really need to set the villain model in the template, just create the villain model in the component. Before Angular 9, this may have gone unnoticed, but now Ivy detects and alerts us about all template-only variables.

6 - Brave: An ng update Story

At times running ng update with Angular 8 (or previous) is amazingly easy and helpful. And other times, it felt like we were poking a sleeping bear. It’s almost like the magical wisps inside of the Angular CLI were playing games with us.

Angular 9 now has a vastly improved ng update experience. It is more accurate, more consistent, and more transparent. Here are three key reasons why the Angular CLI is now more reliable than ever:

  1. It now uses the latest version of the CLI to perform all updates.
  2. Now displays a detailed diary depicting exactly what it is doing during the update.
  3. Refactors our code where it detects a need to be compatible with the latest version.

Since a detailed diary of the update progress is displayed, we always know what code is being refactored. Plus, we can also check our git changes for any refactored code. Here are three examples of the scenarios that the Angular CLI will refactor for us:

  • Update lazy loading syntax to use dynamic imports.
  • Removes the static flag from dynamic queries. As of Angular 9, the "static" flag defaults to false and is no longer required for our view and content queries.
  • Update our services without @Injectable to use @Injectable.

This is really convenient, so we do not have to know every new change in Angular 9 (and beyond). The Angular CLI knows these changes, reports to use what changes it is looking for, and then refactors when it finds any places in our code that need those changes.

7 - The Legendary Journey of Entry Components

A long time ago, in a time of myth and legend, only one person knew when we needed to define entryComponents in our NgModules. Ok, that’s not entirely accurate as many of us have used entryComponents. But do we always remember what they do and when they are needed? Or was that knowledge lost in our mind? With no more hope of resurfacing than that of a lost soul in the Minotaur’s maze.

Lest we forget, this was needed when we used a component (perhaps in code), but it never appeared in a template. Prior to Angular 9, specifying the component in the entryComponents array was the recommended way to tell Angular, “Hey, we have a component here!”.

@NgModule({
  // ...
  entryComponents: [ModalComponent]
})
export class AppModule {}

Here is a scenario where we might have a component that is not referenced in a template. Imagine that we create a ModalComponent which shows a modal dialog to the user, letting them select “yes” or “no”. When using Angular Material, we could use the MatDialog.open() function and pass it the ModalComponent to display to the user. This could be the only place in the app that the component is referenced. Prior to Angular 9, this must be set in the entryComponents array in a NgModule. Otherwise, Angular would not know what ModalComponent is.

Wow, this is something we probably don’t do that often. However, when we do need this feature, we often spend some time searching Google for how to solve it.

The good news here is that in Angular 9 there have been changes to the compiler and runtime that make it so we no longer need to specify this in the entryComponents array. Angular will find the component on its own.

The bad news, if we can call it bad news, is that Angular will not remove the component from the entryComponents array for us. So we should search our code after updating and manually remove them. Then test … always test. Just in case.

Upgraded Tooling

One of the best things about Angular is the amazing and helpful ecosystem. When we upgrade to version 9 we really want to make sure we’re using the latest tools that go with Angular. Here are two tools we recommend installing or upgrading:

  1. VS Code editor
  2. Angular Essentials Extension for Visual VS Code

The Angular Essentials extension includes a set of useful extensions to enhance the development experience with Angular. The one that stands out most is the Angular Language Service, which adds a lot of features to VS Code, so it knows how to help us write our Angular code. Others include useful Angular snippets, ESLint, and debugging extensions.

That’s All Folks!

It looks like we have a lot to look forward to with Angular v9. We have faster build times, a more accurate ng update, and Ivy is making smaller bundle sizes, just to name a few! The Angular team has been working countless hours on this version and we can now reap the benefits!

Which is your favorite of those Magnificent Seven? Which one will help your project the most? Let us know in the comments below!