Angular-HMR Hot Module Reloading for Webpack and Angular. All versions of Angular and Webpack will work with this module
npm install @angularclass/hmr
main.browser.ts
import{removeNgStyles,createNewHosts,bootloader}from'@angularclass/hmr'; @NgModule({bootstrap: [App],declarations: [App],imports: [// Angular 2BrowserModule,FormsModule,HttpModule,RouterModule.forRoot([],{useHash: true}),// appappModule// vendors],providers: []})classMainModule{constructor(publicappRef: ApplicationRef){}hmrOnInit(store){if(!store||!store.state)return;console.log('HMR store',store);console.log('store.state.data:',store.state.data)// inject AppStore here and update it// this.AppStore.update(store.state)if('restoreInputValues'instore){store.restoreInputValues();}// change detectionthis.appRef.tick();deletestore.state;deletestore.restoreInputValues;}hmrOnDestroy(store){varcmpLocation=this.appRef.components.map(cmp=>cmp.location.nativeElement);// recreate elementsstore.disposeOldHosts=createNewHosts(cmpLocation)// inject your AppStore and grab state then set it on store// var appState = this.AppStore.get()store.state={data: 'yolo'};// store.state = Object.assign({}, appState)// save input valuesstore.restoreInputValues=createInputTransfer();// remove stylesremoveNgStyles();}hmrAfterDestroy(store){// display new elementsstore.disposeOldHosts()deletestore.disposeOldHosts;// anything you need done the component is removed}}exportfunctionmain(){returnplatformBrowserDynamic().bootstrapModule(MainModule)// use `hmrModule` or the "@angularclass/hmr-loader".then((ngModuleRef: any)=>{// `module` global ref for webpackhmr// Don't run this in ProdreturnhmrModule(ngModuleRef,module);});}// boot on document readybootloader(main);bootloader is only needed to detect that the dom is ready before bootstraping otherwise bootstrap. This is needed because that dom is already ready during reloading.
- removeNgStyles: remove angular styles
- createNewHosts and disposeOldHosts: recreate root elements for bootstrapping
- bootloader: boot on document ready or boot if it's already ready
- createInputTransfer and restoreInputValues: transfer input DOM state during replacement
In production you only need bootloader which just does this:
exportfunctionbootloader(main){if(document.readyState==='complete'){main()}else{document.addEventListener('DOMContentLoaded',main);}}You would bootstrap your app the normal way, in production, after dom is ready. Also, in production, you should remove the loader:
To hook into NGRX 4 you simply need to supply a reducer to set the state, and include it in your development metaReducers.
// make sure you export for AoTexportfunctionstateSetter(reducer: ActionReducer<any>): ActionReducer<any>{returnfunction(state: any,action: any){if(action.type==='SET_ROOT_STATE'){returnaction.payload;}returnreducer(state,action);};}In your root reducer you can do something like this to include it in your metaReducers. You should access your environment here and only include this in development.
/** * By default, @ngrx/store uses combineReducers with the reducer map to compose * the root meta-reducer. To add more meta-reducers, provide an array of meta-reducers * that will be composed to form the root meta-reducer. */exportconstmetaReducers: ActionReducer<any,any>[]=[stateSetter]Simply supply the metaReducer to the StoreModule and your hmr is hooked in.
StoreModule.forRoot(reducers,{ metaReducers }),enjoy — PatrickJS

