部署到EKS的PWA刷新后白屏,报Uncaught SyntaxError错误求助
问题背景
PWA应用部署到EKS生产环境后,部分用户反馈刷新页面出现白屏,需再次刷新才能正常使用,但本地测试无此问题。Chrome开发者工具捕获到以下错误:
Uncaught SyntaxError: Unexpected token "<" 2.9345ebBe.chunk.js:1 Uncaught SyntaxError: Unexpected token "<" main.fa04b6.chunk.js:1
推测是请求JS文件时返回了HTML("<"来自<!doctype html>),但用户清除浏览器缓存后问题仍未解决。
核心原因分析
结合提供的package.json及报错信息,问题根源通常涉及以下几点:
- 静态资源缓存策略冲突:入口文件
index.html被强缓存,导致用户加载旧的HTML,而旧HTML引用的JS哈希文件已被新版本替换,请求时404后被路由 fallback 到HTML。 - react-scripts版本过旧:当前使用
react-scripts@2.1.3,该版本存在静态资源哈希生成、PWA Service Worker缓存的已知缺陷。 - EKS Ingress路由配置缺失:未正确配置路由 fallback,导致刷新非根路径时返回HTML而非对应静态资源。
- Service Worker缓存残留:PWA的Service Worker缓存了旧的错误响应,即使清除浏览器缓存也无法清除Service Worker缓存。
具体解决方案
1. 修正Ingress/Nginx的缓存与路由配置
确保静态资源(带哈希的JS/CSS)设置强缓存,而index.html设置不缓存,同时配置路由 fallback 避免404返回HTML:
# 主路由配置,处理单页应用路由 location / { try_files $uri $uri/ /index.html; # 禁止缓存index.html add_header Cache-Control "no-cache, no-store, must-revalidate"; expires 0; } # 静态资源强缓存(带哈希的文件不会变更) location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires 1y; add_header Cache-Control "public, immutable"; }
在EKS中,需将此配置添加到Ingress的nginx.ingress.kubernetes.io/configuration-snippet注解中,或者修改Pod内的Nginx配置文件。
2. 升级react-scripts到稳定版本
旧版本react-scripts@2.1.3的构建系统存在资源哈希生成不严谨、Service Worker逻辑不完善的问题,升级到最新稳定版:
npm install react-scripts@latest --save
升级后重新执行npm run build:production,确保构建出的静态资源哈希正确,且Service Worker的缓存逻辑更可靠。
3. 强制Service Worker更新
添加Service Worker更新监听逻辑,确保新版本部署后用户能及时获取更新,避免旧缓存残留:
在项目的index.js中加入以下代码:
if ('serviceWorker' in navigator) { window.addEventListener('load', () => { navigator.serviceWorker.register('/service-worker.js') .then(registration => { // 监听Service Worker更新 registration.addEventListener('updatefound', () => { const newWorker = registration.installing; newWorker.addEventListener('statechange', () => { if (newWorker.state === 'installed' && navigator.serviceWorker.controller) { // 提示用户刷新以应用更新 if (confirm('应用已更新,请点击确定刷新页面')) { window.location.reload(); } } }); }); }) .catch(error => { console.error('Service Worker注册失败:', error); }); }); }
另外,每次部署新版本时,可以修改service-worker.js中的cacheName(如添加版本号),强制旧缓存失效。
4. 验证EKS部署的资源完整性
检查Pod内的静态资源是否与本地构建一致,确保没有缺失或路径错误:
# 替换为你的Pod名称 kubectl exec -it <your-pod-name> -- ls /usr/share/nginx/html/static/js
确认输出的JS文件名与本地构建的哈希文件名一致,避免部署过程中出现资源丢失。
内容的提问来源于stack exchange,提问作者thanhtran3k

