From 0cc72fca86bcb11f1daa0a068d83ae2a869dcca0 Mon Sep 17 00:00:00 2001 From: Vasil Trifonov Date: Mon, 10 Sep 2018 18:28:14 +0300 Subject: [PATCH 1/2] Sync only hmr updates without bundle files --- bundle-config-loader.js | 7 ++++++- hot-loader-helper.js | 8 ++++---- hot.js | 25 +++++++++++++++++++++++-- markup-hot-loader.js | 2 +- page-hot-loader.js | 2 +- plugins/WatchStateLoggerPlugin.ts | 17 ++++++++++++++++- style-hot-loader.js | 2 +- 7 files changed, 52 insertions(+), 11 deletions(-) diff --git a/bundle-config-loader.js b/bundle-config-loader.js index 343e25b7..0c96b872 100644 --- a/bundle-config-loader.js +++ b/bundle-config-loader.js @@ -10,11 +10,16 @@ module.exports = function (source) { if (!angular && registerModules) { const hmr = ` if (module.hot) { + const fileSystemModule = require("tns-core-modules/file-system"); + const applicationFiles = fileSystemModule.knownFolders.currentApp(); + global.__hmrLivesyncBackup = global.__onLiveSync; global.__onLiveSync = function () { console.log("LiveSyncing..."); - require("nativescript-dev-webpack/hot")("", {}); + require("nativescript-dev-webpack/hot")(__webpack_require__.h(), (fileName) => applicationFiles.getFile(fileName)); }; + global.__hmrInitialSync = true; // needed to determine if we are performing initial sync + global.__onLiveSync(); } `; diff --git a/hot-loader-helper.js b/hot-loader-helper.js index cc5dcd76..a11bf1cc 100644 --- a/hot-loader-helper.js +++ b/hot-loader-helper.js @@ -1,11 +1,11 @@ -module.exports.reload = ` +module.exports.reload = function(type) { return ` if (module.hot) { module.hot.accept(); module.hot.dispose(() => { setTimeout(() => { global.__hmrLivesyncBackup(); - }); + }, ${type === 'style' ? "global.__hmrInitialSync ? 1000 : 0" : 0}); }) } -`; - +`}; +// we need to add a timeout of 1000 if we have a css change, otherwise the app crashes on initial hmr sync \ No newline at end of file diff --git a/hot.js b/hot.js index 90c00665..040b6365 100644 --- a/hot.js +++ b/hot.js @@ -83,7 +83,7 @@ function check(options) { .then((appliedModules) => { if (!upToDate()) { log.warn("Hashes don't match. Ignoring second update..."); - // check(options); + check(options); } result(modules, appliedModules); @@ -122,7 +122,7 @@ if (module.hot) { console.error('Hot Module Replacement is disabled.'); } -module.exports = function update(currentHash, options) { +function update(currentHash, options) { lastHash = currentHash; if (!upToDate()) { const status = module.hot.status(); @@ -138,3 +138,24 @@ module.exports = function update(currentHash, options) { } }; +function getCurrentHash(currentHash, getFileContent) { + const file = getFileContent(`${currentHash}.hot-update.json`); + return file.readText().then(hotUpdateContent => { + if(hotUpdateContent) { + const manifest = JSON.parse(hotUpdateContent); + const newHash = manifest.h; + return getCurrentHash(newHash, getFileContent); + } else { + return Promise.resolve(currentHash); + } + }).catch(error => Promise.reject(error)); +} + +module.exports = function checkState(initialHash, getFileContent) { + getCurrentHash(initialHash, getFileContent).then(currentHash => { + if(currentHash != initialHash) { + update(currentHash, {}); + } + }) +} + diff --git a/markup-hot-loader.js b/markup-hot-loader.js index 3b4f19c2..6d330447 100644 --- a/markup-hot-loader.js +++ b/markup-hot-loader.js @@ -1,5 +1,5 @@ const { reload } = require("./hot-loader-helper"); module.exports = function (source) { - return `${source};${reload}`; + return `${source};${reload('markup')}`; }; diff --git a/page-hot-loader.js b/page-hot-loader.js index 3b4f19c2..eaa4bcdf 100644 --- a/page-hot-loader.js +++ b/page-hot-loader.js @@ -1,5 +1,5 @@ const { reload } = require("./hot-loader-helper"); module.exports = function (source) { - return `${source};${reload}`; + return `${source};${reload('page')}`; }; diff --git a/plugins/WatchStateLoggerPlugin.ts b/plugins/WatchStateLoggerPlugin.ts index a3fb0813..2396f7cf 100644 --- a/plugins/WatchStateLoggerPlugin.ts +++ b/plugins/WatchStateLoggerPlugin.ts @@ -32,7 +32,7 @@ export class WatchStateLoggerPlugin { console.log(messages.compilationComplete); } - const emittedFiles = Object + let emittedFiles = Object .keys(compilation.assets) .filter(assetKey => compilation.assets[assetKey].emitted); @@ -40,6 +40,8 @@ export class WatchStateLoggerPlugin { WatchStateLoggerPlugin.rewriteHotUpdateChunk(compiler, compilation, emittedFiles); } + emittedFiles = WatchStateLoggerPlugin.getUpdatedEmittedFiles(emittedFiles); + // provide fake paths to the {N} CLI - relative to the 'app' folder // in order to trigger the livesync process const emittedFilesFakePaths = emittedFiles @@ -90,6 +92,19 @@ export class WatchStateLoggerPlugin { return content.substring(startIndex, endIndex); } + /** + * Checks if there's a file in the following pattern 5e0326f3bb50f9f26cf0.hot-update.json + * if yes this is a HMR update and remove all bundle files as we don't need them to be synced, + * but only the update chunks + */ + static getUpdatedEmittedFiles(emittedFiles) { + if(emittedFiles.some(x => x.endsWith('.hot-update.json'))) { + return emittedFiles.filter(x => x.indexOf('.hot-update.') > 0); + } else { + return emittedFiles; + } + } + /** * Gets the webpackHotUpdate call with updated modules not to include the ones with errors */ diff --git a/style-hot-loader.js b/style-hot-loader.js index 3b4f19c2..23e6ad72 100644 --- a/style-hot-loader.js +++ b/style-hot-loader.js @@ -1,5 +1,5 @@ const { reload } = require("./hot-loader-helper"); module.exports = function (source) { - return `${source};${reload}`; + return `${source};${reload('style')}`; }; From f613d91ad3276d9e15199892a1d553019f0bc804 Mon Sep 17 00:00:00 2001 From: Vasil Trifonov Date: Mon, 10 Sep 2018 19:01:17 +0300 Subject: [PATCH 2/2] Messaging updates --- bundle-config-loader.js | 2 +- hot.js | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/bundle-config-loader.js b/bundle-config-loader.js index 0c96b872..c3d379ff 100644 --- a/bundle-config-loader.js +++ b/bundle-config-loader.js @@ -15,7 +15,7 @@ module.exports = function (source) { global.__hmrLivesyncBackup = global.__onLiveSync; global.__onLiveSync = function () { - console.log("LiveSyncing..."); + console.log("HMR Sync..."); require("nativescript-dev-webpack/hot")(__webpack_require__.h(), (fileName) => applicationFiles.getFile(fileName)); }; global.__hmrInitialSync = true; // needed to determine if we are performing initial sync diff --git a/hot.js b/hot.js index 040b6365..80dca41f 100644 --- a/hot.js +++ b/hot.js @@ -1,5 +1,5 @@ const log = console; -const refresh = 'Please refresh the page.'; +const refresh = 'Please restart the application.'; const hotOptions = { ignoreUnaccepted: true, ignoreDeclined: true, @@ -73,7 +73,7 @@ function check(options) { .then((modules) => { if (!modules) { log.warn( - `Cannot find update. The server may have been restarted. ${refresh}` + `Cannot find update. ${refresh}` ); return null; } @@ -82,7 +82,6 @@ function check(options) { .apply(hotOptions) .then((appliedModules) => { if (!upToDate()) { - log.warn("Hashes don't match. Ignoring second update..."); check(options); }