Svelte
You can use the built-in Vite
virtual module virtual:pwa-register/svelte
for Svelte
which will return writable
stores (Writable<boolean>
) for offlineReady
and needRefresh
.
警告
你需要将 workbox-window
作为 dev
依赖添加到你的 Vite
项目中
类型声明
提示
如果你的 TypeScript 构建时或 IDE 抱怨在导入时找不到模块或类型定义,请将以下内容添加到tsconfig.json
的 compilerOptions.types
数组中:
{
"compilerOptions": {
"types": ["vite-plugin-pwa/client"]
}
}
或者你可以添加以下引用到任何 d.ts
文件中(例如,在 vite-env.d.ts
或 global.d.ts
中):
/// <reference types="vite-plugin-pwa/client" />
From version 0.14.5
you can also use types definition for svelte instead of vite-plugin-pwa/client
:
{
"compilerOptions": {
"types": ["vite-plugin-pwa/svelte"]
}
}
Or you can add the following reference in any of your d.ts
files (for example, in vite-env.d.ts
or global.d.ts
):
/// <reference types="vite-plugin-pwa/svelte" />
declare module 'virtual:pwa-register/svelte' {
import type { Writable } from 'svelte/store';
import type { RegisterSWOptions } from 'vite-plugin-pwa/types';
export type { RegisterSWOptions };
export function useRegisterSW(options?: RegisterSWOptions): {
needRefresh: Writable<boolean>;
offlineReady: Writable<boolean>;
updateServiceWorker: (reloadPage?: boolean) => Promise<void>;
};
}
Prompt for update
You can use this ReloadPrompt.svelte
component:
ReloadPrompt.svelte
<script lang="ts">
import { useRegisterSW } from 'virtual:pwa-register/svelte';
const { offlineReady, needRefresh, updateServiceWorker } = useRegisterSW({
onRegistered(swr) {
console.log(`SW registered: ${swr}`);
},
onRegisterError(error) {
console.log('SW registration error', error);
}
});
function close() {
offlineReady.set(false)
needRefresh.set(false)
}
$: toast = $offlineReady || $needRefresh;
</script>
{#if toast}
<div
class="pwa-toast"
role="alert"
>
<div class="message">
{#if $offlineReady}
<span>
App ready to work offline
</span>
{:else}
<span>
New content available, click on reload button to update.
</span>
{/if}
</div>
{#if $needRefresh}
<button on:click={() => updateServiceWorker(true)}>
Reload
</button>
{/if}
<button on:click={close}>
Close
</button>
</div>
{/if}
<style>
.pwa-toast {
position: fixed;
right: 0;
bottom: 0;
margin: 16px;
padding: 12px;
border: 1px solid #8885;
border-radius: 4px;
z-index: 1;
text-align: left;
box-shadow: 3px 4px 5px 0 #8885;
background-color: white;
}
.pwa-toast .message {
margin-bottom: 8px;
}
.pwa-toast button {
border: 1px solid #8885;
outline: none;
margin-right: 5px;
border-radius: 2px;
padding: 3px 10px;
}
</style>
Periodic SW Updates
As explained in 定期更新 Service Worker , you can use this code to configure this behavior on your application with the virtual module virtual:pwa-register/svelte
:
import { useRegisterSW } from 'virtual:pwa-register/svelte';
const intervalMS = 60 * 60 * 1000;
const updateServiceWorker = useRegisterSW({
onRegistered(r) {
r &&
setInterval(() => {
r.update();
}, intervalMS);
},
});
The interval must be in milliseconds, in the example above it is configured to check the service worker every hour.
警告
这只适用于在导入任何虚拟模块或使用 workbox-window
模块时
因为 workbox-window
使用基于时间的 heuristic
算法来处理 service worker 更新,因此,如果您构建了自己的 service worker 并再次注册它,如果上次注册和本次注册之间的时间不足 1 分钟,那么workbox-window
将把 service worker update found
事件作为外部事件处理,因此可能会有很奇怪的行为(例如,如果使用 prompt
,将显示离线准备就绪的对话框,而不是显示新内容可用的对话框;如果使用 autoUpdate
,将显示离线准备就绪的对话框,然而它不应该显示)。