这个插件由 workbox 和其他好东西提供支持。
在这里分享您精彩的 PWA 项目
特征
next-i18next
示例blitz.config.js
)next.config.js
将experimental.modern
设置为true
时预缓存.module.js
注意 1 -
next-pwa
版本 2.0.0+ 只能与next.js
9.1+ 一起使用,并且静态文件只能通过public
目录提供。这将使事情变得更简单。注意 2 - 如果您在构建过程中遇到错误
TypeError: Cannot read property **'javascript' of undefined**
,请考虑在next.config.js
中升级到 webpack5 。
如果您对
next.js
或react.js
完全陌生,您可能需要首先查看学习 next.js 或 next.js 文档。然后从 next.js 存储库中的简单示例或渐进式 Web 应用程序示例开始。
yarn add next-pwa
更新或创建next.config.js
const withPWA = require ( 'next-pwa' ) ( {
dest : 'public'
} )
module . exports = withPWA ( {
// next.js config
} )
运行next build
后,这将在您的public
中生成两个文件: workbox-*.js
和sw.js
,这两个文件将自动静态提供。
如果您使用的是 Next.js 版本 9 或更高版本,请跳过以下选项并继续执行步骤 2。
如果您使用的 Next.js 版本早于 9,则需要在继续步骤 2 之前选择下面的一个选项。
将文件复制到静态文件托管服务器,以便可以从以下路径访问它们: https://yourdomain.com/sw.js
和https://yourdomain.com/workbox-*.js
。
一个示例是使用 Firebase 托管服务静态托管这些文件。您可以使用部署工作流程中的脚本自动执行复制步骤。
出于安全原因,您必须直接从您的域托管这些文件。如果使用重定向传递内容,浏览器将拒绝运行 Service Worker。
当收到 HTTP 请求时,测试是否请求了这些文件,然后返回这些静态文件。
示例server.js
const { createServer } = require ( 'http' )
const { join } = require ( 'path' )
const { parse } = require ( 'url' )
const next = require ( 'next' )
const app = next ( { dev : process . env . NODE_ENV !== 'production' } )
const handle = app . getRequestHandler ( )
app . prepare ( ) . then ( ( ) => {
createServer ( ( req , res ) => {
const parsedUrl = parse ( req . url , true )
const { pathname } = parsedUrl
if ( pathname === '/sw.js' || / ^/(workbox|worker|fallback)-w+.js$ / . test ( pathname ) ) {
const filePath = join ( __dirname , '.next' , pathname )
app . serveStatic ( req , res , filePath )
} else {
handle ( req , res , parsedUrl )
}
} ) . listen ( 3000 , ( ) => {
console . log ( `> Ready on http://localhost: ${ 3000 } ` )
} )
} )
以下设置与
next-pwa
插件无关,您可能已经设置过它们。如果没有,请继续设置它们。
在public
文件夹中创建一个manifest.json
文件:
{
"name" : " PWA App " ,
"short_name" : " App " ,
"icons" : [
{
"src" : " /icons/android-chrome-192x192.png " ,
"sizes" : " 192x192 " ,
"type" : " image/png " ,
"purpose" : " any maskable "
},
{
"src" : " /icons/android-chrome-384x384.png " ,
"sizes" : " 384x384 " ,
"type" : " image/png "
},
{
"src" : " /icons/icon-512x512.png " ,
"sizes" : " 512x512 " ,
"type" : " image/png "
}
],
"theme_color" : " #FFFFFF " ,
"background_color" : " #FFFFFF " ,
"start_url" : " / " ,
"display" : " standalone " ,
"orientation" : " portrait "
}
将以下内容添加到_document.jsx
或_app.tsx
的中:
< meta name =" application-name " content =" PWA App " />
< meta name =" apple-mobile-web-app-capable " content =" yes " />
< meta name =" apple-mobile-web-app-status-bar-style " content =" default " />
< meta name =" apple-mobile-web-app-title " content =" PWA App " />
< meta name =" description " content =" Best PWA App in the world " />
< meta name =" format-detection " content =" telephone=no " />
< meta name =" mobile-web-app-capable " content =" yes " />
< meta name =" msapplication-config " content =" /icons/browserconfig.xml " />
< meta name =" msapplication-TileColor " content =" #2B5797 " />
< meta name =" msapplication-tap-highlight " content =" no " />
< meta name =" theme-color " content =" #000000 " />
< link rel =" apple-touch-icon " href =" /icons/touch-icon-iphone.png " />
< link rel =" apple-touch-icon " sizes =" 152x152 " href =" /icons/touch-icon-ipad.png " />
< link rel =" apple-touch-icon " sizes =" 180x180 " href =" /icons/touch-icon-iphone-retina.png " />
< link rel =" apple-touch-icon " sizes =" 167x167 " href =" /icons/touch-icon-ipad-retina.png " />
< link rel =" icon " type =" image/png " sizes =" 32x32 " href =" /icons/favicon-32x32.png " />
< link rel =" icon " type =" image/png " sizes =" 16x16 " href =" /icons/favicon-16x16.png " />
< link rel =" manifest " href =" /manifest.json " />
< link rel =" mask-icon " href =" /icons/safari-pinned-tab.svg " color =" #5bbad5 " />
< link rel =" shortcut icon " href =" /favicon.ico " />
< link rel =" stylesheet " href =" https://fonts.googleapis.com/css?family=Roboto:300,400,500 " />
< meta name =" twitter:card " content =" summary " />
< meta name =" twitter:url " content =" https://yourdomain.com " />
< meta name =" twitter:title " content =" PWA App " />
< meta name =" twitter:description " content =" Best PWA App in the world " />
< meta name =" twitter:image " content =" https://yourdomain.com/icons/android-chrome-192x192.png " />
< meta name =" twitter:creator " content =" @DavidWShadow " />
< meta property =" og:type " content =" website " />
< meta property =" og:title " content =" PWA App " />
< meta property =" og:description " content =" Best PWA App in the world " />
< meta property =" og:site_name " content =" PWA App " />
< meta property =" og:url " content =" https://yourdomain.com " />
< meta property =" og:image " content =" https://yourdomain.com/icons/apple-touch-icon.png " />
提示:如果需要,请将
viewport
元标记放入_app.js
而不是_document.js
中。
< meta
name = 'viewport'
content = 'minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no, user-scalable=no, viewport-fit=cover'
/ >
当从缓存和网络获取失败时,脱机后备非常有用,可以提供预缓存的资源,而不是从浏览器中显示错误。
首先,只需添加一个/_offline
页面,例如pages/_offline.js
或pages/_offline.jsx
或pages/_offline.ts
或pages/_offline.tsx
。那么一切就都准备好了!当用户离线时,所有未缓存的页面将回退到“/_offline”。
使用此示例查看其实际效果
next-pwa
帮助您在第一次加载时预缓存这些资源,然后将handlerDidError
插件的后备处理程序注入到所有runtimeCaching
配置中,以便在获取失败时提供预缓存的资源。
您还可以在runtimeCaching配置条目中设置precacheFallback.fallbackURL
来实现类似的功能。不同的是,上面的方法是基于资源类型的,这个方法是基于匹配的url模式。如果在 runtimeCaching 配置条目中设置此配置,则将针对此特定 url 模式自动禁用基于资源类型的回退以避免冲突。
您可以使用一些选项来自定义此插件的行为,方法是在next.config.js
的下一个配置中添加pwa
对象:
const withPWA = require ( 'next-pwa' ) ( {
dest : 'public'
// disable: process.env.NODE_ENV === 'development',
// register: true,
// scope: '/app',
// sw: 'service-worker.js',
//...
} )
module . exports = withPWA ( {
// next.js config
} )
false
disable: false
,这样它就会在dev
和prod
中生成serviceworkerdisable: true
以完全禁用PWAdev
中调试 Service Worker,可以设置disable: process.env.NODE_ENV === 'development'
true
false
,这可以在根应用程序的componentDidMount
中完成。您可以考虑 register.js 作为示例。next.config.js
中的basePath
或/
/app
这样/app
下的路径将是 PWA,而其他路径则不是/sw.js
public
文件夹中的文件被预缓存。['!noprecache/**/*']
- 这意味着默认行为将预缓存public
文件夹中的所有文件,但/public/noprecache
文件夹中的文件除外。您可以简单地将文件放入该文件夹中,而不是在没有配置的情况下预先缓存它们。['!img/super-large-image.jpg', '!fonts/not-used-fonts.otf']
.next/static
(或您的自定义构建)文件夹中预缓存的文件[]
[/chunks/images/.*$/]
- 不要在.next/static/chunks/images
下预缓存文件(强烈建议将此与next-optimized-images
插件一起使用)true
true
cacheStartUrl
设置为true
时有效/login
,建议设置此重定向网址以获得最佳用户体验。undefined
dynamicStartUrlRedirect
设置为true
时有效/_offline
页面,例如pages/_offline.js
就可以了,无需配置object
fallbacks.document
- 文档(页面)的后备路由,如果您创建了该页面,则默认为/_offline
fallbacks.image
- 图像的后备路由,默认为无fallbacks.audio
- 音频的后备路由,默认为无fallbacks.video
- 视频的后备路由,默认为无fallbacks.font
- 字体的后备路由,默认为无next/link
的页面之间导航时启用额外的路由缓存。查看此示例以了解有关实现此功能的原因的一些背景信息。false
""
- 即默认值没有前缀/subdomain
(如果应用托管在example.com/subdomain
location.reload()
来刷新应用程序。true
next-pwa
查找自定义工作线程实现以添加到工作箱生成的服务工作线程的目录。有关更多信息,请查看自定义工作线程示例。worker
next-pwa
使用workbox-webpack-plugin
,也可以放入pwa
对象中的其他选项可以在GenerateSW和InjectManifest的文档中找到。如果指定swSrc
,将使用InjectManifest
插件,否则将使用GenerateSW
生成 Service Worker。
next-pwa
使用默认运行时cache.js
您很有可能想要自定义自己的运行时缓存规则。请随意复制默认的cache.js
文件并根据需要自定义规则。不要忘记将配置注入next.config.js
中的pwa
配置中。
这是有关如何编写运行时缓存配置的文档,包括后台同步和广播更新功能等等!
postMessage
时,使用像{command: 'doSomething', message: ''}
对象这样的约定。这样在侦听器上,它可以使用if...else...
执行多个不同的任务。clean application cache
以减少一些片状错误。runtimeCaching
中指定它,例如options.cacheableResponse.statuses=[200,302]
。sw.js
文件以弄清楚到底发生了什么。next.config.js
的pwa
部分中指定选项mode: 'production'
强制next-pwa
生成工作框生产版本。尽管next-pwa
在开发期间自动生成工作框开发构建(通过运行next
),并在生产期间自动生成工作框生产构建(通过运行next build
和next start
)。即使在 Web 应用程序的开发过程中,您可能仍然希望强制它进行生产构建,原因如下:self.__WB_DISABLE_DEV_LOGS = true
放入您的worker/index.js
中(如果没有,则创建一个)。userAgent
字符串来确定用户是否使用 Safari/iOS/MacOS 或其他平台,ua-parser-js 库是实现此目的的好朋友。 麻省理工学院