结论:
publicPath:"/"解决,不能设置相对路径。
环境
可能相关的环境:
- vue-cli5.0
- vue3
- vue-router4
可能的原因
- publicPath:“./”
- 路由history
- 路由base
现象
图片异常
img
部分图片被转换成了base64
可以出来- style里
url("~@/assets/img/xxx.webp")
可以出来 img
部分图片使用路径也加载不出来- el-image引用的图片报错,也加载不出来
跳转异常
- 路由跳转失败
- 对应有一个
304xxx.js
的文件加载失败
排查
- 以上失败原因都是路径错误,加载路径变成了
http://127.0.0.1:8080/plat/static/img
,正确的应该是在根目录http://127.0.0.1:8080/static/img
,但我路由也没设置base
。本来应该在根目录下的,这个路径就成了在plat文件夹
下,那肯定是加载不到。 - 看
index.html
中<%= BASE_URL %>favicon.ico
变成了favicon.ico
,也就是说<%= BASE_URL %>
是空的,本来期待值应该是./
,其他引入的js也是static/js/
,肯定是publicPath出问题。 - 尝试了
publicPath: '././'
这种配置,<%= BASE_URL %>
还是空的,打包的js文件是正确了./static/js/xxx
,但图片还是错的。app.js里路径是a.p+"static/img/xxx"
,这个肯定是跟<%= BASE_URL %>
是一致的。 - 尝试
publicPath: '/'
,ok了
如果正式环境不是把资源放到cdn
,直接不设置publicPath
就没问题,默认就是/
,我这个是设置了生产环境,测试环境也配置了。
vue-cli4.5的时候不知道没用上这个场景还是没问题,我懒得回退,之前都是生产环境用./
。
vuecli官网-静态资源这块讲的听明白的。
- 图片不要放在
public
下,不会被webpack
处理,把js静态文件
放到public
下。 <%= BASE_URL %>
是vue-cli3
以后使用的,js静态文件
放到public
下的,前面的引用路径可以用这个,也可以直接写./
or/
。- 当前
./
都被取代成空了,所以不管是怎么变化,最后<%= BASE_URL %>
得到的是空的。 - 图片资源
8kb
以下转base64
,更大的图片还是引用路径,即小于 8KiB 的资源内联,以减少 HTTP 请求的数量,可以通过 chainWebpack 调整内联文件的大小限制。 - el-image中存在动态加载不更新问题,静态加载没问题。使用require后面更改后路径不会被更新,得用变量或computed。模块在第一次加载后会运行一次,然后将运行结果缓存到内存里,后面都是直接读取缓存的值。所以编译时直接转字符串,后面不会改变了。
vuecli的URL 转换规则
- 如果 URL 是一个绝对路径 (例如 /images/foo.png),它将会被保留不变。
- 如果 URL 以 . 开头,它会作为一个相对模块请求被解释且基于你的文件系统中的目录结构进行解析。
- 如果 URL 以 ~ 开头,其后的任何内容都会作为一个模块请求被解析。
- 如果 URL 以 @ 开头,它也会作为一个模块请求被解析。它的用处在于 Vue CLI 默认会设置一个指向 /src 的别名 @。(仅作用于模版中)