Vue-CLI项目Sass中引用public目录图片报模块未找到错误如何解决
这个报错的原因很明确:webpack默认会解析CSS/Sass中url()传入的路径,会把/开头的路径识别为src目录下的模块资源去检索,自然找不到存放在public目录下的文件,下面是几个可直接落地的方案:
方案1:使用内置BASE_URL变量(官方推荐,适配所有部署场景)
Vue CLI 自带全局的process.env.BASE_URL变量,对应你在vue.config.js里配置的publicPath(默认值为/)。在Sass里写路径时前面加~标识,告诉webpack走模块解析逻辑,拼接资源路径即可:
// 常规SCSS写法 background-image: url('~' + process.env.BASE_URL + 'media/image.png'); // 如果你的SCSS支持模板字符串语法,也可以简化写法 // background-image: url(`~${process.env.BASE_URL}media/image.png`);
这个写法是兼容性最好的,不管项目部署在域名根目录还是二级子目录,路径都能正常解析,不会出现静态资源404问题。
方案2:路径前补双斜杠(仅适合根路径部署场景)
如果确定项目永远部署在域名根路径,不会放到二级子目录下,可以直接在原有路径前多加一个斜杠,让webpack跳过这个路径的模块解析,直接按站点根路径读取资源:
background-image: url('//media/image.png');
这个写法本地开发完全正常,但是如果后续项目部署到类似https://xxx.com/vue-project/的子路径下,图片会默认去https://xxx.com/media/目录下查找,直接报404,只适合固定部署在根路径的项目使用。
方案3:修改webpack配置跳过根路径解析(特殊场景使用)
如果不想改动现有路径写法,可以修改项目根目录的vue.config.js配置,让css-loader跳过/开头的路径解析:
module.exports = { chainWebpack: config => { config.module .rule('scss') .oneOf('vue') .use('css-loader') .tap(options => { options.url = url => !url.startsWith('/') return options }) } }
改完配置重启开发服务,原来写的url('/media/image.png')就能正常生效,但是这个方案同样不兼容子路径部署,没有特殊需求不推荐使用。
避坑提醒:不要写相对路径跳转到public目录引用资源,比如
url('../../public/media/image.png'),这种写法会让webpack把public下的图片重复打包到dist的img目录并重命名,既产生冗余资源,也不符合你统一管理public目录图片的规划。
内容的提问来源于stack exchange,提问作者laurisstepanovs

