From 121c3b27cff08d98d7f74e8b4aea262203add5e8 Mon Sep 17 00:00:00 2001 From: fatme Date: Sun, 30 Jun 2019 23:48:46 +0300 Subject: [PATCH] fix: don't restart application when lazy loaded code is changed in angular app with uglify option Currently there is a logic that gets all runtime files and entry point files from webpack compilation. These files are needed to CLI in order to decides if the application should be restarted or refreshed on device(when there is at least one file that is not hot update file, CLI restarts the application). However, this logic doesn't work for lazy loaded modules in angular application as they are reported neither entry point files nor runtime files. Lazy loaded modules are directly injected into webpack compilation using the hooks of ContextModuleFactory - https://github.com/angular/ngtools-webpack-builds/blob/39ccb0b487e92a7ac4330ff9db821337b7aa5c45/src/angular_compiler_plugin.js#L516. This PR fixes the behavior with lazy loaded files as it gets all chunks produced from webpack compilation and omits hot-update.js files from them. Chunk files are all files except hot update files. Chunk files are: `runtime.js`, `tns_modules/inspector-modules.js`, `bundle.js`, `vendor.js` and all lazy loaded modules. When a files is changed in hmr mode, .hot-update.js file is included into chunk files. This way we don't need to separate the files to entry point, runtime, lazy loaded and others. We just need to omit .hot-update.js file from chunk files from webpack compilation. --- plugins/WatchStateLoggerPlugin.ts | 47 ++++++++----------------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/plugins/WatchStateLoggerPlugin.ts b/plugins/WatchStateLoggerPlugin.ts index e10bca88..7e5302d7 100644 --- a/plugins/WatchStateLoggerPlugin.ts +++ b/plugins/WatchStateLoggerPlugin.ts @@ -33,51 +33,28 @@ export class WatchStateLoggerPlugin { .keys(compilation.assets) .filter(assetKey => compilation.assets[assetKey].emitted); - const webpackRuntimeFiles = getWebpackRuntimeOnlyFiles(compilation); - const entryPointFiles = getEntryPointFiles(compilation); + const chunkFiles = getChunkFiles(compilation); process.send && process.send(messages.compilationComplete, error => null); // Send emitted files so they can be LiveSynced if need be - process.send && process.send({ emittedFiles, webpackRuntimeFiles, entryPointFiles }, error => null); + process.send && process.send({ emittedFiles, chunkFiles }, error => null); }); } } -function getWebpackRuntimeOnlyFiles(compilation) { - let runtimeOnlyFiles = []; +function getChunkFiles(compilation) { + const chunkFiles = []; try { - runtimeOnlyFiles = [].concat(...Array.from(compilation.entrypoints.values()) - .map(entrypoint => entrypoint.runtimeChunk) - // filter embedded runtime chunks (e.g. part of bundle.js or inspector-modules.js) - .filter(runtimeChunk => !!runtimeChunk && runtimeChunk.preventIntegration) - .map(runtimeChunk => runtimeChunk.files)) - // get only the unique files in case of "single" runtime (e.g. runtime.js) - .filter((value, index, self) => self.indexOf(value) === index); - } catch (e) { - // breaking change in the Webpack API - console.log("Warning: Unable to find Webpack runtime files."); - } - - return runtimeOnlyFiles; -} - -function getEntryPointFiles(compilation) { - const entryPointFiles = []; - try { - Array.from(compilation.entrypoints.values()) - .forEach((entrypoint: any) => { - for (const entryChunk of entrypoint.chunks) { - entryChunk.files.forEach(fileName => { - if (fileName.indexOf("hot-update") === -1) { - entryPointFiles.push(fileName); - } - }); + compilation.chunks.forEach(chunk => { + chunk.files.forEach(file => { + if (file.indexOf("hot-update") === -1) { + chunkFiles.push(file); } }); + }); } catch (e) { - console.log("Warning: Unable to find Webpack entry point files."); + console.log("Warning: Unable to find chunk files."); } - return entryPointFiles - .filter((value, index, self) => self.indexOf(value) === index); // get only the unique files -} \ No newline at end of file + return chunkFiles; +}