Since Angular 18 is around the corner (planned for the Week of May 20, 2024), it's now time to actually update to Angular 17 in production.
Besides the automatic update process executed mainly by Angular's fantastic CLI, we also need to take care of 3rd party dependencies, the new control flow migration and eventually switch to the new application builder using esbuild and Vite.
When to update Angular
I generally recommend updating after the first or the second minor release V[N].2.0 and before the next major release V[N+1].0.0.
The reason for waiting up to the second minor is mainly to allow 3rd party libraries to catch up and provide compatible versions of their packages. Most of them will try to catch up earlier β however, just to make sure everything is well tested and stable for production use.
In case of the Angular 17 update, the recommended update window is between V17.2.0 (February 14, 2024) and V18.0.0 (planned for the week of May 20, 2024). So, it's about time to update π
Doing an Angular update
Using the Angular CLI
In my experience, Angular updates are usually quite smooth and straightforward. The Angular CLI provides a fantastic tool to automate the update process. You can run the following command to update your project to Angular 17:
ng update @angular/core@17 @angular/cli@17
Depending on your project setup, you might want to include some additional packages like code>@angular/material and code>@angular/cdk or code>@angular-eslint/schematics:
ng update @angular/core@17 @angular/cli@17 @angular/material@17 @angular/cdk@17 @angular-eslint/schematics@17
If you're using Nrwl Nx
, you can simply run:
nx migrate latest
As already mentioned, these Angular core updates typically are very smooth. If something needs to be changed in your codebase or configuration, the CLI will do it automatically or β if that's not possible β tell you what to do and provide you with the necessary information.
By the way, it's officially planned to use AI in the Angular CLI in the future to make the automated update process even smoother π€―
Manually updating 3rd party packages
However, you need to be aware that the CLI can't and doesn't update everything. Since most Angular Apps use 3rd party dependencies, you need to check if they have a compatible version for Angular 17. If yes, you must update them too. If they are not Angular specific you should update them as well to get the latest features, bug fixes and - most importantly - security updates. In any case, you should avoid peer dependency conflicts.
Here is an example of how you can update packages manually. First, check for outstanding updates:
npm outdated
Then update the mentioned packages. I typically use my favorite IDE, Intellij WebStorm, to find the latest version: Simply open your package.json
and your IDE will show you the latest version of the package when editing the version. When done updating the dependencies, run:
npm i | yarn | pnpm i
Important notes on updating 3rd party packages
- If you're using Component Frameworks from
Bootstrap
toAngular Material
, watch out for breaking changes that need your attention. - If you're running multiple frontend projects on your machine, make sure to try pnpm for faster installs and much, much less disk space consumption π
- Make sure to avoid peer dependency conflicts as good as possible. For example, you won't be able to use the latest
eslint
version 9.X.X because@angular-eslint
currently only supports version 8.X.X. So you'd currently prefereslint
version 8.57.0 until@angular-eslint
catches up (probably in Version 18, but who knows). In some cases however, we will have to usenpm i --legacy-peer-deps
and with that potentially screw up our dependency resolution β so be careful with that! - Final advice on doing an update across multiple Angular versions: Do one version after the other and test everything in between. This way you can easily identify potential breaking changes and fix them step by step. For example, Angular 16 has dropped support for
ViewEngine
libraries, so you need to make sure that all your dependencies are already supportingIvy
. If not, you need to update them first. In some rare cases, you might even need to replace those dependencies. At least that's what I did in my projects.
Now let's assume you've successfully updated your project to Angular 17 and all your 3rd party dependencies (except the ones like eslint
) are as well up-to-date. Let's move on to the next migration step.
New control flow migration
Angular 17 ships with its new template control flow syntax. The Angular team wanted to improve the framework performance and also the developer experience. At first glance the new syntax looked a bit awkward (like PHP) to me, I must confess. However, you'll get used to it pretty fast. The handling of code>@for loops during runtime is up to 90% faster according to independent benchmarks:
Running the migration schematic
The Angular CLI doesn't automatically migrate your project. To migrate your Angular HTML templates to the new control flow syntax, you can use this Angular CLI
schematic:
ng g @angular/core:control-flow
Manual improvements & clean up
While the migration schematic hopefully (and in my experience actually) doesn't produce any errors or bugs, you might want to improve and clean up your code manually afterward.
Here is some general advice on the new control flow:
- Check your
@if
blocks. You might want to reduce complexity here and there by using the@else if
and@else
. This will make your HTML templates more readable and thus more maintainable. - Check your
@for
blocks. You might want to add the@empty
block β again cleaning up your HTML templates. Also, make sure you're using the now mandatorytrack
intelligently. - Enforce the new control flow syntax in your team. You might want to add the corresponding
@angular-eslint
rule to youreslint
configuration:"files": ["*.html"], "rules": { "@angular-eslint/template/prefer-control-flow": "warn",
- Since you're now using the new control flow syntax, think about introducing
@defer
blocks for heavyweight components in your app.
Adding @defer for lazy-loading of components
To learn how to use code>@defer, check out my blog post Angular 17βs Deferrable Views. Make sure to use code>@defer especially for large dependencies: How to lazy load large 3rd-party deps with Angular 17βs @defer.
Now let's assume you've successfully migrated your HTML templates. Let's move on to the final migration step.
Application builder migration
Angular 16 introduced the new application builder β using modern tools esbuild and Vite β which has now become the default builder for new projects in Angular 17. If you haven't switched to the new builder yet, you should try it now. It is definitely faster and also said-to-be more reliable than the old one, and it even results in a slightly smaller build size π
To switch existing Angular apps to the new builder, you need to run the update script or edit your angular.json
(or project.json
for Nx projects).
Changing the app builders automatically
Run this special update script to update all app builders automatically:
ng update @angular/cli --name use-application-builder
Changing the app builder in angular.json
In your angular.json
, you would typically find:
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
Changing the builder field is the first change you will need to make:
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:application",
Additionally, you need to rename main
to browser
within the build target. Here is a table of changes copied from the Angular Docs on esbuild:
If you're using SSR make sure to change the builder in the server
targets as well.
Replacing webpack bundle analyzer
Since were not using webpack
anymore, you need to replace the webpack-bundle-analyzer
as well. Here are some tools you can use to analyze your Vite bundles:
- source-map-explorer (works with both webpack and Vite)
npx source-map-explorer dist/[app-name]/browser/**/*.js --no-border-checks
- vite-bundle-visualizer
npx vite-bundle-visualizer -i dist/[app-name]/browser/index.html
- To find the source Treemap feature of Google Lighthouse DevTools, look at this screenshot:
Please feel very free to contact me via email, X or LinkedIn if you have any other tool you'd like to recommend (and have it mentioned here) or if you have any other question or feedback concerning this blog post.
Conclusion
Angular 17 is already pretty stable, so it's time to update and migrate your Angular projects today.
In this post, we've shown you how to update Angular including 3rd-party packages and how to migrate to the new control flow and the new application builder using esbuild and Vite.
References
- Angular Update Guide V16 --> V17
- Angular Docs: control flow guide
- Angular 17βs Deferrable Views by Alex Thalhammer
- How to lazy load large 3rd-party deps with Angular 17βs @defer by Alex Thalhammer
- Angular Docs: esbuild guide
Workshops
If you want to deep dive into Angular, we offer a variety of workshops - both in English and German.
- Accessibility Workshop βΏ
- Performance Workshop π
- NG Styling Workshop π¨
This blog post was written by Alex Thalhammer. Follow me on GitHub, X or LinkedIn.