如何配置Vite-PWA-plugin实现Web Push通知功能?
问题
我原本有一个支持Web Push通知的sw.js文件,但安装Vite-PWA-plugin后,默认配置没法集成原有通知功能。请问怎么配置vite.config.ts,让生成的serviceWorker.js包含原有的Web Push实现?
解决方案
1. 抽离自定义Web Push代码
把原有sw.js里的Web Push逻辑单独存到一个新文件,比如resources/js/custom-sw.js,内容如下:
// Web Push 通知处理逻辑 self.addEventListener('push', function (e) { if (!( self.Notification && self.Notification.permission === 'granted' )) { // 不支持通知或未授权,直接返回 return; } if (e.data) { let message = e.data.json(); e.waitUntil(self.registration.showNotification(message.title, { body: message.body, icon: message.icon, actions: message.actions })); } }); // 通知点击跳转逻辑 self.addEventListener('notificationclick', function(event) { event.notification.close(); if (event.action === 'farm') clients.openWindow("/farm"); else if (event.action === 'home') clients.openWindow("/"); else if (event.action === 'training') clients.openWindow("/mining-training"); else if (event.action === 'dns') clients.openWindow("/shops/dns"); else if (event.action === 'ali') clients.openWindow("/shops/aliexpress"); else clients.openWindow("/farm"); }, false);
2. 修改Vite-PWA配置
在vite.config.ts的VitePWA插件配置里,给workbox添加swSrc字段,指向刚才创建的自定义文件。修改后的完整配置如下:
import {defineConfig} from 'vite'; import laravel from 'laravel-vite-plugin'; import react from '@vitejs/plugin-react'; import path from 'path'; import {VitePWA} from "vite-plugin-pwa"; const manifest = { "theme_color" : "#2B2B2B", "background_color": "#2B2B2B", "display" : "standalone", "scope" : "/", "start_url" : "/farm", "name" : "ColorBit", "short_name" : "Mining", "description" : "...", "icons" : [ { "src" : "icons/icon-192x192.png", "sizes": "192x192", "type" : "image/png" }, // ... 其他图标省略 { "src" : "icons/maskable_icon.png", "sizes" : "682x682", "type" : "image/png", "purpose": "maskable" } ] }; const getCache = ({ name, pattern, strategy = "CacheFirst" }: any) => ({ urlPattern: pattern, handler: strategy, options: { cacheName: name, expiration: { maxEntries: 500, maxAgeSeconds: 60 * 60 * 24 * 60 // 2个月 }, cacheableResponse: { statuses: [0, 200] } } }); export default defineConfig({ plugins: [ laravel({ input : [ 'resources/js/app.tsx',], refresh: true, }), react({ fastRefresh: false }), VitePWA({ registerType: 'autoUpdate', outDir : path.resolve(__dirname, 'public'), manifest : manifest, manifestFilename: 'manifest.webmanifest', injectRegister : false, workbox : { globDirectory: path.resolve(__dirname, 'public'), globPatterns : [ '{build,images,sounds,icons}/**/*.{js,css,html,ico,png,jpg,mp4,svg}' ], navigateFallback: null, swDest : 'public/serviceWorker.js', // 新增:指向自定义Web Push逻辑文件 swSrc: path.resolve(__dirname, 'resources/js/custom-sw.js'), runtimeCaching: [ getCache({ pattern: /^https:\/\/fonts\.googleapis\.com\/.*/i, name: "google-fonts-cache", }), getCache({ pattern: /^https:\/\/fonts\.gstatic\.com\/.*/i, name: "gstatic-fonts-cache" }), getCache({ pattern: /.*storage.*/, name: "dynamic-images-cache", }), ] } }) ], resolve: { alias : { '@' : path.resolve(__dirname, 'resources/js'), '@hooks' : path.resolve(__dirname, 'resources/js/hooks'), '@assets' : path.resolve(__dirname, 'resources/js/assets/'), '@components': path.resolve(__dirname, 'resources/js/components') }, extensions: ['.js', '.ts', '.tsx', '.jsx'], }, });
原理说明
配置swSrc后,Workbox会自动把你自定义的Web Push代码和它生成的缓存管理逻辑(install、activate、fetch事件)合并到最终的serviceWorker.js里,既保留了PWA的缓存功能,又能正常处理Web Push通知。
如果你的自定义代码里已有install/activate/fetch事件,Workbox会自动处理事件监听的优先级,不会出现冲突。
内容的提问来源于stack exchange,提问作者Влад Рогов
相关产品推荐
相关产品推荐

