Skip to content

Commit e238698

Browse files
committed
Introduce hot module replacement
1 parent ac86ee6 commit e238698

File tree

7 files changed

+79
-10
lines changed

7 files changed

+79
-10
lines changed

config/helpers.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
var path = require('path');
2-
var _root = path.resolve(__dirname, '..');
1+
const path = require('path');
2+
const _root = path.resolve(__dirname, '..');
33

44
function hasProcessFlag(flag) {
55
return process.argv.join('').indexOf(flag) > -1;
@@ -10,5 +10,10 @@ function root(args) {
1010
return path.join.apply(path, [_root].concat(args));
1111
}
1212

13+
function prod() {
14+
return process.env.NODE_ENV === 'production';
15+
}
16+
1317
exports.hasProcessFlag = hasProcessFlag;
1418
exports.root = root;
19+
exports.prod = prod;

config/webpack.common.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ module.exports = {
2121
{
2222
test: /\.ts$/,
2323
loaders: [
24+
'@angularclass/hmr-loader',
2425
'awesome-typescript-loader',
2526
'angular2-template-loader',
2627
'angular2-router-loader?loader=system',

config/webpack.dev.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ module.exports = webpackMerge(commonConfig, {
1212
filename: '[name].js',
1313
sourceMapFilename: '[name].map',
1414
chunkFilename: '[id].chunk.js',
15-
publicPath: '/'
15+
// required for hot module replacement
16+
publicPath: 'http://localhost:4200/',
1617
},
1718
plugins: [
1819
new webpack.DefinePlugin({

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"prebuild:prod": "yarn run clean:dist",
1717
"build:prod": "yarn run ngc && webpack --config config/webpack.aot.js --progress --profile --bail",
1818
"server": "yarn run server:dev",
19-
"server:dev": "webpack-dev-server --config config/webpack.dev.js --progress --profile --watch --content-base src/",
19+
"server:dev": "webpack-dev-server --config config/webpack.dev.js --progress --profile --hot --watch --content-base src/",
2020
"server:prod": "node server.js",
2121
"test": "karma start",
2222
"test:watch": "yarn run karma:watch",
@@ -44,6 +44,8 @@
4444
"@angular/platform-browser": "^2.1.0",
4545
"@angular/platform-browser-dynamic": "^2.1.0",
4646
"@angular/router": "^3.1.0",
47+
"@angularclass/hmr": "^1.2.2",
48+
"@angularclass/hmr-loader": "^3.0.2",
4749
"aphrodite": "^1.0.0",
4850
"bootstrap": "^4.0.0-alpha.4",
4951
"core-js": "^2.4.1",

src/app/app.module.ts

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {NgModule} from "@angular/core";
1+
import {NgModule, ApplicationRef} from "@angular/core";
22
import {BrowserModule} from "@angular/platform-browser";
33
import {RouterModule, PreloadAllModules} from "@angular/router";
44
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
@@ -12,7 +12,11 @@ import {TopModule} from "./pages/top/top.module";
1212
import {NoContentComponent} from "./pages/no-content/no-content.component";
1313
import {HeaderModule} from "./components/header/header.module";
1414
import {SharedModule} from "./shared/shared.module";
15-
import {ToastModule} from "./core/toast/toast.module";
15+
import {
16+
removeNgStyles,
17+
createInputTransfer,
18+
createNewHosts
19+
} from "@angularclass/hmr";
1620

1721
@NgModule({
1822
bootstrap: [AppComponent],
@@ -40,5 +44,44 @@ import {ToastModule} from "./core/toast/toast.module";
4044
]
4145
})
4246
export class AppModule {
47+
constructor(public appRef: ApplicationRef) {
48+
}
49+
50+
hmrOnInit(store) {
51+
if (!store || !store.state) return;
52+
console.log('HMR store', store);
53+
console.log('store.state.data:', store.state.data);
54+
// inject AppStore here and update it
55+
// this.AppStore.update(store.state)
56+
if ('restoreInputValues' in store) {
57+
store.restoreInputValues();
58+
}
59+
// change detection
60+
this.appRef.tick();
61+
delete store.state;
62+
delete store.restoreInputValues;
63+
}
64+
65+
hmrOnDestroy(store) {
66+
const cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement);
67+
// recreate elements
68+
store.disposeOldHosts = createNewHosts(cmpLocation);
69+
// inject your AppStore and grab state then set it on store
70+
// var appState = this.AppStore.get()
71+
store.state = {data: 'yolo'};
72+
// store.state = Object.assign({}, appState)
73+
// save input values
74+
store.restoreInputValues = createInputTransfer();
75+
// remove styles
76+
removeNgStyles();
77+
}
78+
79+
hmrAfterDestroy(store) {
80+
// display new elements
81+
store.disposeOldHosts();
82+
delete store.disposeOldHosts;
83+
// anything you need done the component is removed
84+
}
85+
4386
}
4487

src/main.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
import {platformBrowserDynamic} from "@angular/platform-browser-dynamic";
22
import {AppModule} from "./app";
33
import {decorateModuleRef} from "./app/environment";
4+
import {bootloader} from "@angularclass/hmr";
5+
6+
export function main(): Promise<any> {
7+
return platformBrowserDynamic()
8+
.bootstrapModule(AppModule)
9+
.then(decorateModuleRef)
10+
.catch(err => console.error(err));
11+
}
12+
13+
// needed for hmr
14+
bootloader(main);
415

5-
platformBrowserDynamic()
6-
.bootstrapModule(AppModule)
7-
.then(decorateModuleRef)
8-
.catch(err => console.error(err));

yarn.lock

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@
5252
dependencies:
5353
tsickle "^0.1.7"
5454

55+
"@angularclass/hmr":
56+
version "1.2.2"
57+
resolved "https://registry.yarnpkg.com/@angularclass/hmr/-/hmr-1.2.2.tgz#46a18f89a1e94d05c268b83c9480e005f73fc265"
58+
59+
"@angularclass/hmr-loader":
60+
version "3.0.2"
61+
resolved "https://registry.yarnpkg.com/@angularclass/hmr-loader/-/hmr-loader-3.0.2.tgz#c789182411f09d0b98929e6acbfd3e4aeaace597"
62+
dependencies:
63+
loader-utils "^0.2.15"
64+
5565
"@types/jasmine@^2.5.35":
5666
version "2.5.37"
5767
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-2.5.37.tgz#15f16040b1106941ec4aeefa3cd9c55342a0dcbb"

0 commit comments

Comments
 (0)