Quasar CLI with Vite - @quasar/app-vite
PWA配置

Service Worker

向Quasar项目添加PWA模式意味着将创建一个新文件夹:/src-pwa,其中包含PWA特定文件:

.
└── src-pwa/
    ├── register-service-worker-dev.js   # (或.ts)UI代码**管理**Service Worker
    ├── manifest.json               # 您的PWA manifest文件
    └── custom-service-worker.js    # (或.ts)可选的自定义的service worker文件
                                    # (仅injectManifest模式)

您可以自由编辑这些文件。 注意一些事情:

  1. register-service-worker.[js|ts]会自动导入您的应用程序(与任何其他/src文件一样)。它注册service worker(由Workbox或您的自定义工具创建,具体取决于工作箱插件模式 - quasar.conf.js> pwa> workboxPluginMode),您可以监听Service Worker的事件。您可以使用ES6代码。
  2. 如果工作箱插件模式设置为“InjectManifest”(quasar.conf.js> pwa> workboxMode:‘injectManifest’),custom-service-worker.[js|ts]将成为您的service worker文件。否则,Quasar和Workbox将为您创建一个service-worker文件。
  3. 仅在生产版本上运行Lighthouse测试是有意义的。

TIP

阅读更多关于register-service-worker.[js|ts]的信息以及如何与处理Service Worker文档页面上的Service Worker进行交互。

quasar.config.js

在这里您可以配置Workbox行为并调整manifest.json。

pwa: {
  workboxMode: 'generateSW', // or 'injectManifest'
  injectPwaMetaTags: true,
  swFilename: 'sw.js',
  manifestFilename: 'manifest.json',
  useCredentialsForManifestTag: false,
  extendGenerateSWOptions (cfg) {},
  extendInjectManifestOptions (cfg) {},
  extendManifestJson (json) {},
  extendPWACustomSWConf (esbuildConf) {}
}

sourceFiles: {
  pwaRegisterServiceWorker: 'src-pwa/register-service-worker',
  pwaServiceWorker: 'src-pwa/custom-service-worker',
  pwaManifestFile: 'src-pwa/manifest.json',
}

如果你想篡改/src中UI的Vite配置:

// quasar.config.js
module.exports = function (ctx) {
  return {
    build: {
      extendViteConf (viteConf) {
        if (ctx.mode.pwa) {
          // do something with ViteConf
        }
      }
    }
  }
}

更多信息: Workbox.

在index.html中添加你自己的meta标签

Quasar CLI在你的index.html中(动态地)添加一些面向PWA的元标签。如果您想定制这些标签,请先在/quasar.config.js中禁用这一行为:

// quasar.config.js
pwa: {
  injectPwaMetaTags: false
}

然后,编辑你的/index.html文件。以下是Quasar CLI动态注入的实际meta标签:

<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="apple-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清单。

挑选工作箱(Workbox)模式

有两种工作箱操作模式。generateSW(默认)和injectManifest

设置你想使用的模式是通过quasar.config.js完成的:

// quasar.config.js

pwa: {
  workboxMode: 'generateSW',
  extendGenerateSWOptions (cfg) {
    // configure workbox on generateSW
  }
}

pwa: {
  workboxMode: 'injectManifest',
  extendInjectManifestOptions (cfg) {
    // configure workbox on injectManifest
  }
}

generateSW

何时使用generateSW:

  • 您要预缓存文件。
  • 您具有简单的运行时配置需求(例如,该配置允许您定义路由和策略)。

何时不使用generateSW:

  • 您要使用其他Service Worker功能(即Web Push)。
  • 您要导入其他脚本或添加其他逻辑。

TIP

请在Workbox网站上检查此模式下可用的workboxOptions。

InjectManifest

何时使用InjectManifest:

  • 您想更好地控制service worker。
  • 您要预缓存文件。
  • 您在路由方面有更复杂的需求。
  • 您想将service worker与其他APIS(例如Web Push)一起使用。

何时不使用InjectManifest:

  • 您想要将service worker添加到站点的最简单方法。

提示

  • 如果要使用此模式,则必须自己编写service worker(/src-pwa/custom-service-worker.[js|ts])文件。
  • 请在Workbox网站上检查此模式下可用的workboxOptions。

下面的片段是自定义服务工作者(service worker)的默认代码(/src-pwa/custom-service-worker.[js|ts]),它模仿了generateSW模式的行为:

/*
 * This file (which will be your service worker)
 * is picked up by the build system ONLY if
 * quasar.config.js > 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 fallback to index.html
// Production SSR fallback to offline.html (except for dev)
if (process.env.MODE !== 'ssr' || process.env.PROD) {
  registerRoute(
    new NavigationRoute(
      createHandlerBoundToURL(process.env.PWA_FALLBACK_HTML),
      { denylist: [/sw\.js$/, /workbox-(.)*\.js$/] }
    )
  )
}

配置Manifest文件

Manifest文件位于/src-pwa/manifest.json。你可以自由编辑它。

如果你需要在构建时动态地改变它,你可以通过编辑/quasar.config.js来实现:

// quasar.config.js
pwa: {
  extendManifestJson (json) {
    // tamper with the json
  }
}

在深入研究之前,请阅读Manifest配置

WARNING

请注意,您不需要编辑您的index.html文件(由/index.html生成)来链接到Manifest文件。 Quasar CLI负责为您嵌入正确的东西。

TIP

如果您的PWA在基本身份验证后面或需要Authorization标头,则将quasar.config.js > pwa > useCredentialsForManifestTag设置为true,以在manifest.json的meta标签中包含crossorigin =“ use-credentials”

PWA清单

更多信息:PWA清单

WARNING

不要在开发版本上运行Lighthouse,因为在此阶段,代码有意不进行优化,并包含嵌入式源映射(以及许多其他内容)。 有关详细信息,请参阅这些文档的测试和审核 部分。

自动加载和更新

对于那些不想在服务工作者更新时手动重新加载页面,**并使用默认的generateSW工作箱模式的用户,Quasar CLI已经将工作箱配置为一次性激活。如果您需要禁用这种行为:

// quasar.config.js
pwa: {
  extendGenerateSWOptions (cfg) {
    cfg.skipWaiting = false
    cfg.clientsClaim = false
  }
}

文件名哈希怪癖
@quasar/app-vite v1.1+

由于Rollup构建资源的方式(通过Vite),当你改变任何脚本源文件(.js)时,也会改变(几乎)所有.js文件的哈希部分(例如:assets/index.454d87bd.js中的`454d87bd’)。所有资产的修订号将在你的服务工作者文件中被改变,这意味着当PWA更新时,它将重新下载你的所有资源。这是对带宽的浪费,而且更新PWA的时间也很长。

默认情况下,Vite构建的所有文件名都有哈希部分。然而,如果你希望你的文件名不包含哈希部分,你需要编辑quasar.config.js文件:

// quasar.config.js
build: {
  useFilenameHashes: false // true by default
}

当文件名哈希被禁用时,明智的做法是也要确保你的网络服务器有相应的缓存设置(尽可能低),以确保向不能使用PWA功能的客户提供一致的资源。