今天,帮朋友定位了一个问题,简单描述下是:vue项目,vue-router用的是browser history,设置二级路由,二级页面刷新不生效。
解决办法:webpack配置中publicPath设置为/ 而不是./
具体现象描述:
比如两个页面:/post、/post/detail
post中比如放置一个table,每一行都是一个具体的post,点进去进入detail页面。从table中点入detail页面是好的。
但是这时候刷新一下就白屏了。
这个现象说明,devServer的apiFallback没问题,vue-router的路由配置也是生效的。因为从table点进去,走的SPA逻辑,能正常切换这就是不是vue-router的问题了。
刷新之后,看了下network,请求的js文件404了:
(截图中/cluster等同于举例子的post)
上网查了下,发现原来是这个问题:
一句话结论:vue-router使用broswer history模式的时候,webpack配置中publicPath设置为/
原因是:
publicPath设置的值,在打包生成的文件中,会作为请求js的地址的前缀。
<!-- 这是build之后的html文件中的js引用 -->
<!-- 假设filename 设置的是:/static/js/[name].[contenthash:8].js -->
<script src="`${publicPath} + ${output.filename}`" ></script>
<!-- publicPath: ./ -->
<script src="./static/js/app.xx.js" ></script>
<!-- publicPath: / -->
<script src="/static/js/app.xx.js" ></script>
所以./和/就自然是查找资源的相对路径和绝对路径区别了。
而vue-router的broswer history中(参考: ),以/开头的一级路由会被视作根路径(/post、或者/cluster),那么当publicPath设置为./的时候其实是相对根路径/post,再去寻找./static/xxx.js,但是server中没有/post,所以404。
当设置publicPath为/之后,则直接无视一级路由这个所谓的根路径,直接从server的根路径开始查找,所以自然可以找到资源。
所以可以简单记忆:如果vue-router使用broswer history模式,配置webpack的publicPath为/