diff --git a/lib/controllers/prepare-controller.ts b/lib/controllers/prepare-controller.ts index 4fe1c87582..2e26df5e8c 100644 --- a/lib/controllers/prepare-controller.ts +++ b/lib/controllers/prepare-controller.ts @@ -93,7 +93,7 @@ export class PrepareController extends EventEmitter { this.isInitialPrepareReady = true; if (this.persistedData && this.persistedData.length) { - this.emitPrepareEvent({ files: [], hasNativeChanges: result.hasNativeChanges, hmrData: null, platform: platformData.platformNameLowerCase }); + this.emitPrepareEvent({ files: [], hasOnlyHotUpdateFiles: false, hasNativeChanges: result.hasNativeChanges, hmrData: null, platform: platformData.platformNameLowerCase }); } return result; @@ -130,7 +130,7 @@ export class PrepareController extends EventEmitter { .on("all", async (event: string, filePath: string) => { filePath = path.join(projectData.projectDir, filePath); this.$logger.trace(`Chokidar raised event ${event} for ${filePath}.`); - this.emitPrepareEvent({ files: [], hmrData: null, hasNativeChanges: true, platform: platformData.platformNameLowerCase }); + this.emitPrepareEvent({ files: [], hasOnlyHotUpdateFiles: false, hmrData: null, hasNativeChanges: true, platform: platformData.platformNameLowerCase }); }); this.watchersData[projectData.projectDir][platformData.platformNameLowerCase].nativeFilesWatcher = watcher; diff --git a/lib/controllers/run-controller.ts b/lib/controllers/run-controller.ts index df5ec94d47..fad79b8705 100644 --- a/lib/controllers/run-controller.ts +++ b/lib/controllers/run-controller.ts @@ -152,7 +152,7 @@ export class RunController extends EventEmitter implements IRunController { const platformLiveSyncService = this.$liveSyncServiceResolver.resolveLiveSyncService(platform); try { - let shouldRestart = filesChangeEventData && filesChangeEventData.hasNativeChanges; + let shouldRestart = filesChangeEventData && (filesChangeEventData.hasNativeChanges || !filesChangeEventData.hasOnlyHotUpdateFiles); if (!shouldRestart) { shouldRestart = await platformLiveSyncService.shouldRestart(projectData, liveSyncResultInfo); } diff --git a/lib/services/webpack/webpack-compiler-service.ts b/lib/services/webpack/webpack-compiler-service.ts index 693345ae84..d66974a7d4 100644 --- a/lib/services/webpack/webpack-compiler-service.ts +++ b/lib/services/webpack/webpack-compiler-service.ts @@ -28,19 +28,26 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp prepareData.watch = true; const childProcess = await this.startWebpackProcess(platformData, projectData, prepareData); - childProcess.on("message", (message: any) => { + childProcess.on("message", (message: string | IWebpackEmitMessage) => { if (message === "Webpack compilation complete.") { this.$logger.info("Webpack build done!"); resolve(childProcess); } + message = message as IWebpackEmitMessage; if (message.emittedFiles) { if (isFirstWebpackWatchCompilation) { isFirstWebpackWatchCompilation = false; return; } - const result = this.getUpdatedEmittedFiles(message.emittedFiles, message.webpackRuntimeFiles, message.entryPointFiles); + let result; + + if (prepareData.hmr) { + result = this.getUpdatedEmittedFiles(message.emittedFiles, message.webpackRuntimeFiles, message.entryPointFiles); + } else { + result = { emittedFiles: message.emittedFiles, fallbackFiles: [], hash: "" }; + } const files = result.emittedFiles .map((file: string) => path.join(platformData.appDestinationDirectoryPath, "app", file)); @@ -49,13 +56,16 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp const data = { files, + hasOnlyHotUpdateFiles: files.every(f => f.indexOf("hot-update") > -1), hmrData: { hash: result.hash, fallbackFiles } }; - this.emit(WEBPACK_COMPILATION_COMPLETE, data); + if (data.files.length) { + this.emit(WEBPACK_COMPILATION_COMPLETE, data); + } } }); @@ -193,27 +203,24 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp private getUpdatedEmittedFiles(emittedFiles: string[], webpackRuntimeFiles: string[], entryPointFiles: string[]) { let fallbackFiles: string[] = []; let hotHash; - if (emittedFiles.some(x => x.endsWith('.hot-update.json'))) { - let result = emittedFiles.slice(); - const hotUpdateScripts = emittedFiles.filter(x => x.endsWith('.hot-update.js')); - if (webpackRuntimeFiles && webpackRuntimeFiles.length) { - result = result.filter(file => webpackRuntimeFiles.indexOf(file) === -1); - } - if (entryPointFiles && entryPointFiles.length) { - result = result.filter(file => entryPointFiles.indexOf(file) === -1); - } - hotUpdateScripts.forEach(hotUpdateScript => { - const { name, hash } = this.parseHotUpdateChunkName(hotUpdateScript); - hotHash = hash; - // remove bundle/vendor.js files if there's a bundle.XXX.hot-update.js or vendor.XXX.hot-update.js - result = result.filter(file => file !== `${name}.js`); - }); - // if applying of hot update fails, we must fallback to the full files - fallbackFiles = emittedFiles.filter(file => result.indexOf(file) === -1); - return { emittedFiles: result, fallbackFiles, hash: hotHash }; + let result = emittedFiles.slice(); + const hotUpdateScripts = emittedFiles.filter(x => x.endsWith('.hot-update.js')); + if (webpackRuntimeFiles && webpackRuntimeFiles.length) { + result = result.filter(file => webpackRuntimeFiles.indexOf(file) === -1); } + if (entryPointFiles && entryPointFiles.length) { + result = result.filter(file => entryPointFiles.indexOf(file) === -1); + } + hotUpdateScripts.forEach(hotUpdateScript => { + const { name, hash } = this.parseHotUpdateChunkName(hotUpdateScript); + hotHash = hash; + // remove bundle/vendor.js files if there's a bundle.XXX.hot-update.js or vendor.XXX.hot-update.js + result = result.filter(file => file !== `${name}.js`); + }); + // if applying of hot update fails, we must fallback to the full files + fallbackFiles = emittedFiles.filter(file => hotUpdateScripts.indexOf(file) === -1); - return { emittedFiles, fallbackFiles }; + return { emittedFiles: result, fallbackFiles, hash: hotHash }; } private parseHotUpdateChunkName(name: string) { diff --git a/lib/services/webpack/webpack.d.ts b/lib/services/webpack/webpack.d.ts index 3a597b4ae2..16f232478c 100644 --- a/lib/services/webpack/webpack.d.ts +++ b/lib/services/webpack/webpack.d.ts @@ -28,9 +28,16 @@ declare global { platform: string; files: string[]; hmrData: IPlatformHmrData; + hasOnlyHotUpdateFiles: boolean; hasNativeChanges: boolean; } + interface IWebpackEmitMessage { + emittedFiles: string[]; + webpackRuntimeFiles: string[]; + entryPointFiles: string[]; + } + interface IPlatformProjectService extends NodeJS.EventEmitter, IPlatformProjectServiceBase { getPlatformData(projectData: IProjectData): IPlatformData; validate(projectData: IProjectData, options: IOptions, notConfiguredEnvOptions?: INotConfiguredEnvOptions): Promise; diff --git a/test/controllers/prepare-controller.ts b/test/controllers/prepare-controller.ts index c730a3f6d5..4f056804ed 100644 --- a/test/controllers/prepare-controller.ts +++ b/test/controllers/prepare-controller.ts @@ -103,7 +103,7 @@ describe("prepareController", () => { assert.lengthOf(emittedEventNames, 1); assert.lengthOf(emittedEventData, 1); assert.deepEqual(emittedEventNames[0], PREPARE_READY_EVENT_NAME); - assert.deepEqual(emittedEventData[0], { files: [], hasNativeChanges: true, hmrData: null, platform: platform.toLowerCase() }); + assert.deepEqual(emittedEventData[0], { files: [], hasNativeChanges: true, hasOnlyHotUpdateFiles: false, hmrData: null, platform: platform.toLowerCase() }); }); }); });