Skip to content

Commit 7a780b9

Browse files
Merge pull request #3876 from NativeScript/trifonov/hmr
feat: add --hmr option
2 parents f50d34c + 9eea83f commit 7a780b9

11 files changed

+41
-35
lines changed

lib/declarations.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -468,10 +468,10 @@ interface IOptions extends ICommonOptions, IBundleString, IPlatformTemplate, IHa
468468
production: boolean; //npm flag
469469
sdk: string;
470470
syncAllFiles: boolean;
471-
liveEdit: boolean;
472471
chrome: boolean;
473472
inspector: boolean; // the counterpart to --chrome
474473
background: string;
474+
hmr: boolean;
475475
}
476476

477477
interface IEnvOptions {

lib/definitions/livesync.d.ts

+12-14
Original file line numberDiff line numberDiff line change
@@ -142,19 +142,13 @@ interface IOptionalSkipWatcher {
142142
/**
143143
* Describes a LiveSync operation.
144144
*/
145-
interface ILiveSyncInfo extends IProjectDir, IEnvOptions, IBundle, IRelease, IOptionalSkipWatcher {
145+
interface ILiveSyncInfo extends IProjectDir, IEnvOptions, IBundle, IRelease, IOptionalSkipWatcher, IHasUseHotModuleReloadOption {
146146
/**
147147
* Defines if all project files should be watched for changes. In case it is not passed, only `app` dir of the project will be watched for changes.
148148
* In case it is set to true, the package.json of the project and node_modules directory will also be watched, so any change there will be transferred to device(s).
149149
*/
150150
watchAllFiles?: boolean;
151151

152-
/**
153-
* Defines if the liveEdit functionality should be used, i.e. LiveSync of .js files without restart.
154-
* NOTE: Currently this is available only for iOS.
155-
*/
156-
useLiveEdit?: boolean;
157-
158152
/**
159153
* Forces a build before the initial livesync.
160154
*/
@@ -167,6 +161,13 @@ interface ILiveSyncInfo extends IProjectDir, IEnvOptions, IBundle, IRelease, IOp
167161
timeout: string;
168162
}
169163

164+
interface IHasUseHotModuleReloadOption {
165+
/**
166+
* Defines if the hot module reload should be used.
167+
*/
168+
useHotModuleReload?: boolean;
169+
}
170+
170171
interface ILatestAppPackageInstalledSettings extends IDictionary<IDictionary<boolean>> { /* empty */ }
171172

172173
interface IIsEmulator {
@@ -317,28 +318,25 @@ interface IShouldSkipEmitLiveSyncNotification {
317318
interface IAttachDebuggerOptions extends IDebuggingAdditionalOptions, IEnableDebuggingDeviceOptions, IIsEmulator, IPlatform, IOptionalOutputPath {
318319
}
319320

320-
interface ILiveSyncWatchInfo extends IProjectDataComposition {
321+
interface ILiveSyncWatchInfo extends IProjectDataComposition, IHasUseHotModuleReloadOption {
321322
filesToRemove: string[];
322323
filesToSync: string[];
323324
isReinstalled: boolean;
324325
syncAllFiles: boolean;
325-
useLiveEdit?: boolean;
326326
}
327327

328-
interface ILiveSyncResultInfo {
328+
interface ILiveSyncResultInfo extends IHasUseHotModuleReloadOption {
329329
modifiedFilesData: Mobile.ILocalToDevicePathData[];
330330
isFullSync: boolean;
331331
deviceAppData: Mobile.IDeviceAppData;
332-
useLiveEdit?: boolean;
333332
}
334333

335334
interface IAndroidLiveSyncResultInfo extends ILiveSyncResultInfo, IAndroidLivesyncSyncOperationResult { }
336335

337-
interface IFullSyncInfo extends IProjectDataComposition {
336+
interface IFullSyncInfo extends IProjectDataComposition, IHasUseHotModuleReloadOption {
338337
device: Mobile.IDevice;
339338
watch: boolean;
340339
syncAllFiles: boolean;
341-
useLiveEdit?: boolean;
342340
}
343341

344342
interface IPlatformLiveSyncService {
@@ -434,7 +432,7 @@ interface IAndroidLivesyncTool {
434432
*/
435433
removeFile(filePath: string): Promise<boolean>;
436434
/**
437-
* Removes files
435+
* Removes files
438436
* @param filePaths - Array of files that will be removed.
439437
* @returns {Promise<boolean[]>}
440438
*/

lib/helpers/livesync-command-helper.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper {
102102
emulator: d.isEmulator,
103103
projectDir: this.$projectData.projectDir
104104
}),
105-
skipNativePrepare: additionalOptions && additionalOptions.skipNativePrepare
105+
skipNativePrepare: additionalOptions && additionalOptions.skipNativePrepare,
106106
};
107107

108108
return info;
@@ -116,7 +116,8 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper {
116116
bundle: !!this.$options.bundle,
117117
release: this.$options.release,
118118
env: this.$options.env,
119-
timeout: this.$options.timeout
119+
timeout: this.$options.timeout,
120+
useHotModuleReload: this.$options.hmr
120121
};
121122

122123
await this.$liveSyncService.liveSync(deviceDescriptors, liveSyncInfo);

lib/options.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ export class Options extends commonOptionsLibPath.OptionsBase {
3434
all: { type: OptionType.Boolean },
3535
teamId: { type: OptionType.Object },
3636
syncAllFiles: { type: OptionType.Boolean, default: false },
37-
liveEdit: { type: OptionType.Boolean },
3837
chrome: { type: OptionType.Boolean },
3938
inspector: { type: OptionType.Boolean },
4039
clean: { type: OptionType.Boolean },
4140
watch: { type: OptionType.Boolean, default: true },
4241
background: { type: OptionType.String },
4342
username: { type: OptionType.String },
44-
pluginName: { type: OptionType.String }
43+
pluginName: { type: OptionType.String },
44+
hmr: {type: OptionType.Boolean}
4545
},
4646
$errors, $staticConfig, $settingsService);
4747

@@ -50,6 +50,10 @@ export class Options extends commonOptionsLibPath.OptionsBase {
5050
if (that.justlaunch) {
5151
that.watch = false;
5252
}
53+
54+
if (that.hmr) {
55+
that.bundle = "webpack";
56+
}
5357
}
5458
}
5559
$injector.register("options", Options);

lib/services/livesync/android-device-livesync-service.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export class AndroidDeviceLiveSyncService extends DeviceLiveSyncServiceBase impl
3939
const reloadedSuccessfully = await this.reloadApplicationFiles(deviceAppData, localToDevicePaths);
4040

4141
const canExecuteFastSync = reloadedSuccessfully && !liveSyncInfo.isFullSync && !_.some(localToDevicePaths,
42-
(localToDevicePath: Mobile.ILocalToDevicePathData) => !this.canExecuteFastSync(localToDevicePath.getLocalPath(), projectData, this.device.deviceInfo.platform));
42+
(localToDevicePath: Mobile.ILocalToDevicePathData) => !this.canExecuteFastSync(liveSyncInfo, localToDevicePath.getLocalPath(), projectData, this.device.deviceInfo.platform));
4343

4444
if (!canExecuteFastSync) {
4545
return this.restartApplication(deviceAppData, projectData.projectName);

lib/services/livesync/android-device-livesync-sockets-service.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export class AndroidDeviceSocketsLiveSyncService extends DeviceLiveSyncServiceBa
2020
protected $staticConfig: Config.IStaticConfig,
2121
private $logger: ILogger,
2222
protected device: Mobile.IAndroidDevice,
23-
private $options: ICommonOptions,
23+
private $options: IOptions,
2424
private $processService: IProcessService,
2525
private $fs: IFileSystem,
2626
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants) {
@@ -58,7 +58,7 @@ export class AndroidDeviceSocketsLiveSyncService extends DeviceLiveSyncServiceBa
5858
let result = { operationId, didRefresh: true };
5959

6060
if (liveSyncInfo.modifiedFilesData.length) {
61-
const canExecuteFastSync = !liveSyncInfo.isFullSync && this.canExecuteFastSyncForPaths(liveSyncInfo.modifiedFilesData, projectData, this.device.deviceInfo.platform);
61+
const canExecuteFastSync = !liveSyncInfo.isFullSync && this.canExecuteFastSyncForPaths(liveSyncInfo, liveSyncInfo.modifiedFilesData, projectData, this.device.deviceInfo.platform);
6262
const doSyncPromise = this.livesyncTool.sendDoSyncOperation(canExecuteFastSync, null, operationId);
6363

6464
const syncInterval: NodeJS.Timer = setInterval(() => {
@@ -86,7 +86,7 @@ export class AndroidDeviceSocketsLiveSyncService extends DeviceLiveSyncServiceBa
8686
}
8787

8888
public async refreshApplication(projectData: IProjectData, liveSyncInfo: IAndroidLiveSyncResultInfo) {
89-
const canExecuteFastSync = !liveSyncInfo.isFullSync && this.canExecuteFastSyncForPaths(liveSyncInfo.modifiedFilesData, projectData, this.device.deviceInfo.platform);
89+
const canExecuteFastSync = !liveSyncInfo.isFullSync && this.canExecuteFastSyncForPaths(liveSyncInfo, liveSyncInfo.modifiedFilesData, projectData, this.device.deviceInfo.platform);
9090
if (!canExecuteFastSync || !liveSyncInfo.didRefresh) {
9191
await this.device.applicationManager.restartApplication({ appId: liveSyncInfo.deviceAppData.appIdentifier, projectName: projectData.projectName });
9292
if (!this.$options.justlaunch && this.livesyncTool.protocolVersion && semver.gte(this.livesyncTool.protocolVersion, AndroidDeviceSocketsLiveSyncService.MINIMAL_VERSION_LONG_LIVING_CONNECTION)) {

lib/services/livesync/device-livesync-service-base.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ export abstract class DeviceLiveSyncServiceBase {
99
protected device: Mobile.IDevice
1010
) { }
1111

12-
public canExecuteFastSync(filePath: string, projectData: IProjectData, platform: string): boolean {
12+
public canExecuteFastSync(liveSyncResult: ILiveSyncResultInfo, filePath: string, projectData: IProjectData, platform: string): boolean {
1313
const fastSyncFileExtensions = this.getFastLiveSyncFileExtensions(platform, projectData);
14-
return _.includes(fastSyncFileExtensions, path.extname(filePath));
14+
return liveSyncResult.useHotModuleReload || _.includes(fastSyncFileExtensions, path.extname(filePath));
1515
}
1616

17-
protected canExecuteFastSyncForPaths(localToDevicePaths: Mobile.ILocalToDevicePathData[], projectData: IProjectData, platform: string) {
17+
protected canExecuteFastSyncForPaths(liveSyncResult: ILiveSyncResultInfo, localToDevicePaths: Mobile.ILocalToDevicePathData[], projectData: IProjectData, platform: string) {
1818
return !_.some(localToDevicePaths,
1919
(localToDevicePath: Mobile.ILocalToDevicePathData) =>
20-
!this.canExecuteFastSync(localToDevicePath.getLocalPath(), projectData, this.device.deviceInfo.platform));
20+
!this.canExecuteFastSync(liveSyncResult, localToDevicePath.getLocalPath(), projectData, this.device.deviceInfo.platform));
2121
}
2222

2323
@cache()
@@ -42,7 +42,7 @@ export abstract class DeviceLiveSyncServiceBase {
4242
public async finalizeSync(liveSyncInfo: ILiveSyncResultInfo, projectData: IProjectData): Promise<IAndroidLivesyncSyncOperationResult> {
4343
//implement in case a sync point for all remove/create operation is needed
4444
return {
45-
didRefresh:true,
45+
didRefresh: true,
4646
operationId: ""
4747
};
4848
}

lib/services/livesync/ios-device-livesync-service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ export class IOSDeviceLiveSyncService extends DeviceLiveSyncServiceBase implemen
6161
constants.LIVESYNC_EXCLUDED_FILE_PATTERNS.forEach(pattern => scriptRelatedFiles = _.concat(scriptRelatedFiles, localToDevicePaths.filter(file => minimatch(file.getDevicePath(), pattern, { nocase: true }))));
6262

6363
const otherFiles = _.difference(localToDevicePaths, _.concat(scriptFiles, scriptRelatedFiles));
64-
const canExecuteFastSync = this.canExecuteFastSyncForPaths(otherFiles, projectData, deviceAppData.platform);
64+
const canExecuteFastSync = this.canExecuteFastSyncForPaths(liveSyncInfo, otherFiles, projectData, deviceAppData.platform);
6565

66-
if (!canExecuteFastSync || (!liveSyncInfo.useLiveEdit && scriptFiles.length)) {
66+
if (!canExecuteFastSync) {
6767
await this.restartApplication(deviceAppData, projectData.projectName);
6868
return;
6969
}

lib/services/livesync/ios-livesync-service.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ export class IOSLiveSyncService extends PlatformLiveSyncServiceBase implements I
5252
return {
5353
deviceAppData,
5454
isFullSync: true,
55-
modifiedFilesData: []
55+
modifiedFilesData: [],
56+
useHotModuleReload: syncInfo.useHotModuleReload
5657
};
5758
}
5859

lib/services/livesync/livesync-service.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
477477
const liveSyncResultInfo = await platformLiveSyncService.fullSync({
478478
projectData, device,
479479
syncAllFiles: liveSyncData.watchAllFiles,
480-
useLiveEdit: liveSyncData.useLiveEdit,
480+
useHotModuleReload: liveSyncData.useHotModuleReload,
481481
watch: !liveSyncData.skipWatcher
482482
});
483483

@@ -597,7 +597,7 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi
597597
filesToSync: currentFilesToSync,
598598
isReinstalled: appInstalledOnDeviceResult.appInstalled,
599599
syncAllFiles: liveSyncData.watchAllFiles,
600-
useLiveEdit: liveSyncData.useLiveEdit
600+
useHotModuleReload: liveSyncData.useHotModuleReload
601601
};
602602

603603
const liveSyncResultInfo = await service.liveSyncWatchAction(device, settings);

lib/services/livesync/platform-livesync-service-base.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ export abstract class PlatformLiveSyncServiceBase {
5252
return {
5353
modifiedFilesData,
5454
isFullSync: true,
55-
deviceAppData
55+
deviceAppData,
56+
useHotModuleReload: syncInfo.useHotModuleReload
5657
};
5758
}
5859

@@ -107,7 +108,8 @@ export abstract class PlatformLiveSyncServiceBase {
107108
return {
108109
modifiedFilesData: modifiedLocalToDevicePaths,
109110
isFullSync: liveSyncInfo.isReinstalled,
110-
deviceAppData
111+
deviceAppData,
112+
useHotModuleReload: liveSyncInfo.useHotModuleReload
111113
};
112114
}
113115

0 commit comments

Comments
 (0)