DEV Community

Cover image for Lazy load AngularJS app from modern Angular project
Hank Chiu
Hank Chiu

Posted on

Lazy load AngularJS app from modern Angular project

Background

AngularJS was deprecated in 2018 and the Angular team has been working on Angular 2+ since 2016 (currently Angular v19!). AngularJS is still widely used in many projects and it is not easy to migrate to Angular 2+ in a short time.
I proposed a technique in this post to demonstrate lazy-loading AngularJS apps from modern Angular projects without changing the existing AngularJS code too much.

Rationale

While Angular officially provides @angular/upgrade, it suggests a progressive migration approach. However, a medium to large project often leaves an intermediate state in business logic scattered between AngularJS and Angular 2+. It is not easy to maintain and test the code in such a state.
Lazy-loading is a technique to connect the whole legacy logic as is, and gradually migrate the code to Angular 2+ later.

Show me the code

If you are in a hurry, you can check the code in this repository: https://github.com/hankchiutw/ng1-migration-example

How it works in a nutshell

The key is to bootstrap the AngularJS app manually by angular.bootstrap, instead of using ng-app in the template.

Step 1: Wrap main AngularJS code in controllers and directives

Your Angular project will render the AngularJS directive. Here is a minimal example of AngularJS code:

const ng1Module = angular.module('myApp', []);
angular.module('myApp').directive('myAppRoot', () => ({
  controller: MainController,
  template: `my AngularJS app`,
}));
Enter fullscreen mode Exit fullscreen mode

Tips: You can set loader option in angular.json to separate the template as a html file.

// angular.json
  "builder": "@angular-devkit/build-angular:application",
  "options": {
    "loader": {
      ".html": "text"
    },
Enter fullscreen mode Exit fullscreen mode
import template from './ng1-app.html';

angular.module('myApp').directive('myAppRoot', () => ({
  controller: MainController,
  template,
}));
Enter fullscreen mode Exit fullscreen mode

Step 2: Bootstrap AngularJS app in Angular project

A reasonable place to bootstrap AngularJS app is in ngOnInit of Angular component. The key is to ensure the AngularJS module is loaded before bootstrapping the AngularJS app. Here is an example:

import { ng1Module } from './ng1-app/ng1-app';

ngOnInit() {
  angular.bootstrap(this.elRef.nativeElement, [ng1Module.name]);
}
Enter fullscreen mode Exit fullscreen mode

If your AngularJS code is really fat, you can use import() to load the AngularJS code dynamically. Here is an example:

ngOnInit() {
  import('./ng1-app/ng1-app').then(({ ng1Module }) => {
    angular.bootstrap(this.elRef.nativeElement, [ng1Module.name]);
  });
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Lazy-loading gives you the flexibility of choosing different migration strategies. You can migrate the whole AngularJS app to Angular 2+ at once, or migrate feature by feature. It is a good way to keep the project maintainable and testable during the migration process.


Practically, your AngularJS app may have more complex logic and dependencies. You may need to adjust the code to fit your project. However, the basic idea is the same. I hope this post can help you to migrate your AngularJS project to Angular 2+ more smoothly.
If you have any specific use cases want to discuss(e.g. use AngularJS and Angular routing together), feel free to leave a comment below. I am happy to discuss with you. Thank you for reading!

Top comments (0)