fix(build): derive sw.js cache tag from bundle content hash
The service worker uses staleWhileRevalidate on /dist/*, so after a release it would serve old bundles from cache indefinitely (cache is only wiped when the cache *name* changes, which was hardcoded to 'dashcaddy-shell-v10'). Result: dashboard appears unchanged after a self-update until the user manually unregisters the SW. build.js now hashes the concatenated dist bundles and writes `dashcaddy-shell-<10-hex-chars>` into sw.js. Any change in dist/ produces a fresh cache name; on the next page load the SW's activate handler deletes all older caches and the new bundles are fetched.
This commit is contained in:
+25
-1
@@ -6,6 +6,7 @@ const esbuild = require('esbuild');
|
||||
const JS = (...parts) => path.join(__dirname, 'js', ...parts);
|
||||
const DIST = path.join(__dirname, 'dist');
|
||||
const INDEX_HTML = path.join(__dirname, 'index.html');
|
||||
const SW_JS = path.join(__dirname, 'sw.js');
|
||||
|
||||
// Bundle definitions — files are concatenated in order, then minified
|
||||
const bundles = {
|
||||
@@ -129,6 +130,7 @@ async function build() {
|
||||
}
|
||||
|
||||
const cspHash = updateInlineScriptCspHash();
|
||||
const cacheTag = updateServiceWorkerCache();
|
||||
|
||||
// Summary
|
||||
console.log('\n DashCaddy Frontend Build\n');
|
||||
@@ -143,7 +145,29 @@ async function build() {
|
||||
console.log(' ─────────────────────────────────────────');
|
||||
console.log(` ${'Total'.padEnd(18)} ${totalRaw.toFixed(1).padStart(6)} KB ${totalMin.toFixed(1).padStart(6)} KB`);
|
||||
console.log(`\n Output: ${DIST}`);
|
||||
console.log(` CSP Hash: sha256-${cspHash}\n`);
|
||||
console.log(` CSP Hash: sha256-${cspHash}`);
|
||||
console.log(` SW Cache: dashcaddy-shell-${cacheTag}\n`);
|
||||
}
|
||||
|
||||
// Rewrites the CACHE constant in sw.js to a tag derived from the bundle
|
||||
// contents. Every change in dist/ produces a new cache name; on next load
|
||||
// the SW's activate handler wipes all older caches, so users never get
|
||||
// stuck on stale precached bundles after a release.
|
||||
function updateServiceWorkerCache() {
|
||||
const sw = fs.readFileSync(SW_JS, 'utf8');
|
||||
const hash = crypto.createHash('sha256');
|
||||
for (const name of Object.keys(bundles)) {
|
||||
hash.update(fs.readFileSync(path.join(DIST, name)));
|
||||
}
|
||||
const tag = hash.digest('hex').slice(0, 10);
|
||||
const updated = sw.replace(
|
||||
/const CACHE = 'dashcaddy-shell-[^']+';/,
|
||||
`const CACHE = 'dashcaddy-shell-${tag}';`
|
||||
);
|
||||
if (updated !== sw) {
|
||||
fs.writeFileSync(SW_JS, updated);
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
// Watch mode
|
||||
|
||||
Reference in New Issue
Block a user