Clean up service worker code and fix 404 (#5855)
parent
86bbac430c
commit
2153bc536c
|
@ -19,6 +19,8 @@ gulp.task("gen-service-worker-app-dev", (done) => {
|
||||||
console.debug('Service worker disabled in development');
|
console.debug('Service worker disabled in development');
|
||||||
|
|
||||||
self.addEventListener('install', (event) => {
|
self.addEventListener('install', (event) => {
|
||||||
|
// This will activate the dev service worker,
|
||||||
|
// removing any prod service worker the dev might have running
|
||||||
self.skipWaiting();
|
self.skipWaiting();
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
|
@ -27,6 +29,17 @@ self.addEventListener('install', (event) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task("gen-service-worker-app-prod", async () => {
|
gulp.task("gen-service-worker-app-prod", async () => {
|
||||||
|
// Read bundled source file
|
||||||
|
const bundleManifest = require(path.resolve(paths.output, "manifest.json"));
|
||||||
|
let serviceWorkerContent = fs.readFileSync(
|
||||||
|
paths.root + bundleManifest["service_worker.js"],
|
||||||
|
"utf-8"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Delete old file from frontend_latest so manifest won't pick it up
|
||||||
|
fs.removeSync(paths.root + bundleManifest["service_worker.js"]);
|
||||||
|
fs.removeSync(paths.root + bundleManifest["service_worker.js.map"]);
|
||||||
|
|
||||||
const workboxManifest = await workboxBuild.getManifest({
|
const workboxManifest = await workboxBuild.getManifest({
|
||||||
// Files that mach this pattern will be considered unique and skip revision check
|
// Files that mach this pattern will be considered unique and skip revision check
|
||||||
// ignore JS files + translation files
|
// ignore JS files + translation files
|
||||||
|
@ -37,7 +50,8 @@ gulp.task("gen-service-worker-app-prod", async () => {
|
||||||
"frontend_latest/*.js",
|
"frontend_latest/*.js",
|
||||||
// Cache all English translations because we catch them as fallback
|
// Cache all English translations because we catch them as fallback
|
||||||
// Using pattern to match hash instead of * to avoid caching en-GB
|
// Using pattern to match hash instead of * to avoid caching en-GB
|
||||||
"static/translations/**/en-+([a-f0-9]).json",
|
// 'v' added as valid hash letter because in dev we hash with 'dev'
|
||||||
|
"static/translations/**/en-+([a-fv0-9]).json",
|
||||||
// Icon shown on splash screen
|
// Icon shown on splash screen
|
||||||
"static/icons/favicon-192x192.png",
|
"static/icons/favicon-192x192.png",
|
||||||
"static/icons/favicon.ico",
|
"static/icons/favicon.ico",
|
||||||
|
@ -53,20 +67,6 @@ gulp.task("gen-service-worker-app-prod", async () => {
|
||||||
console.warn(warning);
|
console.warn(warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace `null` with 0 for better compression
|
|
||||||
for (const entry of workboxManifest.manifestEntries) {
|
|
||||||
if (entry.revision === null) {
|
|
||||||
entry.revision = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const manifest = require(path.resolve(paths.output, "manifest.json"));
|
|
||||||
|
|
||||||
// Write bundled source file
|
|
||||||
let serviceWorkerContent = fs.readFileSync(
|
|
||||||
paths.root + manifest["service_worker.js"],
|
|
||||||
"utf-8"
|
|
||||||
);
|
|
||||||
// remove source map and add WB manifest
|
// remove source map and add WB manifest
|
||||||
serviceWorkerContent = sourceMapUrl.removeFrom(serviceWorkerContent);
|
serviceWorkerContent = sourceMapUrl.removeFrom(serviceWorkerContent);
|
||||||
serviceWorkerContent = serviceWorkerContent.replace(
|
serviceWorkerContent = serviceWorkerContent.replace(
|
||||||
|
@ -76,8 +76,4 @@ gulp.task("gen-service-worker-app-prod", async () => {
|
||||||
|
|
||||||
// Write new file to root
|
// Write new file to root
|
||||||
fs.writeFileSync(swDest, serviceWorkerContent);
|
fs.writeFileSync(swDest, serviceWorkerContent);
|
||||||
|
|
||||||
// Delete old file from frontend_latest
|
|
||||||
fs.removeSync(paths.root + manifest["service_worker.js"]);
|
|
||||||
fs.removeSync(paths.root + manifest["service_worker.js.map"]);
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -184,7 +184,7 @@ export class HcConnect extends LitElement {
|
||||||
this.castManager = null;
|
this.castManager = null;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
registerServiceWorker(false);
|
registerServiceWorker(this, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _handleDemo() {
|
private async _handleDemo() {
|
||||||
|
|
|
@ -121,7 +121,7 @@ class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
||||||
const tempA = document.createElement("a");
|
const tempA = document.createElement("a");
|
||||||
tempA.href = this.redirectUri!;
|
tempA.href = this.redirectUri!;
|
||||||
if (tempA.host === location.host) {
|
if (tempA.host === location.host) {
|
||||||
registerServiceWorker(false);
|
registerServiceWorker(this, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,10 +164,18 @@ self.addEventListener("install", (event) => {
|
||||||
event.waitUntil(caches.delete(cacheName));
|
event.waitUntil(caches.delete(cacheName));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
self.addEventListener("activate", () => {
|
||||||
|
// Attach the service worker to any page of the app
|
||||||
|
// that didn't have a service worker loaded.
|
||||||
|
// Happens the first time they open the app without any
|
||||||
|
// service worker registered.
|
||||||
|
// This will serve code splitted bundles from SW.
|
||||||
|
clients.claim();
|
||||||
|
});
|
||||||
|
|
||||||
self.addEventListener("message", (message) => {
|
self.addEventListener("message", (message) => {
|
||||||
if (message.data.type === "skipWaiting") {
|
if (message.data.type === "skipWaiting") {
|
||||||
self.skipWaiting();
|
self.skipWaiting();
|
||||||
clients.claim();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ export class HomeAssistantAppEl extends HassElement {
|
||||||
protected firstUpdated(changedProps) {
|
protected firstUpdated(changedProps) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
this._initialize();
|
this._initialize();
|
||||||
setTimeout(registerServiceWorker, 1000);
|
setTimeout(() => registerServiceWorker(this), 1000);
|
||||||
/* polyfill for paper-dropdown */
|
/* polyfill for paper-dropdown */
|
||||||
import(
|
import(
|
||||||
/* webpackChunkName: "polyfill-web-animations-next" */ "web-animations-js/web-animations-next-lite.min"
|
/* webpackChunkName: "polyfill-web-animations-next" */ "web-animations-js/web-animations-next-lite.min"
|
||||||
|
|
|
@ -96,7 +96,7 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) {
|
||||||
import(
|
import(
|
||||||
/* webpackChunkName: "onboarding-core-config" */ "./onboarding-core-config"
|
/* webpackChunkName: "onboarding-core-config" */ "./onboarding-core-config"
|
||||||
);
|
);
|
||||||
registerServiceWorker(false);
|
registerServiceWorker(this, false);
|
||||||
this.addEventListener("onboarding-step", (ev) => this._handleStepDone(ev));
|
this.addEventListener("onboarding-step", (ev) => this._handleStepDone(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,49 +1,57 @@
|
||||||
import { HassElement } from "../state/hass-element";
|
|
||||||
import { showToast } from "./toast";
|
import { showToast } from "./toast";
|
||||||
|
|
||||||
export const supportsServiceWorker = () =>
|
export const supportsServiceWorker = () =>
|
||||||
"serviceWorker" in navigator &&
|
"serviceWorker" in navigator &&
|
||||||
(location.protocol === "https:" || location.hostname === "localhost");
|
(location.protocol === "https:" || location.hostname === "localhost");
|
||||||
|
|
||||||
export const registerServiceWorker = (notifyUpdate = true) => {
|
export const registerServiceWorker = async (
|
||||||
|
rootEl: HTMLElement,
|
||||||
|
notifyUpdate = true
|
||||||
|
) => {
|
||||||
if (!supportsServiceWorker()) {
|
if (!supportsServiceWorker()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
navigator.serviceWorker.register("/service_worker.js").then((reg) => {
|
|
||||||
reg.addEventListener("updatefound", () => {
|
|
||||||
const installingWorker = reg.installing;
|
|
||||||
if (!installingWorker || !notifyUpdate) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
installingWorker.addEventListener("statechange", () => {
|
|
||||||
if (
|
|
||||||
installingWorker.state === "installed" &&
|
|
||||||
navigator.serviceWorker.controller &&
|
|
||||||
!__DEV__ &&
|
|
||||||
!__DEMO__
|
|
||||||
) {
|
|
||||||
// Notify users here of a new frontend being available.
|
|
||||||
const haElement = window.document.querySelector(
|
|
||||||
"home-assistant, ha-onboarding"
|
|
||||||
)! as HassElement;
|
|
||||||
showToast(haElement, {
|
|
||||||
message: "A new version of the frontend is available.",
|
|
||||||
action: {
|
|
||||||
action: () =>
|
|
||||||
installingWorker.postMessage({ type: "skipWaiting" }),
|
|
||||||
text: "reload",
|
|
||||||
},
|
|
||||||
duration: 0,
|
|
||||||
dismissable: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// If the active service worker changes, refresh the page because the cache has changed
|
// If the active service worker changes, refresh the page because the cache has changed
|
||||||
navigator.serviceWorker.addEventListener("controllerchange", () => {
|
navigator.serviceWorker.addEventListener("controllerchange", () => {
|
||||||
location.reload();
|
location.reload();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const reg = await navigator.serviceWorker.register("/service_worker.js");
|
||||||
|
|
||||||
|
if (!notifyUpdate || __DEV__ || __DEMO__) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
reg.addEventListener("updatefound", () => {
|
||||||
|
const installingWorker = reg.installing;
|
||||||
|
|
||||||
|
if (!installingWorker) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
installingWorker.addEventListener("statechange", () => {
|
||||||
|
if (
|
||||||
|
installingWorker.state !== "installed" ||
|
||||||
|
!navigator.serviceWorker.controller
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify users a new frontend is available.
|
||||||
|
// When
|
||||||
|
showToast(rootEl, {
|
||||||
|
message: "A new version of the frontend is available.",
|
||||||
|
action: {
|
||||||
|
// We tell the service worker to call skipWaiting, which activates
|
||||||
|
// the new service worker. Above we listen for `controllerchange`
|
||||||
|
// so we reload the page once a new servic worker activates.
|
||||||
|
action: () => installingWorker.postMessage({ type: "skipWaiting" }),
|
||||||
|
text: "reload",
|
||||||
|
},
|
||||||
|
duration: 0,
|
||||||
|
dismissable: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue