RsBuild与Module Federation v2配置React嵌套路由静态资源异常问题
当publicPath设为"auto"时,RsBuild/Rspack会基于当前页面的URL路径动态推断静态资源的基础路径,具体逻辑是:
- 首次从根路径(
/)进入应用时,入口脚本从根目录加载(如http://localhost:3001/main.js),此时运行时推断的publicPath为"/",所有静态资源都从根路径请求,单级路由跳转(如/some)时资源已加载完成,不会出现问题。 - 刷新嵌套路由页面(如
/some/route1)时,浏览器直接请求该路径,服务器返回根目录的index.html。此时页面URL的路径层级为/some/route1/,相对路径的资源引用会被解析为/some/route1/xxx.js,但实际静态资源存放在根目录下,导致资源加载失败、应用崩溃。
而将publicPath改为"/"时,所有资源强制从根路径请求,remote自身路由刷新恢复正常,但host应用会尝试从自身根路径加载remote资源,而非remote的服务器地址,因此无法定位资源。
要兼顾remote自身路由正常和host能正确加载remote资源,可采用以下两种方案:
方案1:设置固定远程publicPath
将remote的publicPath设置为其完整服务器地址(开发环境为"http://localhost:3001/",生产环境替换为部署域名),同时确保Module Federation配置正确:
修改remote的rsbuild.config.js:
export default defineConfig({ output: { publicPath: "http://localhost:3001/", // 开发环境固定地址 }, moduleFederation: { name: "remote", filename: "remoteEntry.js", exposes: { "./NestedRoutes": "./src/routes/NestedRoutes", }, }, });
该方案配置简单,但需根据环境切换publicPath值,适合开发阶段快速验证。
方案2:使用运行时动态publicPath
通过RsBuild的runtimePublicPath配置,让publicPath在运行时根据入口脚本的实际加载路径自动推断,同时确保服务器配置正确的SPA fallback规则:
修改remote的rsbuild.config.js:
export default defineConfig({ output: { publicPath: "auto", runtimePublicPath: true, // 启用运行时动态publicPath }, moduleFederation: { name: "remote", filename: "remoteEntry.js", exposes: { "./NestedRoutes": "./src/routes/NestedRoutes", }, }, });
同时确保remote的服务器配置SPA fallback规则(所有路由请求返回根目录的index.html):
- 开发环境使用RsBuild内置devServer时,默认已开启该规则;
- 生产环境部署(如Nginx)时,添加配置:
location / { try_files $uri $uri/ /index.html; }
该方案无需硬编码服务器地址,适配多环境部署,能同时满足remote自身路由和host加载资源的需求。
确保remote的Module Federation配置中filename和exposes路径正确,host的remote配置指向remote的remoteEntry.js地址:
// host的rsbuild.config.js moduleFederation: { name: "host", remotes: { remote: "remote@http://localhost:3001/remoteEntry.js", }, },
内容的提问来源于stack exchange,提问作者Petros

