问题

最近发现了一个奇怪的 bug,在笔记项目rhombsvelte迁移到sveltekit后,PWA功能失效了。

导致在tauri中打包后的网页,在每次打开时都会登录错误。

在清除tauri的缓存和service worker后,发现问题依然存在,并且service worker也无法注册。

最后发现是vite-pwa插件和SvelteKit的自带PWA功能冲突导致的。需要重新配置vite-pwa插件。

简介

vite-pwa是一个用于在Vite项目中添加PWA功能的插件。

针对SvelteKit项目,有一个专门的子项目vite-pwa/sveltekit

安装

pnpm add -D @vite-pwa/sveltekit

配置

SvelteKit中的配置

SvelteKit中的svelte.config.js里需要取消生成自带的PWA配置文件service-worker.js

import adapter from "@sveltejs/adapter-static";
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
import preprocessReact from "svelte-preprocess-react/preprocessReact";

/** @type {import('@sveltejs/kit').Config} */
const config = {
  kit: {
    adapter: adapter({
      fallback: "index.html", // may differ from host to host
    }),
    serviceWorker: {
      register: false, // 取消生成 service-worker.js
    },
  },
  preprocess: [vitePreprocess(), preprocessReact()],
};

export default config;

Vite中的配置

Vite中的vite.config.js里添加vite-pwa插件。

// vite.config.js / vite.config.ts
import { SvelteKitPWA } from "@vite-pwa/sveltekit";

/** @type {import('vite').UserConfig} */
const config = {
  plugins: [
    sveltekit(),
    SvelteKitPWA({
      /* pwa options */
    }),
  ],
};

export default config;

SvelteKit中添加注册 service worker

SvelteKit中的src/routes/++layout.svelte里添加注册service worker的代码。

<script>
	import { pwaInfo } from "virtual:pwa-info";
	import { onMount } from "svelte";

	onMount(async () => {
		if (pwaInfo) {
			const { registerSW } = await import("virtual:pwa-register");
			registerSW({
				immediate: true,
				onRegistered(r) {
					// uncomment following code if you want check for updates
					// r && setInterval(() => {
					//    console.log('Checking for sw update')
					//    r.update()
					// }, 20000 /* 20s for testing purposes */)
					console.log(`SW Registered: ${r}`);
				},
				onRegisterError(error) {
					console.log("SW registration error", error);
				}
			});
		}
	});
</script>

参考