SvelteKit 最新中文文档教程(16)—— Service workers

news/2025/4/2 10:54:52/文章来源:https://www.cnblogs.com/yayujs/p/18802929

前言

Svelte,一个语法简洁、入门容易,面向未来的前端框架。

从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1

image.png

Svelte 以其独特的编译时优化机制著称,具有轻量级高性能易上手等特性,非常适合构建轻量级 Web 项目

为了帮助大家学习 Svelte,我同时搭建了 Svelte 最新的中文文档站点。

如果需要进阶学习,也可以入手我的小册《Svelte 开发指南》,语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!

欢迎围观我的“网页版朋友圈”、加入“冴羽·成长陪伴社群”,踏上“前端大佬成长之路”。

Service workers

Service workers 作为代理服务端,处理应用程序内部的网络请求。这使得您的应用程序能够离线工作,但即使您不需要离线支持(或由于您正在构建的应用程序类型而无法实现它),使用 service workers 预缓存构建的 JS 和 CSS 来加快导航速度,通常也是值得的。

在 SvelteKit 中,如果您有一个 src/service-worker.js 文件(或 src/service-worker/index.js),它将被打包并自动注册。如果需要,您可以更改 service worker 的位置。

如果您需要使用自己的逻辑注册 service worker 或使用其他解决方案,可以禁用自动注册。默认注册看起来类似这样:

if ('serviceWorker' in navigator) {addEventListener('load', function () {navigator.serviceWorker.register('./path/to/service-worker.js');});
}

Service Worker 内部

在 service worker 内部,您可以访问 $service-worker 模块,它为您提供所有静态资源、构建文件和预渲染页面的路径。您还会获得一个应用程序版本字符串,可用于创建唯一的缓存名称,以及部署的 base 路径。如果您的 Vite 配置指定了 define(用于全局变量替换),这也将应用于 service workers 以及服务端/客户端构建。

以下示例会尽可能早的缓存构建的应用程序和 static 中的所有文件,并在访问时缓存所有其他请求。这将使每个页面在访问后都能离线工作。

// @errors: 2339
/// <reference types="@sveltejs/kit" />
import { build, files, version } from '$service-worker';// 为此部署创建唯一的缓存名称
const CACHE = `cache-${version}`;const ASSETS = [...build, // 应用程序本身...files // `static` 中的所有内容
];self.addEventListener('install', (event) => {// 创建新缓存并添加所有文件async function addFilesToCache() {const cache = await caches.open(CACHE);await cache.addAll(ASSETS);}event.waitUntil(addFilesToCache());
});self.addEventListener('activate', (event) => {// 从磁盘删除以前的缓存数据async function deleteOldCaches() {for (const key of await caches.keys()) {if (key !== CACHE) await caches.delete(key);}}event.waitUntil(deleteOldCaches());
});self.addEventListener('fetch', (event) => {// 忽略 POST 请求等if (event.request.method !== 'GET') return;async function respond() {const url = new URL(event.request.url);const cache = await caches.open(CACHE);// `build`/`files` 始终可以从缓存中提供服务if (ASSETS.includes(url.pathname)) {const response = await cache.match(url.pathname);if (response) {return response;}}// 对于其他所有内容,首先尝试网络// 但如果我们离线,则回退到缓存try {const response = await fetch(event.request);// 如果我们离线,fetch 可能返回非 Response 值// 而不是抛出错误 - 我们不能将这个非 Response 传递给 respondWithif (!(response instanceof Response)) {throw new Error('invalid response from fetch');}if (response.status === 200) {cache.put(event.request, response.clone());}return response;} catch (err) {const response = await cache.match(event.request);if (response) {return response;}// 如果没有缓存,就直接报错// 因为我们无法对这个请求做任何响应throw err;}}event.respondWith(respond());
});

[!NOTE] 缓存时要小心!在某些情况下,过时的数据可能比离线时无法获取的数据更糟糕。由于浏览器会在缓存太满时清空缓存,因此您还应该谨慎缓存大型资源,如视频文件。

在开发过程中

service worker 在生产环境中会被打包,但在开发过程中不会。因此,只有支持 service workers 中的模块 的浏览器才能在开发时使用它们。如果您手动注册 service worker,在开发时需要传递 { type: 'module' } 选项:

import { dev } from '$app/environment';navigator.serviceWorker.register('/service-worker.js', {type: dev ? 'module' : 'classic'
});

[!NOTE] 在开发环境中,buildprerendered 是空数组

类型安全

为 service workers 设置适当的类型需要一些手动设置。在您的 service-worker.js 中,在文件顶部添加以下内容:

/// <reference types="@sveltejs/kit" />
/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />
/// <reference lib="webworker" />const sw = /** @type {ServiceWorkerGlobalScope} */ (/** @type {unknown} */ (self));
/// <reference types="@sveltejs/kit" />
/// <reference no-default-lib="true"/>
/// <reference lib="esnext" />
/// <reference lib="webworker" />const sw = self as unknown as ServiceWorkerGlobalScope;

这会禁用对 service worker 中不可用的 DOM 类型(如 HTMLElement)的访问,并实例化正确的全局变量。将 self 重新赋值给 sw 允许您在此过程中进行类型转换(有几种方法可以做到这一点,但这是最简单的,不需要额外的文件)。在文件的其余部分使用 sw 而不是 self

对 SvelteKit 类型的引用确保 $service-worker 导入具有适当的类型定义。如果您导入 $env/static/public,您要么必须使用 // @ts-ignore 注释导入,要么添加 /// <reference types="../.svelte-kit/ambient.d.ts" /> 到引用类型中。

其他解决方案

SvelteKit 的 service worker 实现故意保持低级别。如果您需要更全功能但也更有主见的解决方案,我们建议查看像 Vite PWA 插件 这样的解决方案,它使用 Workbox。有关 service workers 的更多一般信息,我们推荐 MDN web 文档。

Svelte 中文文档

点击查看中文文档:SvelteKit Service workers

系统学习 Svelte,欢迎入手小册《Svelte 开发指南》。语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!

此外我还写过 JavaScript 系列、TypeScript 系列、React 系列、Next.js 系列、冴羽答读者问等 14 个系列文章, 全系列文章目录:https://github.com/mqyqingfeng/Blog

欢迎围观我的“网页版朋友圈”、加入“冴羽·成长陪伴社群”,踏上“前端大佬成长之路”。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/908823.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OLLAMA 自定义大模型角色

在Ollama中通过deepseek-r1生成特定角色的模板(如教案设计),核心是通过Modelfile定义模型的系统提示(SYSTEM)和对话模板(TEMPLATE)。以下是具体步骤和示例: 一、Modelfile 基本结构与关键指令FROM指令指定基础模型,这里你可以使用ollama本地下载的模型,也可以去Huggi…

WebSocket调试神器对决:Apipost凭何碾压Apifox?

你以为所有API工具都能玩转WebSocket? 当你的APP需要实时股票行情推送,当你的游戏要处理千人同屏交互,当你的IM系统必须保障消息零延迟——传统HTTP协议的"一问一答"模式瞬间破功。此刻WebSocket协议才是真正的救世主,这个全双工通信协议能让客户端与服务器建立&…

一年前的无心之举,一年后我想要将其做的更好——公众号开通。

大家好,答应的事情要做到。 我是晚秋,我在这里,这是我的公众号。 一年前我想把学过的技术,解决得问题都记录下来,帮助更多的人。 日复一日,也放弃过。 但是到今日,忽然看到自己的无心之举帮助了很多刚进入技术这一行的人。 他们迷茫,他们困顿,正如当初的我一样。 谢谢…

用户头像呼吸光环+鼠标悬停旋转放大

用户头像呼吸光环+鼠标悬停旋转放大在 子比主题后台 – 自定义代码 – 自定 CSS 样式代码 里面添加下面代码: /*【用户头像呼吸光环+鼠标悬停旋转放大】开始 */ .avatar{border-radius: 50%; animation: light 4s ease-in-out infinite; transition: 0.5s;}.avatar:hover{tran…

开源守护,智护童年——幼儿园未成年行为与安全智能监控系统

在孩子成长的每一步,安全始终是第一位的。幼儿园作为孩子们探索世界的起点,其安全管理的重要性不言而喻。然而,哭闹、打闹、意外跌倒,甚至外部隐患如陌生人逗留、内部管理疏漏等问题,常常让传统人工监控捉襟见肘。家长们也迫切希望了解孩子在园的点滴,渴望一份安心与信任…

20241220廖补林实验二《Python程序设计》实验报告

实验二 计算器设计 (一)实验内容 设计并完成一个完整的应用程序,完成加减乘除模等运算,功能多多益善。 考核基本语法、判定语句、循环语句、逻辑运算等知识点 (二)实验要求 创建工程项目,使用Python语言实现具体的操作运算,并完成程序调试和运行,代码托管到码云。 我用…

网络基础

一、概念 冲突域设备发送数据会产生冲突的网络范围 集线器的所有接口在同一个冲突域 交换机的每个接口都是一个独立的冲突域寻址IP寻址是寻找目标在某一个范围 MAC寻址是具体寻找某一个设备MTU数据包的最大传输单元 接口收发数据支持的单个包的最大长度 以太网接口默认MTU1500B…

20241309 实验二《Python程序设计》实验报告

20241309 2024-2025-2 《Python程序设计》实验二报告 课程:《Python程序设计》 班级: 2413 姓名: 梅良谦 学号:20241309 实验教师:王志强 实验日期:2025年3月26日 必修/选修: 公选课 一、实验内容 1.设计并完成一个完整的应用程序,完成加减乘除模等运算,功能多多益善。…

【操作系统】进程管理(二)

一、前言之前已经介绍了操作系统的各个模块,现在来具体深入学习操作系统中的进程管理。 二、进程的基本概念在未配置OS的系统中,程序的执行方式是顺序执行,即必须在一个程序执行完成后,才允许另外一个程序执行;在多道程序环境下,则允许多个程序并发执行。也正是程序的并发…

MybatisPlus--持久层接口

IService: Save()boolean save(T entity) //批量插入 boolean saveBatch(Collection<T> entityList) boolean saveBatch(Collection<T> entityList, int vatchSIze)SQL:INSERT INTO user (name, email) VALUES (John Doe, john.doe@example.com)批量SQL:INSERT…

CH58x/CH59x动态修改广播包

前言:在日常使用中我们可能有需要动态修改广播包的情况。从机设备不走连接将一些传感器数据通过广播包显示出来 程序中提供了接口函数进行动态修改不用再先关闭广播再重新开启。/******************************************************************************** @fn …