Skip to content

Commit 359e3fb

Browse files
authored
Fix/dev mode hot reload (#5550)
* test: add comprehensive unit tests for loader.js - Add test coverage for requirejs configuration - Test i18next initialization and language switching - Mock external dependencies (i18next, requirejs-plugins) - Handle async initialization logic * style: fix formatting in loader.test.js * style: update copyright year to 2026 * style: run prettier on loader.test.js * fix: Implement environment-aware caching for instant dev hot reload - Disable service worker registration on localhost for development - Add environment detection (NODE_ENV) for cache control - Set no-cache headers in development mode (maxAge: 0) - Maintain full PWA functionality in production - Add cross-env for cross-platform environment variable support - Add separate dev/prod npm scripts This fixes the issue where code changes required multiple refreshes or hard refreshes to appear due to aggressive service worker and browser caching. Changes now reflect instantly on refresh during development while maintaining production performance. Closes #[issue-number] * chore: Add package-lock.json with cross-env dependency * style: Run Prettier on index.js to fix formatting * refactor: Simplify server startup logging to minimal output
1 parent 4a46e1d commit 359e3fb

4 files changed

Lines changed: 90 additions & 15 deletions

File tree

index.html

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -558,21 +558,37 @@
558558
</script>
559559

560560
<script>
561+
// Register service worker only in production (not on localhost)
561562
if ("serviceWorker" in navigator) {
562-
if (navigator.serviceWorker.controller) {
563-
console.debug(
564-
"[PWA Builder] active service worker found, no need to register"
565-
);
563+
// Detect if running on localhost for development
564+
const isLocalDev = window.location.hostname === "localhost" ||
565+
window.location.hostname === "127.0.0.1";
566+
567+
if (!isLocalDev) {
568+
// Production: Register service worker for offline mode
569+
if (navigator.serviceWorker.controller) {
570+
console.debug(
571+
"[PWA Builder] Active service worker found, no need to register"
572+
);
573+
} else {
574+
// Register the service worker
575+
navigator.serviceWorker
576+
.register("/sw.js")
577+
.then(function (reg) {
578+
console.debug(
579+
"[PWA Builder] Service worker registered for scope: " +
580+
reg.scope
581+
);
582+
})
583+
.catch(function (err) {
584+
console.error("[PWA Builder] Service worker registration failed:", err);
585+
});
586+
}
566587
} else {
567-
// Register the service worker
568-
navigator.serviceWorker
569-
.register("/sw.js")
570-
.then(function (reg) {
571-
console.debug(
572-
"[PWA Builder] Service worker has been registered for scope: " +
573-
reg.scope
574-
);
575-
});
588+
// Development: Skip service worker for instant updates
589+
console.log(
590+
"🔥 [DEV MODE] Service worker disabled on localhost for instant code updates"
591+
);
576592
}
577593
}
578594
</script>

index.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ const path = require("path");
44

55
const app = express();
66

7+
// Detect environment (default to development for safety)
8+
const isDev = process.env.NODE_ENV !== "production";
9+
710
// Enable compression for all responses
811
app.use(
912
compression({
@@ -12,9 +15,26 @@ app.use(
1215
})
1316
);
1417

18+
// Environment-aware static file serving
1519
app.use(
1620
express.static(path.join(__dirname), {
17-
maxAge: "1h"
21+
// Disable caching in development, enable in production
22+
maxAge: isDev ? 0 : "1h",
23+
etag: isDev ? false : true,
24+
lastModified: isDev ? false : true,
25+
26+
// Set explicit no-cache headers in development
27+
setHeaders: (res, filePath) => {
28+
if (isDev) {
29+
res.setHeader(
30+
"Cache-Control",
31+
"no-store, no-cache, must-revalidate, proxy-revalidate"
32+
);
33+
res.setHeader("Pragma", "no-cache");
34+
res.setHeader("Expires", "0");
35+
res.setHeader("Surrogate-Control", "no-store");
36+
}
37+
}
1838
})
1939
);
2040

package-lock.json

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
"scripts": {
1515
"lint": "eslint js/ planet/js/",
1616
"serve": "http-server -a 127.0.0.1 -p 3000 --gzip --brotli",
17+
"serve:dev": "http-server -a 127.0.0.1 -p 3000 -c-1",
1718
"start": "node index.js",
18-
"dev": "nodemon index.js",
19+
"dev": "cross-env NODE_ENV=development nodemon index.js",
20+
"prod": "cross-env NODE_ENV=production node index.js",
1921
"test": "jest",
2022
"cypress:run": "cypress run",
2123
"electron": "electron .",
@@ -25,6 +27,7 @@
2527
"@babel/core": "^7.28.5",
2628
"@babel/eslint-parser": "^7.28.5",
2729
"@babel/preset-env": "^7.28.5",
30+
"cross-env": "^7.0.3",
2831
"cypress": "^15.9.0",
2932
"electron": "40.0.0",
3033
"electron-builder": "26.4.0",

0 commit comments

Comments
 (0)