diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index 9663355013..0dfd16b01f 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -468,10 +468,10 @@ interface IOptions extends ICommonOptions, IBundleString, IPlatformTemplate, IHa production: boolean; //npm flag sdk: string; syncAllFiles: boolean; - liveEdit: boolean; chrome: boolean; inspector: boolean; // the counterpart to --chrome background: string; + hmr: boolean; } interface IEnvOptions { diff --git a/lib/definitions/livesync.d.ts b/lib/definitions/livesync.d.ts index 0c4bed77c2..f7380695b2 100644 --- a/lib/definitions/livesync.d.ts +++ b/lib/definitions/livesync.d.ts @@ -142,19 +142,13 @@ interface IOptionalSkipWatcher { /** * Describes a LiveSync operation. */ -interface ILiveSyncInfo extends IProjectDir, IEnvOptions, IBundle, IRelease, IOptionalSkipWatcher { +interface ILiveSyncInfo extends IProjectDir, IEnvOptions, IBundle, IRelease, IOptionalSkipWatcher, IHasUseHotModuleReloadOption { /** * 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. * 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). */ watchAllFiles?: boolean; - /** - * Defines if the liveEdit functionality should be used, i.e. LiveSync of .js files without restart. - * NOTE: Currently this is available only for iOS. - */ - useLiveEdit?: boolean; - /** * Forces a build before the initial livesync. */ @@ -167,6 +161,13 @@ interface ILiveSyncInfo extends IProjectDir, IEnvOptions, IBundle, IRelease, IOp timeout: string; } +interface IHasUseHotModuleReloadOption { + /** + * Defines if the hot module reload should be used. + */ + useHotModuleReload?: boolean; +} + interface ILatestAppPackageInstalledSettings extends IDictionary> { /* empty */ } interface IIsEmulator { @@ -317,28 +318,25 @@ interface IShouldSkipEmitLiveSyncNotification { interface IAttachDebuggerOptions extends IDebuggingAdditionalOptions, IEnableDebuggingDeviceOptions, IIsEmulator, IPlatform, IOptionalOutputPath { } -interface ILiveSyncWatchInfo extends IProjectDataComposition { +interface ILiveSyncWatchInfo extends IProjectDataComposition, IHasUseHotModuleReloadOption { filesToRemove: string[]; filesToSync: string[]; isReinstalled: boolean; syncAllFiles: boolean; - useLiveEdit?: boolean; } -interface ILiveSyncResultInfo { +interface ILiveSyncResultInfo extends IHasUseHotModuleReloadOption { modifiedFilesData: Mobile.ILocalToDevicePathData[]; isFullSync: boolean; deviceAppData: Mobile.IDeviceAppData; - useLiveEdit?: boolean; } interface IAndroidLiveSyncResultInfo extends ILiveSyncResultInfo, IAndroidLivesyncSyncOperationResult { } -interface IFullSyncInfo extends IProjectDataComposition { +interface IFullSyncInfo extends IProjectDataComposition, IHasUseHotModuleReloadOption { device: Mobile.IDevice; watch: boolean; syncAllFiles: boolean; - useLiveEdit?: boolean; } interface IPlatformLiveSyncService { @@ -434,7 +432,7 @@ interface IAndroidLivesyncTool { */ removeFile(filePath: string): Promise; /** - * Removes files + * Removes files * @param filePaths - Array of files that will be removed. * @returns {Promise} */ diff --git a/lib/helpers/livesync-command-helper.ts b/lib/helpers/livesync-command-helper.ts index a0a971fa49..7ce40b06b2 100644 --- a/lib/helpers/livesync-command-helper.ts +++ b/lib/helpers/livesync-command-helper.ts @@ -102,7 +102,7 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { emulator: d.isEmulator, projectDir: this.$projectData.projectDir }), - skipNativePrepare: additionalOptions && additionalOptions.skipNativePrepare + skipNativePrepare: additionalOptions && additionalOptions.skipNativePrepare, }; return info; @@ -116,7 +116,8 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { bundle: !!this.$options.bundle, release: this.$options.release, env: this.$options.env, - timeout: this.$options.timeout + timeout: this.$options.timeout, + useHotModuleReload: this.$options.hmr }; await this.$liveSyncService.liveSync(deviceDescriptors, liveSyncInfo); diff --git a/lib/options.ts b/lib/options.ts index 0a48916df6..3d4422ce06 100644 --- a/lib/options.ts +++ b/lib/options.ts @@ -34,14 +34,14 @@ export class Options extends commonOptionsLibPath.OptionsBase { all: { type: OptionType.Boolean }, teamId: { type: OptionType.Object }, syncAllFiles: { type: OptionType.Boolean, default: false }, - liveEdit: { type: OptionType.Boolean }, chrome: { type: OptionType.Boolean }, inspector: { type: OptionType.Boolean }, clean: { type: OptionType.Boolean }, watch: { type: OptionType.Boolean, default: true }, background: { type: OptionType.String }, username: { type: OptionType.String }, - pluginName: { type: OptionType.String } + pluginName: { type: OptionType.String }, + hmr: {type: OptionType.Boolean} }, $errors, $staticConfig, $settingsService); @@ -50,6 +50,10 @@ export class Options extends commonOptionsLibPath.OptionsBase { if (that.justlaunch) { that.watch = false; } + + if (that.hmr) { + that.bundle = "webpack"; + } } } $injector.register("options", Options); diff --git a/lib/services/livesync/android-device-livesync-service.ts b/lib/services/livesync/android-device-livesync-service.ts index a9c7e3a9bf..c212124242 100644 --- a/lib/services/livesync/android-device-livesync-service.ts +++ b/lib/services/livesync/android-device-livesync-service.ts @@ -39,7 +39,7 @@ export class AndroidDeviceLiveSyncService extends DeviceLiveSyncServiceBase impl const reloadedSuccessfully = await this.reloadApplicationFiles(deviceAppData, localToDevicePaths); const canExecuteFastSync = reloadedSuccessfully && !liveSyncInfo.isFullSync && !_.some(localToDevicePaths, - (localToDevicePath: Mobile.ILocalToDevicePathData) => !this.canExecuteFastSync(localToDevicePath.getLocalPath(), projectData, this.device.deviceInfo.platform)); + (localToDevicePath: Mobile.ILocalToDevicePathData) => !this.canExecuteFastSync(liveSyncInfo, localToDevicePath.getLocalPath(), projectData, this.device.deviceInfo.platform)); if (!canExecuteFastSync) { return this.restartApplication(deviceAppData, projectData.projectName); diff --git a/lib/services/livesync/android-device-livesync-sockets-service.ts b/lib/services/livesync/android-device-livesync-sockets-service.ts index 4387eb138d..aa9d27494b 100644 --- a/lib/services/livesync/android-device-livesync-sockets-service.ts +++ b/lib/services/livesync/android-device-livesync-sockets-service.ts @@ -20,7 +20,7 @@ export class AndroidDeviceSocketsLiveSyncService extends DeviceLiveSyncServiceBa protected $staticConfig: Config.IStaticConfig, private $logger: ILogger, protected device: Mobile.IAndroidDevice, - private $options: ICommonOptions, + private $options: IOptions, private $processService: IProcessService, private $fs: IFileSystem, private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants) { @@ -58,7 +58,7 @@ export class AndroidDeviceSocketsLiveSyncService extends DeviceLiveSyncServiceBa let result = { operationId, didRefresh: true }; if (liveSyncInfo.modifiedFilesData.length) { - const canExecuteFastSync = !liveSyncInfo.isFullSync && this.canExecuteFastSyncForPaths(liveSyncInfo.modifiedFilesData, projectData, this.device.deviceInfo.platform); + const canExecuteFastSync = !liveSyncInfo.isFullSync && this.canExecuteFastSyncForPaths(liveSyncInfo, liveSyncInfo.modifiedFilesData, projectData, this.device.deviceInfo.platform); const doSyncPromise = this.livesyncTool.sendDoSyncOperation(canExecuteFastSync, null, operationId); const syncInterval: NodeJS.Timer = setInterval(() => { @@ -86,7 +86,7 @@ export class AndroidDeviceSocketsLiveSyncService extends DeviceLiveSyncServiceBa } public async refreshApplication(projectData: IProjectData, liveSyncInfo: IAndroidLiveSyncResultInfo) { - const canExecuteFastSync = !liveSyncInfo.isFullSync && this.canExecuteFastSyncForPaths(liveSyncInfo.modifiedFilesData, projectData, this.device.deviceInfo.platform); + const canExecuteFastSync = !liveSyncInfo.isFullSync && this.canExecuteFastSyncForPaths(liveSyncInfo, liveSyncInfo.modifiedFilesData, projectData, this.device.deviceInfo.platform); if (!canExecuteFastSync || !liveSyncInfo.didRefresh) { await this.device.applicationManager.restartApplication({ appId: liveSyncInfo.deviceAppData.appIdentifier, projectName: projectData.projectName }); if (!this.$options.justlaunch && this.livesyncTool.protocolVersion && semver.gte(this.livesyncTool.protocolVersion, AndroidDeviceSocketsLiveSyncService.MINIMAL_VERSION_LONG_LIVING_CONNECTION)) { diff --git a/lib/services/livesync/device-livesync-service-base.ts b/lib/services/livesync/device-livesync-service-base.ts index d2e447cecc..9b46395a96 100644 --- a/lib/services/livesync/device-livesync-service-base.ts +++ b/lib/services/livesync/device-livesync-service-base.ts @@ -9,15 +9,15 @@ export abstract class DeviceLiveSyncServiceBase { protected device: Mobile.IDevice ) { } - public canExecuteFastSync(filePath: string, projectData: IProjectData, platform: string): boolean { + public canExecuteFastSync(liveSyncResult: ILiveSyncResultInfo, filePath: string, projectData: IProjectData, platform: string): boolean { const fastSyncFileExtensions = this.getFastLiveSyncFileExtensions(platform, projectData); - return _.includes(fastSyncFileExtensions, path.extname(filePath)); + return liveSyncResult.useHotModuleReload || _.includes(fastSyncFileExtensions, path.extname(filePath)); } - protected canExecuteFastSyncForPaths(localToDevicePaths: Mobile.ILocalToDevicePathData[], projectData: IProjectData, platform: string) { + protected canExecuteFastSyncForPaths(liveSyncResult: ILiveSyncResultInfo, localToDevicePaths: Mobile.ILocalToDevicePathData[], projectData: IProjectData, platform: string) { return !_.some(localToDevicePaths, (localToDevicePath: Mobile.ILocalToDevicePathData) => - !this.canExecuteFastSync(localToDevicePath.getLocalPath(), projectData, this.device.deviceInfo.platform)); + !this.canExecuteFastSync(liveSyncResult, localToDevicePath.getLocalPath(), projectData, this.device.deviceInfo.platform)); } @cache() @@ -42,7 +42,7 @@ export abstract class DeviceLiveSyncServiceBase { public async finalizeSync(liveSyncInfo: ILiveSyncResultInfo, projectData: IProjectData): Promise { //implement in case a sync point for all remove/create operation is needed return { - didRefresh:true, + didRefresh: true, operationId: "" }; } diff --git a/lib/services/livesync/ios-device-livesync-service.ts b/lib/services/livesync/ios-device-livesync-service.ts index 22a9d56bd4..f771f92896 100644 --- a/lib/services/livesync/ios-device-livesync-service.ts +++ b/lib/services/livesync/ios-device-livesync-service.ts @@ -61,9 +61,9 @@ export class IOSDeviceLiveSyncService extends DeviceLiveSyncServiceBase implemen constants.LIVESYNC_EXCLUDED_FILE_PATTERNS.forEach(pattern => scriptRelatedFiles = _.concat(scriptRelatedFiles, localToDevicePaths.filter(file => minimatch(file.getDevicePath(), pattern, { nocase: true })))); const otherFiles = _.difference(localToDevicePaths, _.concat(scriptFiles, scriptRelatedFiles)); - const canExecuteFastSync = this.canExecuteFastSyncForPaths(otherFiles, projectData, deviceAppData.platform); + const canExecuteFastSync = this.canExecuteFastSyncForPaths(liveSyncInfo, otherFiles, projectData, deviceAppData.platform); - if (!canExecuteFastSync || (!liveSyncInfo.useLiveEdit && scriptFiles.length)) { + if (!canExecuteFastSync) { await this.restartApplication(deviceAppData, projectData.projectName); return; } diff --git a/lib/services/livesync/ios-livesync-service.ts b/lib/services/livesync/ios-livesync-service.ts index ae9c0a1bc5..5ad992bb96 100644 --- a/lib/services/livesync/ios-livesync-service.ts +++ b/lib/services/livesync/ios-livesync-service.ts @@ -52,7 +52,8 @@ export class IOSLiveSyncService extends PlatformLiveSyncServiceBase implements I return { deviceAppData, isFullSync: true, - modifiedFilesData: [] + modifiedFilesData: [], + useHotModuleReload: syncInfo.useHotModuleReload }; } diff --git a/lib/services/livesync/livesync-service.ts b/lib/services/livesync/livesync-service.ts index 889d9e20d6..c498a7b9af 100644 --- a/lib/services/livesync/livesync-service.ts +++ b/lib/services/livesync/livesync-service.ts @@ -477,7 +477,7 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi const liveSyncResultInfo = await platformLiveSyncService.fullSync({ projectData, device, syncAllFiles: liveSyncData.watchAllFiles, - useLiveEdit: liveSyncData.useLiveEdit, + useHotModuleReload: liveSyncData.useHotModuleReload, watch: !liveSyncData.skipWatcher }); @@ -597,7 +597,7 @@ export class LiveSyncService extends EventEmitter implements IDebugLiveSyncServi filesToSync: currentFilesToSync, isReinstalled: appInstalledOnDeviceResult.appInstalled, syncAllFiles: liveSyncData.watchAllFiles, - useLiveEdit: liveSyncData.useLiveEdit + useHotModuleReload: liveSyncData.useHotModuleReload }; const liveSyncResultInfo = await service.liveSyncWatchAction(device, settings); diff --git a/lib/services/livesync/platform-livesync-service-base.ts b/lib/services/livesync/platform-livesync-service-base.ts index 30bb8db5e9..f2c64952f0 100644 --- a/lib/services/livesync/platform-livesync-service-base.ts +++ b/lib/services/livesync/platform-livesync-service-base.ts @@ -52,7 +52,8 @@ export abstract class PlatformLiveSyncServiceBase { return { modifiedFilesData, isFullSync: true, - deviceAppData + deviceAppData, + useHotModuleReload: syncInfo.useHotModuleReload }; } @@ -107,7 +108,8 @@ export abstract class PlatformLiveSyncServiceBase { return { modifiedFilesData: modifiedLocalToDevicePaths, isFullSync: liveSyncInfo.isReinstalled, - deviceAppData + deviceAppData, + useHotModuleReload: liveSyncInfo.useHotModuleReload }; }