GCP App Engine部署代码分割React应用出现Loading chunk * failed错误如何解决
GAE 部署React代码分割项目保留旧chunk文件解决方案
核心思路
App Engine 每次部署新版本时默认只会上传当前构建目录下的文件,旧版本chunk文件缺失才会导致404报错,我们只需要在部署时把所有历史chunk文件都纳入当前部署包,就能实现旧文件保留的需求。
具体实现步骤
1. 确认打包哈希规则
CRA 默认已经开启了内容哈希命名规则,打包生成的chunk文件名格式类似2.87f5b34a.chunk.js,哈希值仅随文件内容变化,无需额外修改webpack配置即可直接使用。
2. 搭建历史静态资源池
我们需要一个独立的存储空间保存所有历史版本的chunk文件,推荐用Google Cloud Storage实现:
- 新建一个专用于存储历史前端静态资源的GCS存储桶
- 每次本地执行
npm run build生成新版本构建产物后,先将本次build目录下static/js、static/css文件夹中的所有chunk文件上传到GCS存储桶中归档 - 每次执行部署命令前,先把GCS存储桶中所有历史chunk文件下载到本地当前build目录对应的
static/js、static/css路径下,再执行gcloud app deploy命令
3. 优化app.yaml配置
在现有配置基础上补充缓存规则,避免静态资源被意外清理,同时保证首页能拉取到最新版本:
service: frontend runtime: nodejs14 env: standard instance_class: F1 handlers: - url: /(.*\..+)$ static_files: build/\1 upload: build/(.*\..+)$ expiration: "365d" # 带哈希的静态资源缓存一年,不需要重复请求 - url: /.* static_files: build/index.html upload: build/index.html expiration: "0s" # html不缓存,保证用户新开页面时拿到最新版本资源
4. 前端兜底错误处理
作为补充方案,可以在前端添加chunk加载错误捕获逻辑,极端情况下也不会给用户抛出报错:
// 封装懒加载逻辑,捕获chunk加载失败的情况 const lazyLoad = (importFunc) => { return React.lazy(() => importFunc().catch(() => { // 加载失败时自动刷新页面拉取最新版本资源 window.location.reload(); return Promise.reject(new Error('资源更新,请稍候')); }) ); }; // 路由懒加载时用封装后的方法替代原生React.lazy const ProfilePage = lazyLoad(() => import('./pages/Profile'));
验证方法
两次部署不同版本的代码,第一次部署后打开首页保持页面不刷新,第二次部署完成后点击跳转其他页面,没有出现Loading chunk * failed报错即为配置生效。
内容的提问来源于stack exchange,提问作者Charles-olivier Demers
相关产品推荐
相关产品推荐

