This is what I use for the latest Angular, working just fine. You can give it a try...
// main.ts
import { bootloader, createInputTransfer, createNewHosts, removeNgStyles }
from '@angularclass/hmr/dist/helpers'; // For correct treeshaking
if (environment.production) {
enableProdMode();
}
type HmrModule<S> = { appRef: ApplicationRef }
type HmrNgrxModule<S, A> = HmrModule<S> & {
store: { dispatch: (A) => any } & Observable<S>,
actionCreator: (s: S) => A
}
const isNgrxModule = <S, A, M extends HmrNgrxModule<S, A>>
(instance: HmrModule<S> | HmrNgrxModule<S, A>): instance is M =>
!!((<M>instance).store && (<M>instance).actionCreator);
function processModule<S, A, M extends HmrModule<S> | HmrNgrxModule<S, A>>(ngModuleRef: NgModuleRef<M>) {
const hot = module['hot'];
if (hot) {
hot['accept']();
const instance = ngModuleRef.instance;
const hmrStore = hot['data'];
if (hmrStore) {
hmrStore.rootState
&& isNgrxModule(instance)
&& instance.store.dispatch(instance.actionCreator(hmrStore.rootState));
hmrStore.restoreInputValues && hmrStore.restoreInputValues();
instance.appRef.tick();
Object.keys(hmrStore).forEach(prop => delete hmrStore[prop]);
}
hot['dispose'](hmrStore => {
isNgrxModule(instance) && instance.store.pipe(take(1)).subscribe(s => hmrStore.rootState = s);
const cmpLocation = instance.appRef.components.map(cmp => cmp.location.nativeElement);
const disposeOldHosts = createNewHosts(cmpLocation);
hmrStore.restoreInputValues = createInputTransfer();
removeNgStyles();
ngModuleRef.destroy();
disposeOldHosts();
});
}
else {
console.error('HMR is not enabled for webpack-dev-server!');
console.log('Are you using the --hmr flag for ng serve?');
}
return ngModuleRef;
}
const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule);
const hmrBootstrap = () => bootloader(() => bootstrap().then(processModule));
environment.hmr
? hmrBootstrap()
: bootstrap();
// app.module.ts
@NgModule({ ... })
export class AppModule {
constructor(public appRef: ApplicationRef) { ... }
}
The HMR
setup will work with Ngrx store as well, if you are into this sort of stuff. You can omit the Ngrx-handling code, though.
Hope this helps a little :-)