We're using the upgrade adapter to setup an Angular 1/2 Hybrid app. We're bootstrapping the app like this (As described in the Angular docs https://angular.io/guide/upgrade):
class AppModule {
constructor(private upgrade: UpgradeModule) { }
ngDoBootstrap() {
this.upgrade.bootstrap(document.body, ['ngApp'], { strictDi: true });
}
}
For our HMR setup, we're using Angular CLI and following these instructions https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/configure-hmr.md
The problem is that when HMR runs and tries running that bootstrap code again, it attempts to rebootstrap the Angular 1 app, which results in an error that the Angular 1 module has already been bootstrapped.
Trying to only conditionally run that code if angular 1 hasn't been bootstrapped also won't work, because while the component does refresh, it doesn't reload with the new updates.
We've resorted to something that seems to work, but is less than ideal, which is removing he angular 1 app element, and recreating it, so that the bootstrap doesn't error.
Something like this:
ngDoBootstrap() {
// reinitialize angular 1 app
var element = document.getElementById('ng-app');
let windowRef = <any>window;
if(!windowRef.appContents) {
windowRef.appContents = element.innerHTML;
} else {
document.body.removeChild(element);
element = document.createElement('div');
element.id = 'ng-app';
element.innerHTML = windowRef.appContents;
document.body.appendChild(element);
}
this.upgrade.bootstrap(element, ['ngApp'], { strictDi: true });
}
While a bit hacky, that at least seems to get the HMR working. However, because it is causing the entire angular 1 app to rebootstrap, rather than just refreshing the module that changed, this is only marginally faster than a simple livereload.
Is there any better way to rebootstrap a hybrid app to allow for HMR to work?