Improved watch script

- Added hot reload
- Added file serve via express
- Added cleanup on watch exit
This commit is contained in:
Kentai Radiquum 2025-01-23 02:43:52 +05:00
parent 47af5064ea
commit edf51ec0f7
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
9 changed files with 883 additions and 25 deletions

11
src/hotreload.js Normal file
View file

@ -0,0 +1,11 @@
let webSocket = new WebSocket('ws://127.0.0.1:3001');
webSocket.onmessage = function(e) {
if (e.data == "RELOAD") {
console.log("Reloading page after build")
location.reload()
} else if (e.data == "CONNECTED") {
console.log("Connected to server")
} else {
console.warn(`unknown data received: ${e}`)
}
};

View file

@ -7,6 +7,8 @@ const _CreatePacksIndex = require("./templates/index");
let PackIndex = null
let Packs = [];
const isDev = process.env.DEVMODE || false
const dirents = fs.readdirSync(config.stickerPacksDir, { withFileTypes: true });
const files = dirents
.filter(dirent => dirent.isFile())
@ -29,7 +31,7 @@ if (!fs.existsSync(config.outDir)) fs.mkdirSync(config.outDir);
PackIndex.packs.forEach((pack) => {
const packFile = JSON.parse(fs.readFileSync(config.stickerPacksDir + "/" + pack));
if (!fs.existsSync(config.outDir + "/" + packFile.id)) fs.mkdirSync(config.outDir + "/" + packFile.id);
fs.writeFileSync(config.outDir + "/" + packFile.id + "/index.html", _CreatePackPage(PackIndex, packFile));
fs.writeFileSync(config.outDir + "/" + packFile.id + "/index.html", _CreatePackPage(PackIndex, packFile, isDev));
Packs.push({
id: packFile.id,
name: packFile.title,
@ -40,5 +42,5 @@ PackIndex.packs.forEach((pack) => {
})
console.log("preview for " + packFile.id + " created");
})
fs.writeFileSync(config.outDir + "/index.html", _CreatePacksIndex(PackIndex, Packs));
fs.writeFileSync(config.outDir + "/index.html", _CreatePacksIndex(PackIndex, Packs, isDev));
console.log("Generation complete");

View file

@ -1,4 +1,4 @@
const { CreateImageURL } = require("../utils");
const { CreateImageURL, InjectWSConnection } = require("../utils");
function _PackLink(index, pack) {
@ -56,7 +56,7 @@ function _PackLink(index, pack) {
`
}
function _CreatePacksIndex(index, packs) {
function _CreatePacksIndex(index, packs, isDev) {
let packLinks = [];
packs.forEach((packLink) => packLinks.push(_PackLink(index, packLink)));
@ -78,6 +78,7 @@ function _CreatePacksIndex(index, packs) {
<meta property="og:image:height" content="96" />
<meta property="og:image:alt" content="sticker" />
<link href="./static/tailwind.css" rel="stylesheet">
${isDev ? InjectWSConnection() : ""}
</head>
<body class="overflow-x-hidden">
<div class="fixed inset-0 min-h-screen -z-10 tiledBackground"></div>

View file

@ -2,14 +2,16 @@ const PackHead = require("./components/packHead");
const PackCard = require("./components/packCard");
const PackLinks = require("./components/packLinks");
const PackPreview = require("./components/packPreview");
const { InjectWSConnection } = require("../utils")
function _CreatePackPage(index, pack) {
function _CreatePackPage(index, pack, isDev) {
return `
<!DOCTYPE html>
<html lang="en">
<head>
${PackHead(index, pack)}
${isDev ? InjectWSConnection() : ""}
</head>
<body class="overflow-x-hidden">

View file

@ -36,4 +36,12 @@ function CreatePackDescription(pack) {
return description.join(" | ");
}
module.exports = {CreateImageURL, CreatePackDescription};
function InjectWSConnection() {
return `
<!-- The following was injected by watch.js script, because we are in a dev mode -->
<script src="/src/hotreload.js"></script>
<!-- Dev mode: Enabled -->
`
}
module.exports = {CreateImageURL, CreatePackDescription, InjectWSConnection};

View file

@ -1,7 +1,23 @@
const chokidar = require("chokidar");
const exec = require("child_process");
const express = require('express');
const path = require('path');
const WebSocket = require('ws');
const fs = require("fs");
const config = require("./config");
function onChange() {
let triggered = 0
const delay = 1000
let SIGINTCount = 0
function onChange(wss) {
if (triggered != 0 && Date.now() - triggered < delay) {
console.log(` ↳[WARN] Rebuild was triggered less than a ${delay}ms ago!`)
return
}
triggered = Date.now()
process.env.DEVMODE = true
exec.exec("npm run build", (error, stdout, stderr) => {
if (error) {
console.error(`error: ${error.message}`);
@ -12,25 +28,92 @@ function onChange() {
return;
}
console.log(`stdout: ${stdout}`);
if (wss) {
console.log('Reloading web page...');
wss.send("RELOAD")
}
});
}
const watcher = chokidar.watch("./src/templates", {
ignored: (path, stats) =>
stats?.isFile() && !(path.endsWith(".js") || path.endsWith(".json")),
// atomic: true,
function onExit() {
let folders = null
if (fs.existsSync(config.stickerPacksDir + "/index.json")) {
folders = []
JSON.parse(fs.readFileSync(config.stickerPacksDir + "/index.json"))["packs"].map((pack) => folders.push(pack.replace(".json", "")))
folders.forEach(
(folder) => {
if (fs.existsSync(config.outDir + "/" + folder) ) fs.rmdirSync(config.outDir + "/" + folder, {recursive: true})
console.log(`Deleted generated folder: "${folder}"`)
}
)
} else {
console.log("no index.json found, forgot to run build?")
}
if (fs.existsSync(config.outDir + "/index.html")) fs.rmSync(config.outDir + "/index.html")
console.log(`Deleted "index.html" file`)
process.exit(0)
}
const watcher = chokidar.watch(["./src/templates", "./stickerpacks"], {
ignored: (filePath, stats) =>
(stats?.isFile() && !(filePath.endsWith(".js") || filePath.endsWith(".json"))) || filePath.endsWith("index.json"),
atomic: true,
awaitWriteFinish: true,
persistent: true,
});
watcher.on("add", (path) => {
console.log(`File ${path} has been added, rebuilding...`);
onChange();
});
watcher.on("change", (path) => {
console.log(`File ${path} has been changed, rebuilding...`);
onChange();
});
watcher.on("unlink", (path) => {
console.log(`File ${path} has been removed, rebuilding...`);
onChange();
});
function startServerWithRebuild() {
const app = express();
const folder = path.join(__dirname, '..')
const wss = new WebSocket.Server({ port: 3001 });
let WSclient = null
wss.on('connection', (ws) => {
WSclient = ws
ws.send("CONNECTED")
});
process.on("SIGINT", () => {
SIGINTCount += 1
if (WSclient) {
async function _closeWS() {
await WSclient.close()
}
_closeWS()
}
if (SIGINTCount == 1) {
console.log("Gracefully shutdown and cleanup...")
onExit()
} else if (SIGINTCount >= 3) {
console.log("Received 3+ SIGINT signals. Force exit...")
process.exit(0)
}
})
app.use(express.static(folder));
app.listen(3000, () => {
console.log(`[INFO] Serving files from folder ${folder}`)
console.log('[INFO] Express server is running on port 3000');
watcher
.on('add', (path) => {
console.log(`[INFO] File ${path} has been added, rebuilding...`);
onChange(WSclient);
})
.on('change', (path) => {
console.log(`[INFO] File ${path} has been changed, rebuilding...`);
onChange(WSclient);
})
.on('unlink', (path) => {
console.log(`[INFO] File ${path} has been removed, rebuilding...`);
onChange(WSclient);
});
});
}
startServerWithRebuild();