React CRA中BrowserRouter不同basename下manifest.json请求差异排查
问题原因分析
UI1和UI2的行为差异根源在于manifest.json的引用路径类型以及CRA的PUBLIC_URL配置:
- UI2部署在子路径
/admin,构建时必然配置了PUBLIC_URL=/admin,最终打包后的index.html中,manifest的引用会被替换为绝对路径/admin/manifest.json。这种绝对路径不受当前页面路由深度影响,无论访问/admin/a/b/c还是/admin,都会直接请求根域下的/admin/manifest.json。 - UI1部署在根路径,默认未配置
PUBLIC_URL,打包后manifest的引用是相对路径manifest.json。当页面路由到深层路径/a/b/c时,浏览器会以当前URL的路径层级(/a/b/c)为基准,将相对路径解析为/a/b/manifest.json(取当前路径的父级目录),导致请求错误。
修复方案
有两种简单的方式修正UI1的请求路径:
1. 设置PUBLIC_URL环境变量构建
在UI1的构建命令中指定PUBLIC_URL=/,确保打包后生成绝对路径的资源引用:
# npm PUBLIC_URL=/ npm run build # yarn PUBLIC_URL=/ yarn build # pnpm PUBLIC_URL=/ pnpm build
构建完成后,index.html中的manifest引用会变为<link rel="manifest" href="/manifest.json" />,无论路由深度如何,都会正确请求根域下的/manifest.json。
2. 直接修改public/index.html中的引用路径
打开UI1的public/index.html,将manifest的href直接改为绝对路径:
<!-- 原默认引用 --> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <!-- 修改为绝对路径 --> <link rel="manifest" href="/manifest.json" />
这样无需额外配置环境变量,打包后直接生成绝对路径引用,效果和第一种方法一致。
额外验证:Nginx配置确保SPA路由正确
另外要确认Nginx配置已正确处理SPA的深层路由,确保访问/a/b/c时能返回根路径的index.html,示例配置如下:
server { listen 80; server_name domain.com; root /path/to/ui1/build; location / { try_files $uri $uri/ /index.html; } # 如果UI2部署在同一服务器,可添加如下location location /admin { alias /path/to/ui2/build; try_files $uri $uri/ /admin/index.html; } }
内容的提问来源于stack exchange,提问作者Ploppz
相关产品推荐
相关产品推荐

