Real-world Angular Ivy Upgrade

Jared Youtsey
ngconf
4 min readSep 17, 2019

--

Angular’s new rendering engine, Ivy, holds great promise for the future of Angular and what we can do with it. Is your product ready for Ivy? With Angular v8 you can preview what your migration is likely to look like.

It is worth pointing out that Angular v8 Ivy is a tech preview and is not suited for production. Some of the items in this article will be fixed/changed with v9 and may have been already. I used the preview for its intended purpose, to determine whether or not we would have major issues in the near future and how to buffer against them. There may have been some advantage to trying with @next, but I didn’t want to look at Angular v9 at the same time.

Let’s take a look at a real-world, production application in Angular v8 and what had to be done to get it running with the Ivy preview. This is a large application with many dependencies, leveraging complex parts of the Angular architecture.

Up front, I don’t expect you to have the same experience as I did. Ivy is evolving every day, and is not yet ready for production. But, I ran into some error messages that did not have StackOverflow postings or articles that discussed solutions. This will document those errors and what was required to fix them.

I started here:

https://angular.io/guide/ivy

The first step was to make sure that the project was at the latest version of Angular and all of its dependencies. I use a Visual Studio Code extension called Version Lens by pflannery to help with this. This extension highlights both the current version and the latest versions. Clicking on the “latest” link will update package.json to the latest version.

Next, I ran npm install on my project to update it and then attempted to ng serve. However, I got an error about needing to delete node_modules. Although deleting and reinstalling does work, there is an alternate route. Ivy comes with an additional compiler, ngcc. This compiles your third party dependencies for compatibility. The CLI seemed to do this for me when I deleted my node_modules folder and reinstalled.

The lint rules seem a bit more aggressive. I had to ensure that component names end with the word “Component”. I had one outlier…

polyfills.ts: I do have to support IE 11, so I have one polyfill that, for some reason, the conditional polyfills solution in Angular doesn’t include, “array”. The pre-ivy import for this was

import 'core-js/es7/array';

The post-ivy import is:

import 'core-js/es/array'

Subtle, but important. The error I received was “Can’t resolve ‘core-js/es7/reflect’.”

tsconfig.app.json: This is a documented touchpoint for the upgrade. It needed a bit more than what’s documented for v8, but in 9.0.0-next.4+ new projects and upgraded ones will automatically get the added include:

"angularCompilerOptions": {
"enableIvy": true
},
"include": ["main.ts", "polyfills.ts"],

With v8, there were lots of warnings: “WARNING in someTSfile is part of the TypeScript compilation but it's unused. Add only entry points to the 'files' or 'include' properties in your tsconfig.” The only two entry points in an Angular application are main.ts and polyfills.ts, so adding them to the includes ensures that the app works and the warnings are reduced. In my case, even with the include, three warnings remain, and no matter what I do I cannot make them go away. I have opened an issue with Google about this warning and will update this article should I get a reply that solves the issue.

angular.json: This one follows the official Angular documentation:

"projects": {
"my-existing-project": {
"architect": {
"build": {
"options": {
...
"aot": true,

And now, for something truly bizarre… (This should be fixed in Angular v9-next Ivy styling changes that recently were added.)

We had some templates where there was a binding on a component and a class binding with the same name, like this:

<app-my-comp
[class.nonunique]="someBool"
[nonunique]="something"
></app-my-comp>

Ivy responded with “An object literal cannot have multiple properties with the same name in strict mode.”. It took a while to understand why this was so, but the solution was fairly simple, use ngClass instead of class.name bindings:

<app-my-comp
[ngClass]="{ nonunique: someBool }"
[nonunique]="something"
></app-my-comp>

As each code base is different, you’re bound to run into some other subtleties. I have not provided module size or performance savings as v8 did not target those Ivy benefits we are all looking forward to. To really get a better feel for that, I may follow up with an attempt using 9.0.0-next which is targeting those improvements. I’d love to hear about them, or if you have any interesting tidbits about upgrading a real application to Ivy.

EnterpriseNG is coming November 4th & 5th, 2021.

Come hear top community speakers, experts, leaders, and the Angular team present for 2 stacked days on everything you need to make the most of Angular in your enterprise applications.
Topics will be focused on the following four areas:
• Monorepos
• Micro frontends
• Performance & Scalability
• Maintainability & Quality
Learn more here >> https://enterprise.ng-conf.org/

--

--

Jared Youtsey
ngconf
Editor for

Passionate about JavaScript and Angular. Pure front-end development for the past eight years or so…