Package Exports
- @angularclass/hmr
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@angularclass/hmr) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Angular 2 Hot Module Replacement
Angular2-HMR
npm install @angularclass/hmr @angularclass/hmr-loader
Please see repository AngularClass/angular2-seed for a working example.
Also download AngularClass/angular2-hmr-loader
main.browser.ts
import { removeNgStyles, createNewHosts, bootloader } from '@angularclass/hmr';
@NgModule({
bootstrap: [ App ],
declarations: [ App ],
imports: [
// Angular 2
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot([], {
useHash: true
}),
// app
appModule
// vendors
],
providers: []
})
class MainModule {
constructor(public appRef: 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' in store) {
store.restoreInputValues();
}
// change detection
this.appRef.tick();
delete store.state;
delete store.restoreInputValues;
}
hmrOnDestroy(store) {
var cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement);
// recreate elements
store.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 values
store.restoreInputValues = createInputTransfer();
// remove styles
removeNgStyles();
}
hmrAfterDestroy(store) {
// display new elements
store.disposeOldHosts()
delete store.disposeOldHosts;
// anything you need done the component is removed
}
}
export function main() {
return platformBrowserDynamic().bootstrapModule(MainModule);
}
// boot on document ready
bootloader(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.
Important Helpers
- 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
Production
In production you only need bootloader which just does this:
export function bootloader(main) {
if (document.readyState === 'complete') {
main()
} else {
document.addEventListener('DOMContentLoaded', main);
}
}
You would bootstrap your app the normal way, in production, afer dom is ready. Also, in production, you should remove the loader:
{
test: /\.ts$/,
loaders: [
'awesome-typescript-loader',
].concat(prod ? [] : '@angularclass/hmr-loader')
},
enjoy — AngularClass
Learn AngularJS, Angular 2, and Modern Web Development from the best. Looking for corporate Angular training, want to host us, or Angular consulting? patrick@angularclass.com