基于域名配置Workbox多Manifest及解决ServiceWorker注册报错
多子域名Firebase托管+Workbox Service Worker注册失败解决方案
核心原因
ServiceWorker script evaluation failed本质是SW脚本执行时出错,大概率是Workbox生成的SW里硬编码了和域名绑定的资源路径(比如特定manifest文件),或者SW作用域与子域名不匹配。
修复步骤
1. 让SW动态适配子域名的manifest
Webpack的InjectManifest如果配置不当,会把固定域名的manifest(比如manifest.A.json)硬编码进SW的预缓存清单。需要改成动态获取当前域名对应的manifest:
- 如果你用了自定义SW模板(
swSrc),修改缓存逻辑:// 自定义sw.js模板 const subdomainSuffix = self.location.hostname.split('.')[1]; // 从app.B.com提取B const manifestUrl = `/manifest.${subdomainSuffix}.json`; workbox.precaching.precacheAndRoute([ // 其他预缓存资源 { url: manifestUrl, revision: 'auto' }, ]); - 若未用自定义模板,确保Webpack配置里没有把特定manifest文件加入预缓存,完全通过动态逻辑处理。
2. 修正SW注册的作用域
错误里显示作用域是https://B.com/,但你的应用在app.B.com下,作用域不匹配会导致注册失败。修改SW注册代码:
// React中的SW注册逻辑 if ('serviceWorker' in navigator) { window.addEventListener('load', async () => { try { await navigator.serviceWorker.register('/service-worker.js', { scope: './', // 强制作用域为当前子域名根路径 }); } catch (err) { console.error('SW注册失败:', err); } }); }
同时检查firebase.json,不要设置全局SW的固定作用域:
{ "hosting": { "public": "build", "rewrites": [{"source": "**", "function": "handleDomain"}], "serviceWorker": { "globPatterns": ["**/*.{js,css,html,png}"] } } }
3. 确保Firebase函数不篡改SW请求
你的云函数只需要处理index.html的manifest替换,不要拦截service-worker.js请求,让它原样返回:
exports.handleDomain = functions.https.onRequest(async (req, res) => { const domain = req.hostname; // 直接返回SW脚本,不做处理 if (req.path === '/service-worker.js') { return res.sendFile(path.join(__dirname, '../build/service-worker.js')); } // 处理index.html的manifest替换逻辑 const indexHtml = fs.readFileSync(path.join(__dirname, '../build/index.html'), 'utf8'); const manifestFile = domain === 'app.A.com' ? 'manifest.A.json' : 'manifest.B.json'; const modifiedHtml = indexHtml.replace('manifest.json', manifestFile); res.set('Content-Type', 'text/html'); res.send(modifiedHtml); });
4. 清除缓存重新部署
浏览器会缓存旧SW,必须:
- 在浏览器DevTools > Application > Service Workers里注销旧SW
- 重新打包部署:
npm run build firebase deploy --only functions,hosting
验证
- 访问
app.B.com,查看Console确认无SW注册错误 - 检查Application > Service Workers,确认SW作用域为
https://app.B.com/ - 在Network面板查看SW是否请求了正确的
manifest.B.json
内容的提问来源于stack exchange,提问作者Crocsx
相关产品推荐
相关产品推荐

