React路由切换时JS Bundle加载失败404问题求助
你遇到的核心问题是Webpack生成的资源引用路径变成了相对当前路由的路径,而非基于你设置的basename根路径。当导航到/content-manager/foo/edit时,浏览器会错误地从/content-manager/foo/下去请求JS bundle,而正确的资源根路径应该是/content-manager/。
问题根源
你已经在React Router中配置了basename: '/content-manager',但Webpack的output.publicPath设置为空字符串。Webpack默认会生成相对路径的资源引用,这就导致嵌套路由层级下,资源请求路径被错误拼接。
解决方案
1. 修正Webpack的publicPath配置
publicPath是Webpack指定所有输出资源根URL的关键配置,必须设置为和React Routerbasename一致的绝对路径,且末尾需加斜杠(避免路径拼接异常)。
修改webpack.dev.js的output配置:
output: { filename: '[name].[hash].js', publicPath: '/content-manager/', // 与React Router的basename保持一致 },
同时在webpack.common.js中添加统一的output配置(确保生产环境也生效):
module.exports = { // ...其他原有配置 output: { filename: '[name].[hash].js', publicPath: '/content-manager/', }, // ...其他原有配置 };
2. 优化devServer的historyApiFallback(可选但推荐)
为了确保所有路由请求都能正确回退到index.html,同时适配你的basename,可以给historyApiFallback添加重写规则:
devServer: { // ...其他原有配置 historyApiFallback: { rewrites: [ // 匹配所有以/content-manager开头的请求,指向正确的index.html { from: /^\/content-manager\/.*$/, to: '/content-manager/index.html' } ] }, // ...其他原有配置 },
3. 验证资源注入结果
修改完publicPath后,HtmlWebpackPlugin会自动使用这个根路径生成资源引用。打包后的index.html中,JS引用会变成类似:
<script src="/content-manager/main.fdb34ff55bc02a8cd347.js"></script>
这样无论当前处于哪个路由层级,浏览器都会从正确的根路径请求资源。
为什么这样有效?
设置publicPath: '/content-manager/'后,Webpack会给所有生成的资源加上这个绝对路径前缀,确保资源请求始终指向http://app.local/content-manager/,而非相对于当前页面的路径。这和React Router的basename形成了统一的根路径,彻底解决了嵌套路由导致的资源路径错误。
内容的提问来源于stack exchange,提问作者Harry Blue

