Member preview

How to Migrate from angular 4 to 5

The “Pentagonal-donut” a.k.a Angular5 is released. It is time for all ngx-* projects to start supporting angular5 and live on the edge.

This release, under the hood, brings us a lot of improvements, newer features and (as usual) some breaking changes.

One of the coolest features is build optimizer, which is applied by default in a production build. It strips down the decorators, which is apparently not needed in the runtime (saving some bytes) and then marks the pure functions in your code (which will be used by existing tools like rollup for tree shaking) saving few more precious bytes in your bundles.

The full list of angular5 changelog (including improvements, newer features, and breaking changes) are listed here and explained in detail here.


Right from Angular2, development builds are spitting out huge files, that needs extra attention when we need to ship this into production.

ng serve output

Similarly In Angular5, it takes 5.7s to build and 7.3MB bundle size for a basic app generated by angular-cli.

ng serve — aot

On the other hand, aot builds without minification and suppling prod flags takes around 4.9s and 4.1MB bundle size (Note: AOT compilation is much faster than the normal build)

ng serve — aot — prod

With — prod flag, it takes around 16s to build and the bundle size is around 108KB

There is a significant reduction in the build time, but the bundle size is the one that needs to be worked on.


If you are tired of regular benchmarks with angular cli generated app and interested in more of a real-world example, here we go.

For this example, we will take a sample JHipster application, share our story of what we did to migrate to angular 5 and will see the issues that we faced.

If you haven’t heard about JHipster, you should definitely check it here. It is an open-source project for generating web application with all the latest and greatest technologies bundled together. It generates a Java-based web application with spring boot in the backend and then Angular (1 & X)/ React at the frontend. If you are doing full stack development and interested to learn how to do things faster and more awesome you should check out here.

You can find the bundle differences between angular4 and angular5 below,

The vendor file alone increased from 9.9 MB to 12 MB in the development build (note: it also includes all the vendor libraries not only the angular core libraries). On the other hand a 16KB increase in the production build. But the build time is reduced significantly. So, we can use aot builds even in development with source map enabled for debugging.

The migration was not that difficult compared to previous angular migration ( have you used ng-upgrade and ran in hybrid mode) but it still had some bottlenecks, sleepless nights and more doses of caffeine.

First, of all, before migrating you should use this amazing website. This neatly lists down what are the things that we need to consider when we migrate from angular 4 to 5 (ofcourse from any version to any version in angular).

replace <template> tags to <ng-template>

replace opaqueToken with injectionToken (Most libraries released a new version because of this)

replace ngOutletContext with ngTemplateOutletContext

replace trackByFn with trackByFunction

If you are using typescript version other than 2.4.2, please upgrade or downgrade to exact 2.4.2 version. Using any other version will result in this error

Uncaught Error: Unexpected value ‘[object Object]’ imported by the module ‘AppModule’. Please add a @NgModule annotation

This is also applicable to any of your imported libraries. That is if any of your libraries are using the advanced version of typescript they should downgrade to this particular version or you have to wait till that happens.

There is also a new HttpClient Module available, this was added to the angular common package.

import { HttpClientModule, HttpClient } from '@angular/common/http';

But it is not a drop-in replacement for the Http service if you have used it before from @angular/http

That is if you have used the interceptors and hacked into http requests and responses, then you have to make sure that you have to remove them completely before migrating to the newer version. But happily we can use the existing code and we still have untill angular6to complete this.

In our case, custom http interceptor is used. Since previous versions of angular we need to have a custom http interceptor and then use requestInterceptor and responseInterceptor, to hack into the requests and responses. We can get rid of that boilerplate, once we started usinghttpClientModule.

Dependencies for the services that you import into modules should be specified explicitly. This was the toughest one to figure out and spent a lot of time on this particular stuff. In ≤ Angular 4, we just have to specify the services that a library is exporting as in below,

export class NgJhipsterModule {
static forRoot(moduleConfig: JhiModuleConfig): ModuleWithProviders {
return {
ngModule: NgJhipsterModule,
providers: [
...JHI_SERVICES,
JhiLanguageService,
JhiAlertService,
JhiConfigService,
{ provide: JhiModuleConfig,
useValue: moduleConfig }
]
};
}

But from Angular5, we need to explicitly say the dependencies like below,

export class NgJhipsterModule {
static forRoot(moduleConfig: JhiModuleConfig): ModuleWithProviders {
return {
ngModule: NgJhipsterModule,
providers: [
...JHI_SERVICES,
{ provide: JhiLanguageService,
useClass: JhiLanguageService,
deps: [TranslateService, JhiConfigService] },
{ provide: JhiAlertService,
useClass: JhiAlertService,
deps: [Sanitizer, JhiConfigService, TranslateService] },
{ provide: JhiModuleConfig,
useValue: moduleConfig },
{ provide: JhiConfigService,
useClass: JhiConfigService,
deps: [JhiModuleConfig] }
]
};
}

else, it will throw an error can't resolve all parameters for your service(?)

Finally, I personally feel that the people’s interest level in angular is getting decreased and it is always a bumpy ride for us to move to future angular versions. Hopefully this gets resolved in the future releases. And most importantly looking forward, how the bundle size is getting reduced.

You can check for more information on the code over here,

Update: 5.1 is out last week, it includes improved error message when the decorators contain unsupported or incorrect expressions.

It also added typescript 2.5.x support. Typescript 2.5, added optional catch support, type assertion for your Javascript files (if you have any) and more importantly --preserveSymlinks (preventing errors that are thrown when working with linked npm modules) (check out here)

5.1 update also added improved service-worker support via angular-cli. Add service worker to your site. Added App-shell support too (making it easier to generate PWAs).

We have a PR in JHipster already to support angular 5.1.0 ❤️