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`,
}));
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"
},
import template from './ng1-app.html';
angular.module('myApp').directive('myAppRoot', () => ({
controller: MainController,
template,
}));
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]);
}
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]);
});
}
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)