📦 plugin-pwa
道格龙(Docusaurus)插件,基于 Workbox 实现 PWA 支持。该插件仅在生产环境构建时生成 Service Worker,让你的文档站点完全符合 PWA 标准,支持离线访问和安装。
安装
- npm
- Yarn
- pnpm
- Bun
npm install --save @docusaurus/plugin-pwa
yarn add @docusaurus/plugin-pwa
pnpm add @docusaurus/plugin-pwa
bun 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', // 你的 PWA manifest
},
{
tagName: 'meta',
name: 'theme-color',
content: 'rgb(37, 194, 160)',
},
],
},
],
],
};
渐进式 Web 应用(PWA)
仅安装 service worker 并不足以让你的应用成为 PWA。你还需要至少包含 Web App Manifest 并在 <head>
中添加正确的标签(详见 Options > pwaHead)。
部署后,你可以使用 Lighthouse 对站点进行 PWA 检查。
更完整的 PWA 要求可参考 PWA 检查清单。
应用安装支持
如果浏览器支持,你可以将道格龙站点安装为应用。
应用安装需要 HTTPS 协议和有效的 manifest 文件。
离线模式(预缓存)
我们通过 service worker 预缓存机制,让用户可以离线浏览道格龙站点。
workbox-precaching 页面解释了其原理:
service worker 的一个特性是在安装时将一组文件保存到缓存中。这通常被称为"预缓存",因为你在 service worker 启用前就缓存了内容。
这样做的主要原因是开发者可以控制缓存,决定文件何时、如何缓存,以及无需访问网络即可将其提供给浏览器,从而实现离线 Web 应用。
Workbox 简化了预缓存的 API,并确保高效下载资源,大大减轻了开发负担。
默认情况下,站点被安装为应用时会启用离线模式。详见 offlineModeActivationStrategies
选项。
站点被预缓存后,service worker 会为后续访问提供缓存内容。当有新构建和新 service worker 部署时,新 worker 会开始安装并进入等待状态。此时会弹出刷新提示,建议用户刷新页面以获取新内容。在用户清除应用缓存或点击弹窗的 reload
按钮前,service worker 会继续提供旧内容。
离线模式/预缓存需要提前下载站点所有静态资源,可能会消耗不必要的带宽。并不建议所有站点都启用。
选项
debug
- 类型:
boolean
- 默认值:
false
开启调试模式:
- 输出 Workbox 日志
- 输出额外的道格龙日志
- 输出未优化的 SW 文件
- 输出 source map
offlineModeActivationStrategies
- 类型:
('appInstalled' | 'mobile' | 'saveData'| 'queryString' | 'always')[]
- 默认值:
['appInstalled', 'queryString', 'standalone']
用于激活离线模式的策略:
appInstalled
:用户已将站点安装为应用时激活(并非 100% 可靠)standalone
:以独立应用模式运行时激活(PWA 安装后常见)queryString
:URL 查询参数包含offlineMode=true
时激活(便于 PWA 调试)mobile
:移动端用户(宽度 <= 996px
)激活saveData
:用户设置了navigator.connection.saveData === true
时激活always
:对所有用户激活
请谨慎使用:部分用户可能不喜欢被强制进入离线模式。
无法可靠检测页面是否以 PWA 方式渲染。
appinstalled
事件已被 规范移除,navigator.getInstalledRelatedApps()
API 仅在新版 Chrome 支持,且需在 manifest 中声明 related_applications
。
standalone
策略 是激活离线模式的较好兜底方案(至少在已安装应用时有效)。
injectManifestConfig
Workbox 选项,传递给 workbox.injectManifest()
。你可以通过它控制哪些资源会被预缓存、可离线访问。
- 类型:
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 标准。以下为常用标签示例:
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'
在道格龙应用启动前注册 service worker。默认的 registerSW.js
已满足简单注册需求。
传递 false
可完全禁用注册。
Manifest 示例
道格龙站点 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
组件,提示用户刷新。你可以 swizzle 该组件,自定义 UI。该组件会接收 onReload
回调 props,点击"刷新"按钮时应调用此回调,通知 service worker 安装新 worker 并刷新页面。
默认主题已实现刷新弹窗,使用 Infima Alerts。
你的组件可以返回 null
,但不推荐这样做,否则用户无法获取最新内容。