תוצאת תמונה עבור ‪angular migration‬‏

Migrating from AngularJS to Angular - A brand new strategy

Uri Shmueli
4 min readDec 12, 2018

There are many companies out there that still use the great AngularJS framework, and I do personally think it’s a great front end framework, that has a lot of power, as long as you use it right!

I won’t dive into how to use it right, this is not the purpose of this article, but I write this article for those who’d like to experience and do the next step for the latest Angular framework, but still have millions lines of code.

Who is this article for?

  • You’re a company that maintains million lines of code, using AngularJS (1.x)
  • You’re required to keep delivering new features to your clients
  • You’d like to continue delivering and still use existing old services and utilities
  • During the migration, you don’t want to maintain both AngularJS and Angular code

What other migration strategies are out there?

These are the most commonly used strategies, and their disadvantages comparing to the strategy discussed later

  • NgUpgrade – I personally experienced numerous performance issues as both Angular and AngularJS framework run Change Detection mechanism, and rewriting existing code might lead to duplicate services or components at some period of time, one in Angular and one in AngularJS
  • Iframe – have duplicate services and components (old and new), need to bootstrap both frameworks which can cause performance issues in older browser

The common pitfalls for current migration strategies

As you understand from above, in all existing strategies you always need to run both frameworks (old and new) in order to perform the migration process.

Running both frameworks, in a hybrid mode, reduces application performance and eventually leaves you in this mode forever as the migration might never end.

Introducing ng-metadata

Imagine if you could write Angular (2+) code today and rewrite your JS code to Angular (2+) syntax, but still keep a single framework running — no performance degradation!

With this library, you could use the syntax and power of Angular (2+), as if you have the Angular framework running, including the @Component, @NgModule, @Injectable decorators, change detection events (ngOnChanges(changes: SimpleChanges ), html binding decorators ([data], (events)), etc…

Visit this great page below for further information

A high-level overview of the ng-metadata migration strategy (aka TL’DR)

  1. Start writing your new features in the ‘Angular’ (2+) way (using ng-metadata), make sure not to be coupled to any $scope or AngularJS dependencies
  2. On going, rewrite your existing code to ng-metadata (notice that this step will take the longest time in the migration process)
  3. Once done with steps 1 and 2, you should have all your code the Angular (2+) way
  4. Have the third party libraries API agnostic to your code, so when it’s time to replace them, your code won’t get broken
  5. Create an Angular (2+) router file, based on your current ui-router
  6. Install the Angular (2+) supported third party libraries
  7. Remove ng-metadata from your dependencies and replace them with the latest @angular dependencies
  8. You’ll notice that in my github repository, and my examples here, I don’t use ng-metadata directly. This is a good practice where you’re planning to refactor or use a third-party library, having a “buffer-zone” class that exports the necessary code and can be replaced in a single place when needed.
  9. Replace the AngularJS bootstrap to Angular
  10. Welcome to Angular!

Start migrating!

Let’s now begin our migration process.

Visit my github page and check-out the branches for each step.

Step 1 – Install ng-metadata

Install the following npm packages

npm install ng-metadata

npm install reflect-metadata

Step 2 – Start writing Components, Modules and Services — the Angular (2+) way!

A new service

  1. Notice @Injectable('newService') where we definenewService as a string token, which is optional, but this actually gives us the ability to inject this service into ‘older’ services. (AngularJS idenitifes the injectable services by string token, whereas Angular does it by a class name as it uses Typescript)
  2. I don’t import anything from ng metadata but from my-decorators as I mentioned in the high level steps above, as a single source where ng-metadata dependencies are imported, so later on I’ll be able to replace the ng-metadata into angular libs, in just one place

A new component

The $ctrlwould be removed later on when finally replace the framework to Angular.

A new module

Step 3 – bundle the AppModule into our JS application

Notice the ng-metadata’s bundle method that ‘glues’ the new AppModule to our existing AngularJS main module

Step 4 – Ongoing changes, New and Old services

Because we declared a string token in Step 1 @Injectable('newService) we can use our service in our existing components and services as injectable.

What’s next?

Now, go ahead and rewrite your components into the Angular syntax, and make sure you keep some development time for replacing the ui-router, third-party libraries, and existing AngularJS directives (ng-if to be ngIf, ng-repeat to be ngFor, etc…)

Last thing…

I’d like to thank Dima Abramovich (LinkedIn profile below) which helped a lot with this great and out-of-the-box migration process

Questions?

Feel free to contact me in any social media.

--

--

Uri Shmueli

A full-stack software developer, a Team Leader and Front-end frameworks lover!