這個外掛程式由 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 庫是實現此目的的好朋友。 麻省理工學院