工作上有推播需求,因此我先整理 PWA 的基礎配置與實際案例,作為團隊未來導入時的參考。本篇以 Vite 專案為例,介紹如何建立可安裝的 PWA;推播流程可延伸閱讀推播通知篇。
什麼是 PWA
PWA 是使用現代 Web API 建立的網頁應用程式。基礎組成包含:
- Web App Manifest:提供名稱、圖示、啟動方式與顏色等應用程式資訊
- Service Worker:攔截請求、管理快取,並支援離線體驗、推播與背景同步
vite-plugin-pwa 能協助 Vite 專案產生 manifest、Service Worker,並將註冊程式注入頁面入口。若只需要基本離線能力,通常不需要從零撰寫 Service Worker。
使用教學
Step 1 安裝套件
npm install -D vite-plugin-pwaStep 2 在 Vite 設定加入插件
以下為基本可用的設定。registerType: 'autoUpdate' 會在新版 Service Worker 可用時自動更新;若你的產品需要讓使用者自行決定更新時機,可改用 prompt 並實作更新提示介面。
import { defineConfig } from 'vite';
import { VitePWA } from 'vite-plugin-pwa';
export default defineConfig({
plugins: [
VitePWA({
registerType: 'autoUpdate',
manifest: {
name: '台南不動產',
short_name: '台南不動產',
start_url: '/tnrentalweb/',
scope: '/tnrentalweb/',
display: 'standalone',
lang: 'zh-Hant-TW',
background_color: '#ffffff',
theme_color: '#1f6feb',
icons: [
{
src: '/tnrentalweb/pwa-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/tnrentalweb/pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
},
],
},
}),
],
});這個最小設定已能產生 Web App Manifest、Service Worker,並在瀏覽器中註冊 Service Worker。
Step 3 建置並檢查產物
npm run build建置完成後,檢查輸出資料夾是否有 manifest 與 Service Worker 相關檔案。也可透過 Chrome DevTools 的 Application 面板確認 Manifest、Service Workers 與 Cache Storage 是否正常。
基本設定說明
Manifest
manifest 是安裝體驗的核心設定。以下欄位通常最先需要確認:
| 欄位 | 用途 |
|---|---|
name | 安裝畫面與系統中顯示的完整應用程式名稱 |
short_name | 空間有限時使用的短名稱 |
start_url | 從主畫面啟動時開啟的網址 |
scope | 此 PWA 可控制的網址範圍 |
display | standalone 可讓開啟體驗接近原生 App |
theme_color | 瀏覽器或系統介面的主題色 |
background_color | App 載入期間的背景色 |
icons | 安裝圖示,至少提供 192 與 512 像素版本 |
網站部署在子路徑時,base、start_url、scope 與圖示路徑要使用一致的前綴。例如專案放在 /tnrentalweb/ 下,以上路徑都應包含該前綴,避免 Service Worker 控制範圍不正確。
Service Worker 策略
strategies 決定插件如何產生 Service Worker:
generateSW:預設策略,由插件透過 Workbox 自動建立 Service Worker。沒有特殊離線流程時適合先使用它。injectManifest:自行維護 Service Worker 檔案,並由插件注入預快取清單。需要推播、特殊快取策略或自訂事件時較適合。
import { defineConfig } from 'vite';
import { VitePWA } from 'vite-plugin-pwa';
export default defineConfig({
plugins: [
VitePWA({
strategies: 'injectManifest',
srcDir: 'src',
filename: 'sw.ts',
manifest: {
name: '台南不動產',
short_name: '台南不動產',
start_url: '/tnrentalweb/',
display: 'standalone',
},
}),
],
});injectManifest 不代表所有需求都必須自己處理。先評估是否真的需要客製快取邏輯,避免讓 Service Worker 變成難以測試的額外維護成本。
Service Worker 註冊與更新
injectRegister 用來控制插件怎麼把註冊碼放入頁面:
| 設定 | 用途 |
|---|---|
auto | 預設行為。未自行使用虛擬註冊器時會自動注入註冊碼 |
inline | 將簡短註冊程式直接內嵌到 HTML |
script | 以外部 script 註冊 |
script-defer | 以 defer script 註冊,避免阻塞 HTML 解析 |
false | 不自動註冊,改由應用程式自行處理 |
registerType 常見值如下:
prompt:發現新版時通知使用者,讓使用者決定何時重新載入autoUpdate:新版可用時自動更新
內容頻繁更新、表單編輯或多分頁操作的產品,通常較適合 prompt,避免使用者在輸入過程中被重新載入。內容閱讀型網站則可評估 autoUpdate。
開發環境測試
Service Worker 預設主要在 production build 中產生。若要在開發時一併檢查 manifest 與產生的 Service Worker,可開啟 devOptions.enabled:
VitePWA({
registerType: 'autoUpdate',
devOptions: {
enabled: true,
},
});開發環境的快取狀態容易干擾除錯。遇到更新後仍看到舊檔案時,可在 DevTools 的 Application 面板取消註冊 Service Worker,再清除對應的 Cache Storage 後重新整理。
預快取與檔案大小
generateSW 會使用 Workbox 建立預快取清單。當產物中有大檔案,可能會出現類似以下錯誤:
Configure "workbox.maximumFileSizeToCacheInBytes" to change the limit: the default value is 2 MiB.
Assets exceeding the limit:這表示某些檔案超出 Workbox 的預設預快取大小限制。先確認該資源是否真的需要離線可用;影片、大型圖片或地圖資料通常不適合一律加入預快取。
如果確認該資源必須預快取,才提高對應策略的限制:
VitePWA({
strategies: 'injectManifest',
injectManifest: {
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
},
});提高限制會增加首次安裝與更新時需要下載的資料量,因此應搭配實際網路環境與資源用途評估。
常見問題
為什麼安裝選項沒有出現
先確認網站使用 HTTPS。Service Worker 需要安全環境,開發時的 localhost 是例外。接著檢查 manifest 是否可讀取、圖示路徑是否成功載入,以及 Service Worker 是否已成功註冊。
為什麼更新後還是看到舊畫面
Service Worker 有自己的生命週期,新的版本不一定會立刻接管目前頁面。先檢查更新策略,再確認瀏覽器是否仍保留舊快取。開發期間可先取消註冊 Service Worker 與清除 Cache Storage 來排除快取影響。
什麼時候需要 injectManifest
當你需要自訂離線頁面、依 API 類型設定不同快取策略、處理推播事件或背景同步時,才建議改用 injectManifest。如果只有安裝與基本離線快取需求,generateSW 的設定較少,也更容易維護。