Skip to content

Commit 1e92c7b

Browse files
Alexander Vakrilovsis0k0
Alexander Vakrilov
authored andcommitted
feat: HMR bootstrap and livesync options (#1531)
Pass `hmr` specific options on application bootstrap. The hmr options are: - `moduleTypeFactory?: () => Type<any> | NgModuleFactory<any>;` A module factory for re-instantiating the bootstrap module or module-factory on livesync. - `livesyncCallback: (bootstrapPlatfrom: () => void) => void;` A `livesync` callback that will be called instead of the original livesync. It gives the `hmr` a hook to apply the module replacement. The callback also accepts `bootstrapPlatfrom` function which triggers bootstrap of the angular app with the existing platform using the `moduleTypeFactory` to get module/module-factory to be used.
1 parent d9bebc5 commit 1e92c7b

File tree

1 file changed

+49
-4
lines changed

1 file changed

+49
-4
lines changed

Diff for: nativescript-angular/platform-common.ts

+49-4
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,34 @@ if ((<any>global).___TS_UNUSED) {
5050
return InjectionToken;
5151
})();
5252
}
53+
54+
// tslint:disable:max-line-length
55+
/**
56+
* Options to be passed when HMR is enabled
57+
*/
58+
export interface HmrOptions {
59+
/**
60+
* A factory function that returns either Module type or NgModuleFactory type.
61+
* This needs to be a factory function as the types will change when modules are replaced.
62+
*/
63+
moduleTypeFactory?: () => Type<any> | NgModuleFactory<any>;
64+
65+
/**
66+
* A livesync callback that will be called instead of the original livesync.
67+
* It gives the HMR a hook to apply the module replacement.
68+
* @param bootstrapPlatform - A bootstrap callback to be called after HMR is done. It will bootstrap a new angular app within the exisiting platform, using the moduleTypeFactory to get the Module or NgModuleFactory to be used.
69+
*/
70+
livesyncCallback: (bootstrapPlatform: () => void) => void;
71+
}
72+
// tslint:enable:max-line-length
73+
74+
5375
export interface AppOptions {
5476
bootInExistingPage?: boolean;
5577
cssFile?: string;
5678
startPageActionBarHidden?: boolean;
5779
createFrameOnBootstrap?: boolean;
80+
hmrOptions?: HmrOptions;
5881
}
5982

6083
export type PlatformFactory = (extraProviders?: StaticProvider[]) => PlatformRef;
@@ -91,7 +114,14 @@ export class NativeScriptPlatformRef extends PlatformRef {
91114

92115
@profile
93116
bootstrapModuleFactory<M>(moduleFactory: NgModuleFactory<M>): Promise<NgModuleRef<M>> {
94-
this._bootstrapper = () => this.platform.bootstrapModuleFactory(moduleFactory);
117+
this._bootstrapper = () => {
118+
let bootstrapFactory = moduleFactory;
119+
if (this.appOptions.hmrOptions) {
120+
bootstrapFactory = <NgModuleFactory<M>>this.appOptions.hmrOptions.moduleTypeFactory();
121+
}
122+
123+
return this.platform.bootstrapModuleFactory(bootstrapFactory);
124+
};
95125

96126
this.bootstrapApp();
97127

@@ -103,8 +133,14 @@ export class NativeScriptPlatformRef extends PlatformRef {
103133
moduleType: Type<M>,
104134
compilerOptions: CompilerOptions | CompilerOptions[] = []
105135
): Promise<NgModuleRef<M>> {
106-
this._bootstrapper = () => this.platform.bootstrapModule(moduleType, compilerOptions);
136+
this._bootstrapper = () => {
137+
let bootstrapType = moduleType;
138+
if (this.appOptions.hmrOptions) {
139+
bootstrapType = <Type<M>>this.appOptions.hmrOptions.moduleTypeFactory();
140+
}
107141

142+
return this.platform.bootstrapModule(bootstrapType, compilerOptions);
143+
};
108144
this.bootstrapApp();
109145

110146
return null; // Make the compiler happy
@@ -113,7 +149,11 @@ export class NativeScriptPlatformRef extends PlatformRef {
113149
@profile
114150
private bootstrapApp() {
115151
(<any>global).__onLiveSyncCore = () => {
116-
this._livesync();
152+
if (this.appOptions.hmrOptions) {
153+
this.appOptions.hmrOptions.livesyncCallback(() => this._livesync());
154+
} else {
155+
this._livesync();
156+
}
117157
};
118158

119159
if (this.appOptions && typeof this.appOptions.cssFile === "string") {
@@ -224,7 +264,12 @@ export class NativeScriptPlatformRef extends PlatformRef {
224264
if (isLogEnabled()) {
225265
bootstrapLog("Angular livesync started.");
226266
}
227-
onBeforeLivesync.next(lastBootstrappedModule ? lastBootstrappedModule.get() : null);
267+
268+
const lastModuleRef = lastBootstrappedModule ? lastBootstrappedModule.get() : null;
269+
onBeforeLivesync.next(lastModuleRef);
270+
if (lastModuleRef) {
271+
lastModuleRef.destroy();
272+
}
228273

229274
const autoCreateFrame = !!this.appOptions.createFrameOnBootstrap;
230275
let tempAppHostView: AppHostView;

0 commit comments

Comments
 (0)