Skip to page content
Quasar CLI with Vite - @quasar/app-vite

SSG 配合 PWA 客户端接管

警告!Beta 阶段

Quasar SSG 模式目前处于 “beta” 阶段。根据社区反馈,API 在未来可能会有所变动,因此每次升级 “@quasar/app-vite” 时请留意 release notes。

SSG 可以在首次访问时提供预渲染的 HTML,然后安装 service worker 以支持离线访问和后续导航。以下选项在 /quasar.config 的 ssg 配置节中生成:

/quasar.config file

ssg: {
  /**
   * 是否由 PWA 接管客户端,否则为 SPA。
   * @default false
   */
  pwa?: boolean;

  /**
   * 使用 SSG+PWA 时,这是 PWA 客户端回退的
   * index html 文件名。仅用于生产环境。
   *
   * 确保命名不会与 SSG 生成的 html 文件冲突。
   * 它可以有意地与 `clientSideRenderingHtmlFilename` 相同,
   * 以复用同一个应用外壳。
   *
   * @default ssr.pwaOfflineHtmlFilename(如已配置),否则 'offline.html'
   */
  pwaOfflineHtmlFilename?: string;

  /**
   * 扩展/配置 Workbox GenerateSW 选项
   * 指定将应用在 `pwa > extendPWAGenerateSWOptions()` 之上的
   * Workbox 选项。
   *
   * https://developer.chrome.com/docs/workbox/the-ways-of-workbox/
   *
   * 可以是异步的。可以直接修改 "config" 参数,
   * 或返回一个新对象与默认配置合并。
   */
  extendSSGGenerateSWOptions?: (
    config: GenerateSWOptions
  ) => void | GenerateSWOptions | Promise<void | GenerateSWOptions>;

  /**
   * 扩展/配置 Workbox InjectManifest 选项
   * 指定将应用在 `pwa > extendPWAInjectManifestOptions()` 之上的
   * Workbox 选项。
   *
   * https://developer.chrome.com/docs/workbox/the-ways-of-workbox/
   *
   * 可以是异步的。可以直接修改 "config" 参数,
   * 或返回一个新对象与默认配置合并。
   */
  extendSSGInjectManifestOptions?: (
    config: InjectManifestOptions
  ) => void | InjectManifestOptions | Promise<void | InjectManifestOptions>;
}

设置 pwa: true 以启用 PWA 接管。在启用此选项时添加 SSG 模式,也会在需要时安装 PWA 模式。通过常规的 pwa 配置 来配置 manifest、图标、Workbox 模式和 service worker。

生产构建会生成正常的 SSG 页面、PWA 资源和默认位于 dist/ssg/offline.html 的应用外壳。Service worker 使用该外壳作为导航回退。不要将其命名为 index.html,也不要与生成的 SSG 页面同名。

导航是如何被处理的

新客户端的首次访问由你的静态托管服务处理,这也是 service worker 被安装的时机。从那以后,service worker 会接管导航,处理顺序如下:

  1. 如果请求的 URL 匹配预缓存(precache)中某个预渲染页面,就从缓存提供该页面,其服务端渲染的标记和序列化状态完好无损,与首次访问完全一样
  2. 否则(一个未被预渲染的路由,或者一个不对应任何生成文件的 URL),由离线外壳来响应,页面在客户端渲染

第二种情况是客户端渲染页面:没有服务端渲染的标记,没有序列化状态,因此在那里不会发生 store 水合,preFetch 特性 钩子会在客户端运行。

无论哪种情况,导航都不会去访问网络,因此重新部署的页面只有在 service worker 更新其预缓存后才会到达用户,而不会更早。

自定义 Workbox

SSG 特定的扩展钩子在对应的 PWA 钩子之后运行:

/quasar.config file

ssg: {
  pwa: true,

  extendSSGGenerateSWOptions (workboxConfig) {
    workboxConfig.navigateFallbackDenylist.push(
      /^\/api\//,
      /^\/admin\//
    )
  }
}

对 Workbox GenerateSW 使用 extendSSGGenerateSWOptions,对 InjectManifest 使用 extendSSGInjectManifestOptions。

请记住,预缓存路由的注册早于导航回退,也早于任何 runtimeCaching 路由,因此预渲染页面始终由预缓存来响应。若想让导航走网络,首先就得(通过 globIgnores)把生成的页面排除在预缓存之外。

WARNING

部署整个输出目录,包括 service worker、manifest、图标、Workbox 文件、生成的页面和离线外壳。Service worker 在生产环境中还需要 HTTPS(localhost 除外)。

有关 PWA 的更多信息,请前往 PWA 简介 并阅读整个 PWA 指南章节。