plugin-pwa

优质
小牛编辑
130浏览
2023-12-01

该插件利用 Workbox 为网站添加对 PWA 的支持。该插件仅在针对生产环境构建时生成 Service Worker,并允许你创建一个 完全兼容 PWA 的文档站点,以提供对离线和安装到浏览器的支持。

安装

  • npm
  • Yarn
npm install --save @docusaurus/plugin-pwa
yarn add @docusaurus/plugin-pwa

配置

./static/manifest.json 文件中创建 PWA 清单

针对 PWA 对 docusaurus.config.js 文件做最少的修改,例如:

docusaurus.config.js
module.exports = {
  plugins: [
    [
      '@docusaurus/plugin-pwa',
      {
        debug: true,
        offlineModeActivationStrategies: [
          'appInstalled',
          'standalone',
          'queryString',
        ],
        pwaHead: [
          {
            tagName: 'link',
            rel: 'icon',
            href: '/img/docusaurus.png',
          },
          {
            tagName: 'link',
            rel: 'manifest',
            href: '/manifest.json', // your PWA manifest
          },
          {
            tagName: 'meta',
            name: 'theme-color',
            content: 'rgb(37, 194, 160)',
          },
        ],
      },
    ],
  ],
};

渐进式 Web 应用程序(PWA)

在浏览器端安装一个 service worker 并不足以让你的应用成为一个 PWA。你至少需要包含一个 Web App 清单 文件,并且在 <head> (Options > pwaHead) 中添加适当的标签。

部署之后,你可以使用 Lighthouse 对你的网站进行审核。

有关让网站成为一个 PWA 所需的详尽的 For a more exhaustive list of what it takes for your site to be a PWA, refer to the PWA Checklist

App installation support

如果你的浏览器支持,则应该可以将一个 Docusaurus 站点当作一个应用程序来安装。

pwa_install.gif

note

App installation requires the https protocol and a valid manifest.

离线模式(预先缓存)

We enable users to browse a Docusaurus site offline, by using service-worker precaching.

什么是预先缓存?

One feature of service workers is the ability to save a set of files to the cache when the service worker is installing. This is often referred to as "precaching", since you are caching content ahead of the service worker being used.

The main reason for doing this is that it gives developers control over the cache, meaning they can determine when and how long a file is cached as well as serve it to the browser without going to the network, meaning it can be used to create web apps that work offline.

Workbox takes a lot of the heavy lifting out of precaching by simplifying the API and ensuring assets are downloaded efficiently.

By default, offline mode is enabled when the site is installed as an app. See the offlineModeActivationStrategies option for details.

After the site has been precached, the service worker will serve cached responses for later visits. When a new build is deployed along with a new service worker, the new one will begin installing and eventually move to a waiting state. During this waiting state, a reload popup will show and ask the user to reload the page for new content. Until the user either clears the application cache or clicks the reload button on the popup, the service worker will continue serving the old content.

caution

Offline mode / precaching requires downloading all the static assets of the site ahead of time, and can consume unnecessary bandwidth. It may not be a good idea to activate it for all kind of sites.

参数列表

debug

  • 类型: boolean
  • 默认值: false

Turn debug mode on:

  • Workbox logs
  • Additional Docusaurus logs
  • Unoptimized SW file output
  • Source maps

offlineModeActivationStrategies

  • 类型: Array<'appInstalled' | 'mobile' | 'saveData'| 'queryString' | 'always'>
  • 默认值: ['appInstalled','queryString','standalone']

Strategies used to turn the offline mode on:

  • appInstalled: activates for users having installed the site as an app (not 100% reliable)
  • standalone: activates for users running the app as standalone (often the case once a PWA is installed)
  • queryString: activates if queryString contains offlineMode=true (convenient for PWA debugging)
  • mobile: activates for mobile users (width <= 940px)
  • saveData: activates for users with navigator.connection.saveData === true
  • always: activates for all users
caution

Use this carefully: some users may not like to be forced to use the offline mode.

danger

It is not possible to detect if an as a PWA in a very reliable way.

The appinstalled event has been removed from the specification, and the navigator.getInstalledRelatedApps() API is only supported in recent Chrome versions and require related_applications declared in the manifest.

The standalone strategy is a nice fallback to activate the offline mode (at least when running the installed app).

injectManifestConfig

Workbox options to pass to workbox.injectManifest(). This gives you control over which assets will be precached, and be available offline.

  • 类型: InjectManifestOptions
  • 默认值: {}
docusaurus.config.js
module.exports = {
  plugins: [
    [
      '@docusaurus/plugin-pwa',
      {
        injectManifestConfig: {
          manifestTransforms: [
            //...
          ],
          modifyURLPrefix: {
            //...
          },
          // We already add regular static assets (html, images...) to be available offline
          // You can add more files according to your needs
          globPatterns: ['**/*.{pdf,docx,xlsx}'],
          // ...
        },
      },
    ],
  ],
};

reloadPopup

  • 类型: string | false
  • 默认值: '@theme/PwaReloadPopup'

Module path to reload popup component. This popup is rendered when a new service worker is waiting to be installed, and we suggest a reload to the user.

Passing false will disable the popup, but this is not recommended: users won't have a way to get up-to-date content.

A custom component can be used, as long as it accepts onReload as a prop. The onReload callback should be called when the reload button is clicked. This will tell the service worker to install the waiting service worker and reload the page.

interface PwaReloadPopupProps {
  onReload: () => void;
}

The default theme includes an implementation for the reload popup and uses Infima Alerts.

pwa_reload.gif

pwaHead

  • 类型: Array<{ tagName: string } & Record<string,string>>
  • 默认值: []

Array of objects containing tagName and key-value pairs for attributes to inject into the <head> tag. Technically you can inject any head tag through this, but it's ideally used for tags to make your site PWA compliant. Here's a list of tag to make your app fully compliant:

module.exports = {
  plugins: [
    [
      '@docusaurus/plugin-pwa',
      {
        pwaHead: [
          {
            tagName: 'link',
            rel: 'icon',
            href: '/img/docusaurus.png',
          },
          {
            tagName: 'link',
            rel: 'manifest',
            href: '/manifest.json',
          },
          {
            tagName: 'meta',
            name: 'theme-color',
            content: 'rgb(37, 194, 160)',
          },
          {
            tagName: 'meta',
            name: 'apple-mobile-web-app-capable',
            content: 'yes',
          },
          {
            tagName: 'meta',
            name: 'apple-mobile-web-app-status-bar-style',
            content: '#000',
          },
          {
            tagName: 'link',
            rel: 'apple-touch-icon',
            href: '/img/docusaurus.png',
          },
          {
            tagName: 'link',
            rel: 'mask-icon',
            href: '/img/docusaurus.svg',
            color: 'rgb(37, 194, 160)',
          },
          {
            tagName: 'meta',
            name: 'msapplication-TileImage',
            content: '/img/docusaurus.png',
          },
          {
            tagName: 'meta',
            name: 'msapplication-TileColor',
            content: '#000',
          },
        ],
      },
    ],
  ],
};

swCustom

  • 类型: string | undefined
  • 默认值: undefined

Useful for additional Workbox rules. You can do whatever a service worker can do here, and use the full power of workbox libraries. The code is transpiled, so you can use modern ES6+ syntax here.

For example, to cache files from external routes:

import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
// default fn export receiving some useful params
export default function swCustom(params) {
  const {
    debug, // :boolean
    offlineMode, // :boolean
  } = params;
  // Cache responses from external resources
  registerRoute((context) => {
    return [
      /graph\.facebook\.com\/.*\/picture/,
      /netlify\.com\/img/,
      /avatars1\.githubusercontent/,
    ].some((regex) => context.url.href.match(regex));
  }, new StaleWhileRevalidate());
}

The module should have a default function export, and receives some params.

swRegister

  • 类型: string | false
  • 默认值: 'docusaurus-plugin-pwa/src/registerSW.js'

Adds an entry before the Docusaurus app so that registration can happen before the app runs. The default registerSW.js file is enough for simple registration.

Passing false will disable registration entirely.

Manifest example

The Docusaurus site manifest can serve as an inspiration:

{
  "name": "Docusaurus 中文网",
  "short_name": "Docusaurus",
  "theme_color": "#2196f3",
  "background_color": "#424242",
  "display": "standalone",
  "scope": "./",
  "start_url": "./index.html",
  "related_applications": [
    {
      "platform": "webapp",
      "url": "https://www.docusaurus.cn/manifest.json"
    }
  ],
  "icons": [
    {
      "src": "img/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "img/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "img/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "img/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "img/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "img/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "img/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "img/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}