服务工作线程(Service Worker)
¥Service Worker
将 PWA 模式添加到 Quasar 项目意味着将创建一个新文件夹:/src-pwa
,包含 PWA 特定文件:
¥Adding PWA mode to a Quasar project means a new folder will be created: /src-pwa
, which contains PWA specific files:
你可以自由编辑这些文件。注意以下几点:
¥You can freely edit these files. Notice a few things:
register-service-worker.js
会自动导入到你的应用中(就像任何其他 /src 文件一样)。它注册 Service Worker(由 Workbox 创建或你自定义,取决于 Workbox 插件模式 - quasar.config 文件 > pwa > workboxPluginMode),你可以监听 Service Worker 的事件。你可以使用 ES6 代码。¥
register-service-worker.js
is automatically imported into your app (like any other /src file). It registers the service worker (created by Workbox or your custom one, depending on workbox plugin mode – quasar.config file > pwa > workboxPluginMode) and you can listen for Service Worker’s events. You can use ES6 code.仅当 Workbox 插件模式设置为 “injectManifest”(quasar.config 文件 > pwa > workboxMode: ‘injectManifest’)时,
custom-service-worker.js
才是你的 Service Worker 文件。否则,Quasar 和 Workbox 将为你创建一个 service-worker 文件。¥
custom-service-worker.js
will be your service worker file ONLY if workbox plugin mode is set to “injectManifest” (quasar.config file > pwa > workboxMode: ‘injectManifest’). Otherwise, Quasar and Workbox will create a service-worker file for you.仅在生产版本上运行 Lighthouse 测试才有意义。
¥It makes sense to run Lighthouse tests on production builds only.
提示
在 处理 Service Worker 文档页面上阅读更多关于 register-service-worker.js
以及如何与 Service Worker 交互的内容。
¥Read more on register-service-worker.js
and how to interact with the Service Worker on Handling Service Worker documentation page.
quasar.config 文件(quasar.config file)
¥quasar.config file
你可以在此处配置 Workbox 行为并调整 manifest.json。
¥This is the place where you can configure Workbox behavior and also tweak your manifest.json.
pwa: {
workboxMode?: "GenerateSW" | "InjectManifest";
/**
* Generated service worker filename to use (needs to end with .js)
* @default sw.js
*/
swFilename?: string;
/**
* PWA manifest filename to use on your browser
* @default manifest.json
*/
manifestFilename?: string;
/**
* Should you need some dynamic changes to the /src-pwa/manifest.json,
* use this method to do it.
*/
extendManifestJson?: (json: PwaManifestOptions) => void;
/**
* Does the PWA manifest tag requires crossorigin auth?
* @default false
*/
useCredentialsForManifestTag?: boolean;
/**
* Auto inject the PWA meta tags?
* If using the function form, return HTML tags as one single string.
* @default true
*/
injectPwaMetaTags?: boolean | ((injectParam: InjectPwaMetaTagsParams) => string);
/**
* Extend the Esbuild config that is used for the custom service worker
* (if using it through workboxMode: 'InjectManifest')
*/
extendPWACustomSWConf?: (config: EsbuildConfiguration) => void;
/**
* Extend/configure the Workbox GenerateSW options
*/
extendGenerateSWOptions?: (config: GenerateSWOptions) => void;
/**
* Extend/configure the Workbox InjectManifest options
*/
extendInjectManifestOptions?: (config: InjectManifestOptions) => void;
}
sourceFiles: {
pwaRegisterServiceWorker: 'src-pwa/register-service-worker',
pwaServiceWorker: 'src-pwa/custom-service-worker',
pwaManifestFile: 'src-pwa/manifest.json',
}
如果你想要篡改 /src 目录下的 Vite UI 配置:
¥Should you want to tamper with the Vite config for UI in /src:
export default defineConfig((ctx) => {
return {
build: {
extendViteConf (viteConf) {
if (ctx.mode.pwa) {
// do something with viteConf
// or return an object to deeply merge with current viteConf
}
}
}
}
})
更多信息:Workbox。
¥More information: Workbox.
在…中添加自定义元标签 index.html(Adding your own meta tags in index.html)
¥Adding your own meta tags in index.html
Quasar CLI 会(动态地)将一些面向 PWA 的元标记添加到你的 index.html 中。如果你希望自定义标签,请首先在 /quasar.config
文件中禁用此行为:
¥Quasar CLI adds (dynamically) some PWA oriented meta tags into your index.html. Should you wish to customize the tags, first disable this behavior in the /quasar.config
file:
pwa: {
injectPwaMetaTags: false
}
然后,编辑你的 /index.html
文件。以下是 Quasar CLI 动态注入的实际元标签:
¥Then, edit your /index.html
file. The following are the actual meta tags that Quasar CLI injects dynamically:
<head>
<% if (ctx.mode.pwa) { %>
<meta name="theme-color" content="<%= pwaManifest.theme_color %>">
<link rel="mask-icon" href="icons/safari-pinned-tab.svg" color="<%= pwaManifest.theme_color %>">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="msapplication-TileImage" content="icons/ms-icon-144x144.png">
<meta name="msapplication-TileColor" content="#000000">
<meta name="apple-mobile-web-app-title" content="<%= pwaManifest.name %>">
<link rel="apple-touch-icon" href="icons/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="152x152" href="icons/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="167x167" href="icons/apple-icon-167x167.png">
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-icon-180x180.png">
<% } %>
</head>
请注意,你可以通过上面的 pwaManifest
访问你的 PWA 清单。
¥Notice that you have access to your PWA manifest through pwaManifest
above.
或者,你可以像下面这样为 injectPwaMetaTags 分配一个函数:
¥Alternatively, you can assign a function to injectPwaMetaTags like below:
pwa: {
injectPwaMetaTags ({ pwaManifest, publicPath }) {
return `<meta name="mobile-web-app-capable" content="yes">`
+ `<meta name="apple-mobile-web-app-status-bar-style" content="default">`
}
}
选择 Workbox 模式(Picking Workbox mode)
¥Picking Workbox mode
Workbox 有两种运行模式:生成 SW(默认)并注入清单。
¥There are two Workbox operating modes: generateSW (default) and injectManifest.
你可以通过 /quasar.config
文件设置要使用的模式:
¥Setting the mode that you want to use is done through the /quasar.config
file:
pwa: {
workboxMode: 'generateSW',
extendGenerateSWOptions (cfg) {
// configure workbox on generateSW
}
}
pwa: {
workboxMode: 'injectManifest',
extendInjectManifestOptions (cfg) {
// configure workbox on injectManifest
}
}
generateSW(generateSW)
何时使用 generateSW:
¥When to use generateSW:
你希望预缓存文件。
¥You want to precache files.
你有简单的运行时配置需求(例如,配置允许你定义路由和策略)。
¥You have simple runtime configuration needs (e.g. the configuration allows you to define routes and strategies).
何时不使用 generateSW:
¥When NOT to use generateSW:
你希望使用其他 Service Worker 功能(例如 Web 推送)。
¥You want to use other Service Worker features (i.e. Web Push).
你希望导入其他脚本或添加其他逻辑。
¥You want to import additional scripts or add additional logic.
提示
请检查 Workbox 网站 上此模式可用的 workboxOptions。
¥Please check the available workboxOptions for this mode on Workbox website.
InjectManifest(InjectManifest)
何时使用 InjectManifest:
¥When to use InjectManifest:
你希望更好地控制 Service Worker。
¥You want more control over your service worker.
你希望预缓存文件。
¥You want to precache files.
你在路由方面有更复杂的需求。
¥You have more complex needs in terms of routing.
你希望将 Service Worker 与其他 API(例如 Web Push)一起使用。
¥You would like to use your service worker with other APIs (e.g. Web Push).
何时不使用 InjectManifest:
¥When NOT to use InjectManifest:
你希望以最简单的方式将 Service Worker 添加到你的网站。
¥You want the easiest path to adding a service worker to your site.
TIPS
如果你想使用此模式,则必须自行编写 Service Worker (
/src-pwa/custom-service-worker.js
) 文件。¥If you want to use this mode, you will have to write the service worker (
/src-pwa/custom-service-worker.js
) file by yourself.请检查 Workbox 网站 上此模式可用的 workboxOptions。
¥Please check the available workboxOptions for this mode on Workbox website.
以下代码片段是自定义 Service Worker (/src-pwa/custom-service-worker.js
) 的默认代码,它模拟了 generateSW
模式的行为:
¥The following snippet is the default code for a custom service worker (/src-pwa/custom-service-worker.js
) which mimics the behavior of generateSW
mode:
/*
* This file (which will be your service worker)
* is picked up by the build system ONLY if
* quasar.config file > pwa > workboxMode is set to "injectManifest"
*/
import { clientsClaim } from 'workbox-core'
import {
precacheAndRoute,
cleanupOutdatedCaches,
createHandlerBoundToURL,
} from 'workbox-precaching'
import { registerRoute, NavigationRoute } from 'workbox-routing'
self.skipWaiting();
clientsClaim();
// Use with precache injection
precacheAndRoute(self.__WB_MANIFEST)
cleanupOutdatedCaches()
// Non-SSR fallbacks to index.html
// Production SSR fallbacks to offline.html (except for dev)
if (process.env.MODE !== 'ssr' || process.env.PROD) {
registerRoute(
new NavigationRoute(
createHandlerBoundToURL(process.env.PWA_FALLBACK_HTML),
{ denylist: [new RegExp(process.env.PWA_SERVICE_WORKER_REGEX), /workbox-(.)*\.js$/] }
)
)
}
配置 Manifest 文件(Configuring Manifest File)
¥Configuring Manifest File
Manifest 文件位于 /src-pwa/manifest.json
。你可以自由编辑它。
¥The Manifest file is located at /src-pwa/manifest.json
. You can freely edit it.
如果你需要在构建时动态更改它,可以通过编辑 /quasar.config
文件来实现:
¥Should you need to change it dynamically at build time, you can do so by editing the /quasar.config
file:
pwa: {
extendManifestJson (json) {
// tamper with the json inline
}
}
在深入研究之前,请先阅读有关 manifest 配置 的信息。
¥Please read about the manifest config before diving in.
警告
请注意,你无需编辑 index.html 文件(由 /index.html
生成)即可链接到清单文件。Quasar CLI 会负责为你嵌入正确的内容。
¥Note that you don’t need to edit your index.html file (generated from /index.html
) to link to the manifest file. Quasar CLI takes care of embedding the right things for you.
提示
如果你的 PWA 支持基本身份验证或需要授权标头,请将 quasar.config 文件 > pwa > useCredentialsForManifestTag 设置为 true
,以便在 manifest.json 元标记中包含 crossorigin="use-credentials"
。
¥If your PWA is behind basic auth or requires an Authorization header, set quasar.config file > pwa > useCredentialsForManifestTag to true
to include crossorigin="use-credentials"
on the manifest.json meta tag.
PWA 清单(PWA Checklist)
¥PWA Checklist
更多信息:PWA 清单
¥More info: PWA Checklist
危险
请勿在你的开发版本上运行 Lighthouse,因为在此阶段,代码故意未进行优化,并且包含嵌入的源映射(以及许多其他内容)。有关更多信息,请参阅这些文档的 测试与审计 部分。
¥Do not run Lighthouse on your development build because at this stage the code is intentionally not optimized and contains embedded source maps (among many other things). See the Testing and Auditing section of these docs for more information.
自动重新加载和更新(Reload & Update Automatically)
¥Reload & Update Automatically
对于那些不想在 Service Worker 更新时手动重新加载页面并使用默认 generateSW 工作箱模式的用户,Quasar CLI 已配置 Workbox 以立即激活它。如果你需要禁用此行为:
¥For those who don’t want to manually reload the page when the service worker is updated and are using the default generateSW workbox mode, Quasar CLI has configured Workbox to activate it at once. Should you need to disable this behavior:
pwa: {
extendGenerateSWOptions (cfg) {
cfg.skipWaiting = false
cfg.clientsClaim = false
}
}
文件名哈希值怪异(Filename hashes quirk)
¥Filename hashes quirk
由于 Rollup 构建资源的方式(通过 Vite),当你更改任何脚本源文件 (.js) 时,这也会更改(几乎)所有 .js 文件的哈希值部分(例如:assets/index.454d87bd.js
中的 454d87bd
)。Service Worker 文件中所有资源的修订号都会更改,这意味着当 PWA 更新时,它会重新下载所有资源。更新 PWA 真是浪费带宽,而且耗时太长!
¥Due to how Rollup builds the assets (through Vite), when you change any of your script source files (.js) this will also change the hash part of (almost) ALL .js files (ex: 454d87bd
in assets/index.454d87bd.js
). The revision number of all assets will get changed in your service worker file and this means that when PWA updates it will re-download ALL your assets again. What a waste of bandwidth and such a longer time to get the PWA updated!
默认情况下,Vite 使用哈希值部分构建所有文件名。但是,如果你希望文件名不包含哈希部分,则需要编辑 /quasar.config
文件:
¥By default, Vite builds all filenames with the hash part. However, should you want your filenames to NOT contain the hash part, you need to edit the /quasar.config
file:
build: {
useFilenameHashes: false // true by default
}
禁用文件名哈希值时,最好确保你的 Web 服务器也相应地设置了缓存(尽可能低),以确保向无法使用 PWA 功能的客户端提供一致的资源交付。
¥When filename hashes are disabled it would be wise to also make sure that your webserver has cache set accordingly (as low as possible) to ensure consistent resource delivery to your clients that can’t use the PWA functionality.