📦 plugin-pwa
使用 Workbox 来添加 PWA 支持的 Docusaurus 插件。 此插件将仅在生产构建中生成 Service Worker,让你创建支持离线模式和应用安装的 PWA 文档站点。
安装流程
- npm
- Yarn
- pnpm
npm install --save @docusaurus/plugin-pwa
yarn add @docusaurus/plugin-pwa
pnpm add @docusaurus/plugin-pwa
配置
在 ./static/manifest.json
处新建 PWA Manifest。
在 docusaurus.config.js
里简单配置 PWA,如下所示:
export default {
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)',
},
],
},
],
],
};
渐进式网页应用
安装 Service Worker 还不足以让你的应用成为渐进式 Web 应用 (PWA)。 你至少需要先添加一个 Web App Manifest,并在 <head>
里填写正确的标签(选项 > pwaHead)。
部署后,你可以用 Lighthouse 来检查网站的性能。
PWA 检查单详尽地列出了一个网站要成为 PWA 的条件。
应用安装支持
如果你的浏览器支持,就可以把 Docusaurus 当作应用安装了。
安装应用需要 HTTPS 协议及有效的 Manifest。
离线模式(预缓存)
我们通过 Service Worker 预缓存的方式支持用户离线访问 Docusaurus 站点。
The workbox-precaching page explains the idea:
Service Worker 的功能之一是在安装过程中把一些文件保存到缓存。 因为你在 Service Worker 工作之前就开始缓存内容了,所以这一般被称为「预缓存」。
使用此功能的主要原因是让开发者控制缓存,即决定何时缓存、缓存多长时间、以及在离线时向浏览器提供内容,也就是创建离线网页应用。
Workbox 为你完成了预缓存期间的诸多复杂工作,简化了 API 的同时还确保能高效率地下载资源。
默认情况下,当网站作为应用程序安装时,将默认启用离线模式。 请参阅 offlineModeActivationStrategies
选项以了解详情。
网站预缓存完毕后,Service Worker 将为之后的请求提供缓存好的响应。 当新构建的版本随着新的 Service Worker 一起部署后,新版本会自动开始安装并变成等待状态。 在此期间,网站会弹出刷新弹窗,提示用户刷新页面查看新内容。 除非用户清除应用程序缓存,或者点击弹窗的 刷新
按钮,否则 Service Worker 将一直提供旧内容。
离线模式/预缓存需要提前下载网站上的所有静态资源,可能会导致不必要的流量消耗。 并非每个站点都有必要开启此选项。
选项
debug
- 类型:
boolean
- 默认值:
false
打开调试模式,包含以下功能:
- Workbox 日志
- 额外的 Docusaurus 日志
- 未优化的 SW 文件输出
- Source Map
offlineModeActivationStrategies
- 类型:
('appInstalled' | 'mobile' | 'saveData'| 'queryString' | 'always')[]
- 默认值:
['appInstalled', 'queryString', 'standalone']
开启离线模式的策略有:
appInstalled
:在用户安装网站为应用程序时启用(并非百分百可靠)standalone
:在用户以独立模式运行应用程序时启用(通常是紧随安装 PWA 之后)queryString
:在 queryString 包含offlineMode=true
时启用(通常用于 PWA 调试)mobile
: activates for mobile users (width <= 996px
)saveData
:为navigator.connection.saveData === true
的用户启用always
:为所有用户启用
用这个功能要小心:某些用户可能不喜欢强制使用离线模式。
It is not possible to detect if a page is rendered as a PWA in a reliable manner.
技术规范中已经移除了 appinstalled
事件,而且只有新版本的 Chrome 支持 navigator.getInstalledRelatedApps()
API,此时还需要在 Manifest 中声明 related_applications
。
standalone
策略是启用离线模式的不错的备选方案(至少在运行已安装应用时)。
injectManifestConfig
传递给 workbox.injectManifest()
的 Workbox 选项。 这个选项允许你筛选需要预缓存,且可离线浏览的资源。
- 类型:
InjectManifestOptions
- 默认值:
{}
export default {
plugins: [
[
'@docusaurus/plugin-pwa',
{
injectManifestConfig: {
manifestTransforms: [
//...
],
modifyURLPrefix: {
//...
},
// 我们已经包括了常见的静态资源(HTML、图像等)
// 你可以在此处按需添加文件
globPatterns: ['**/*.{pdf,docx,xlsx}'],
// ...
},
},
],
],
};
pwaHead
- 类型:
({ tagName: string; [attributeName: string]: string })[]
- 默认值:
[]
一个对象数组,每个对象包含了 tagName
和属性键值对,会被注入 <head>
标签。 理论上说,你可以通过这个选项注入任何 head 标签,但最好注入那些能让你的网站兼容 PWA 的标签。 下面列出了能让你的应用程序完全兼容 PWA 的标签:
export default {
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
适用于额外的 Workbox 规则。 你可以在此处编写任何想让 Service Worker 做的事,让 Workbox 物尽其用。 代码会被自动转译,所以你可以在这里用最新的 ES6+ 语法。
举个例子,假设我们要从外部路径缓存文件:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
// 导出接收有用参数的默认函数
export default function swCustom(params) {
const {
debug, // :boolean
offlineMode, // :boolean
} = params;
// 从外部资源缓存响应
registerRoute((context) => {
return [
/graph\.facebook\.com\/.*\/picture/,
/netlify\.com\/img/,
/avatars1\.githubusercontent/,
].some((regex) => context.url.href.match(regex));
}, new StaleWhileRevalidate());
}
这个模块应 default
导出一个函数,函数会接受一个对象参数。
swRegister
- 类型:
string | false
- 默认值:
'docusaurus-plugin-pwa/src/registerSW.js'
在 Docusaurus 应用前添加入口,在应用运行前触发注册。 默认的 registerSW.js
文件足够进行简单注册了。
设置为 false
会完全关闭注册功能。
Manifest 示例
Docusaurus 网站的 Manifest 可以给你一些启发:
{
"name": "Docusaurus",
"short_name": "Docusaurus",
"theme_color": "#2196f3",
"background_color": "#424242",
"display": "standalone",
"scope": "./",
"start_url": "./index.html",
"related_applications": [
{
"platform": "webapp",
"url": "https://docusaurus.io/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"
}
]
}
个性化刷新提示框
在新的 Service Worker 等待安装,我们向用户提示刷新的时候,会渲染 @theme/PwaReloadPopup
组件。 You can swizzle this component and implement your own UI. 它会接受一个 onReload
回调作为参数,这个回调应该在 刷新
按钮被点击后调用。 这会告诉 Service Worker 安装等待中的新版 Service Worker,并刷新页面。
默认主题包含了一个刷新弹窗的默认实现,使用了 Infima Alerts。
你的组件也可以返回 null
,但我们不推荐这么做:这样用户就没办法获取最新内容了。