部署Create React App后页面白屏,刷新恢复的问题求助
根据你描述的报错Uncaught SyntaxError: Unexpected token '<',这个问题的核心原因是浏览器请求的JS文件实际上收到了HTML内容(你的index.html),通常是旧缓存页面引用了已不存在的静态资源,或者资源路径解析错误导致Nginx返回了index.html而非对应的JS文件。结合你的Docker+Nginx部署环境,我给出以下针对性解决方案:
1. 配置Nginx缓存策略,避免index.html被缓存
你的Nginx配置目前没有设置缓存控制规则,浏览器可能会缓存旧的index.html。当你部署新版本后,旧的index.html引用的是带有旧哈希值的JS文件,而服务器上已经不存在这些旧文件了,Nginx的try_files规则会把这个不存在的请求重定向到index.html,导致浏览器把HTML当成JS解析,出现语法错误。
修改你的Nginx配置,添加缓存控制:
server { listen 80; server_name localhost; # 对根路径的index.html设置强制不缓存 location = / { root /usr/share/nginx/html; index index.html index.htm; add_header Cache-Control "no-cache, no-store, must-revalidate"; add_header Pragma "no-cache"; add_header Expires 0; } # 处理其他静态资源,设置长期缓存(CRA静态资源带哈希,不会出现版本冲突) location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; # 对哈希命名的静态资源设置长期缓存 if ($request_uri ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$) { expires 1y; add_header Cache-Control "public, immutable"; } } location = /50x.html { root /usr/share/nginx/html; } } # 保留原有gzip配置 gzip on; gzip_http_version 1.0; gzip_comp_level 5; gzip_min_length 256; gzip_proxied any; gzip_vary on; gzip_types application/atom+xml application/javascript application/json application/rss+xml application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component;
2. 确认Create React App的homepage配置正确
确保你的package.json中homepage字段设置为./,这样CRA会生成相对路径的静态资源引用,避免在非根路径部署时出现资源路径错误:
{ "name": "frontend", "version": "1.5.0", "private": true, "homepage": "./", // 确保该字段存在且值为./ "dependencies": { // ... 你的依赖项 } }
修改后重新执行npm run build,检查build后的index.html中JS/CSS的引用是否以./开头(比如<script src="./static/js/main.xxx.js"></script>),而非绝对路径。
3. 验证Docker部署的文件路径
确认你的Dockerfile中build产物的复制路径正确:
COPY --from=build /usr/src/app/build /usr/share/nginx/html
这条命令会把CRA build后的所有文件(包括static文件夹和index.html)复制到Nginx的默认静态资源目录,确保Nginx能正确找到这些文件。
测试验证
部署修改后的配置后,你可以:
- 打开浏览器开发者工具(F12),切换到Network标签,勾选Disable cache,首次访问页面查看JS文件的返回内容是否正确。
- 测试普通用户的访问流程:清除浏览器缓存后首次访问,确认不再出现白屏。
内容的提问来源于stack exchange,提问作者FivEawE

