From baf8d0118b7861a1d087c8298e87409e79b908ea Mon Sep 17 00:00:00 2001 From: Frankly George <54015-franklygeorge@users.noreply.gitgud.io> Date: Mon, 25 Mar 2024 01:57:41 +0000 Subject: [PATCH] Watcher live reload --- devTools/scripts/advancedCompiler.js | 3 +++ devTools/scripts/setup.js | 11 ++++++++ devTools/scripts/watcher.js | 38 ++++++++++++++++++++++----- devTools/scripts/watcherLiveReload.js | 20 ++++++++++++++ gulpfile.js | 18 +++++++++++++ 5 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 devTools/scripts/watcherLiveReload.js diff --git a/devTools/scripts/advancedCompiler.js b/devTools/scripts/advancedCompiler.js index a888e473cb8..c16d95165c7 100644 --- a/devTools/scripts/advancedCompiler.js +++ b/devTools/scripts/advancedCompiler.js @@ -89,6 +89,9 @@ if (settings.compilerMode === "simple") { if (settings.compilerFilenamePmodVersion === true) { command += ` --pmodversion`; } + if (settings.WatcherLiveReload === true) { + command += ` --inject-live-reload`; + } command += ` --filename=${args.filename}`; } diff --git a/devTools/scripts/setup.js b/devTools/scripts/setup.js index 43d52ff6cc2..1ae3eee36ad 100644 --- a/devTools/scripts/setup.js +++ b/devTools/scripts/setup.js @@ -47,6 +47,7 @@ const args = yargs(hideBin(process.argv)) * @property {boolean} checksOnlyChangedTypescript If true then we will only check changed lines * @property {-1|0|1} precommitHookEnabled 0 = Disabled, 1 = Enabled, -1 = temporarily disabled * @property {string} FCHostPath Path to FCHost's directory + * @property {boolean} WatcherLiveReload If true then the watcher will trigger a live reload of FC each time it gets re-compiled */ // TODO:@franklygeorge Do we want an extensions.json file for VSCode? @@ -79,6 +80,7 @@ const settings = { checksOnlyChangedTypescript: true, precommitHookEnabled: 1, FCHostPath: "FCHost/fchost/Release", + WatcherLiveReload: false, }; // create settings.json if it doesn't exist @@ -455,6 +457,10 @@ async function MiscSettings() { } else { choices.push("Automatically pulling upstream pregmod-master branch. Sanity checks can report changed lines"); } + choices.push(settings.WatcherLiveReload + ? "Watcher is triggering a live reload on each successful build" + : "Watcher is not triggering a live reload on each successful build" + ); choices.push("Back"); @@ -492,6 +498,11 @@ async function MiscSettings() { } else { settings.fetchUpstreamBranch += 1; } + } else if ( + MiscMenuChoice === "Watcher is triggering a live reload on each successful build" || + MiscMenuChoice === "Watcher is not triggering a live reload on each successful build" + ) { + settings.WatcherLiveReload = !settings.WatcherLiveReload; } else if (MiscMenuChoice === "Back") { return; } diff --git a/devTools/scripts/watcher.js b/devTools/scripts/watcher.js index 3395f342970..a4bd1603cb6 100644 --- a/devTools/scripts/watcher.js +++ b/devTools/scripts/watcher.js @@ -7,6 +7,7 @@ import jetpack from "fs-jetpack"; import watch from "node-watch"; import {execSync, spawn} from "child_process"; import * as path from "path"; +import * as http from "http"; const batSh = (process.platform === "win32") ? "bat" : "sh"; @@ -20,6 +21,22 @@ execSync("node devTools/scripts/setup.js --settings"); /** @type {import("./setup.js").Settings} */ const settings = jetpack.read("settings.json", "json"); +let needsReloaded = false; + +if (settings.WatcherLiveReload === true) { + // start http server for live reloading + let app = http.createServer((req, res) => { + res.setHeader("Content-Type", "application/json"); + res.setHeader("Access-Control-Allow-Origin", "*"); + res.end(JSON.stringify({needsReloaded: needsReloaded}, null, 2)); + needsReloaded = false; + }); + app.listen(16969); + console.log("Live reload server listening on port 15959"); +} else { + console.log("Live reloading is disabled"); +} + /** * Builds FC using the advanced compiler */ @@ -29,15 +46,23 @@ function build() { if (buildProcess !== undefined) { buildProcess.kill(); } - buildProcess = spawn("node", ["devTools/scripts/advancedCompiler.js", "--filename=FC_pregmod.watcher.html", "--no-interaction"], { - stdio: ['inherit', 'inherit', 'inherit'], - }); + buildProcess = spawn( + "node", + ["devTools/scripts/advancedCompiler.js", "--filename=FC_pregmod.watcher.html", "--no-interaction"], + { + stdio: ['inherit', 'inherit', 'inherit'], + } + ); - buildProcess.on('exit', function (code) { + buildProcess.on('exit', function(code) { if (code === null) { return; } else if (code === 0) { console.log(`Saving changes in "setup.${batSh}" will toggle a rebuild`); + if (settings.WatcherLiveReload === true) { + // trigger a reload + needsReloaded = true; + } } else { console.log('Compiler exited with code:', code); } @@ -46,6 +71,7 @@ function build() { const watcher = watch(".", { recursive: true, + // eslint-disable-next-line jsdoc/require-jsdoc filter(f, skip) { if ( f.startsWith("src") || @@ -71,8 +97,6 @@ const watcher = watch(".", { } }); -// TODO:@franklygeorge optional launching of a live reloading web server - watcher.on("change", function(event, filename) { filename = filename.toString(); @@ -87,4 +111,4 @@ console.log("Watching for changes"); console.log(""); // run build when we first startup -build() +build(); diff --git a/devTools/scripts/watcherLiveReload.js b/devTools/scripts/watcherLiveReload.js new file mode 100644 index 00000000000..a6c8ada97e5 --- /dev/null +++ b/devTools/scripts/watcherLiveReload.js @@ -0,0 +1,20 @@ +/** @file This is injected into FC to allow the watchers live reload functionality */ + +const liveReloadUrl = "http://localhost:16969"; + +function checkForLiveReload() { + try { + $.getJSON(liveReloadUrl, function(data) { + if (data !== undefined && "needsReloaded" in data && data["needsReloaded"] === true) { + // reload + location.reload(); + } + }); + } catch (e) { + // fail silently + // this can happen for many reasons. The main one being that the server has been closed while FC has been left open + } +} + +// query server every 2 seconds and see if we need to reload +window.setInterval(checkForLiveReload, 2000); diff --git a/gulpfile.js b/gulpfile.js index d63dee4f59c..92beb2c5693 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -92,6 +92,11 @@ const args = yargs(hideBin(process.argv)) description: 'The filename to save the compiled HTML file as', default: cfg.output, }) + .option('inject-live-reload', { + type: 'boolean', + description: 'Injects code used by the watcher to live reload FC', + default: false, + }) // commands should exist as exported gulp tasks .command('html', "Build FC") .command('themes', "Build themes") @@ -215,6 +220,19 @@ function processScripts(srcGlob, destDir, destFileName) { const addSourcemaps = !args.release; const prefix = path.relative(destDir, srcGlob.substr(0, srcGlob.indexOf("*"))); + if (args.injectLiveReload === true && destFileName === "module-script.js") { + const liveReloadScriptPath = "devTools/scripts/watcherLiveReload.js"; + if (jetpack.exists(liveReloadScriptPath) === "file") { + log.info("Injecting live reload code"); + if (typeof srcGlob === "string") { + srcGlob = [srcGlob]; + } + srcGlob.push(liveReloadScriptPath); + } else { + log.error(`Live reload script is missing from "${liveReloadScriptPath}"!`); + } + } + return gulp.src(srcGlob) .pipe(args.debug ? noop() -- GitLab