vite打包后css中背景图等资源404,根本原因是css内url()相对路径未被正确重写,需从base配置生效性、资源是否被vite接管、构建产物真实性三方面交叉验证。

你的Vite项目打包后CSS里背景图、字体或图片全变成404,控制台显示请求路径指向/assets/xxx但实际文件在/dist/img/或/dist/assets/xxx,根本不是路径拼错,而是Vite没重写CSS中url()里的相对路径——这问题必须从base配置是否生效、资源是否被Vite接管、构建产物是否真实反映配置三方面交叉验证。
确认base配置是否真正参与了build流程
打开vite.config.ts(或.js),检查base字段是否写在defineConfig顶层对象内,且未被环境变量覆盖:export default defineConfig({ base: '/my-app/' });若使用VITE_BASE环境变量,确保构建命令中明确传入--mode production且.vite-env.d.ts或.env.production中定义了VITE_BASE=/my-app/。
运行npm run build后,立刻打开dist/index.html,用Ctrl+F搜索<script src href staging> <p>这一步不能跳过。很多开发者改完配置就跑build,却没验证HTML里是否真加了前缀。</script>
检查CSS中url()是否属于Vite可接管范围
方法一:资源必须放在src/assets目录下,且CSS中url()为静态字面量路径
✅ 正确写法:background: url('./logo.png');
❌ 错误写法:background: url('../public/logo.png')、background: url('/logo.png')、background: url('./'+iconName)。
方法二:第三方CSS必须通过import引入,不能直接link或@import
比如Bootstrap的CSS,必须在main.ts或入口JS中写import 'bootstrap/dist/css/bootstrap.min.css';如果只在index.html里,Vite不会扫描重写其中的url(../fonts/),这些路径会原样拷贝进dist,必然404。
【关键前提】只有src目录下的CSS文件(含.vue单文件组件style块)+ import引入的第三方CSS,Vite才会解析并重写url()内的相对路径;public目录下任何CSS或直接引用的CDN CSS,全部绕过构建链路。
验证构建产物中CSS内部路径是否被重写
第一步:进入dist目录,用文本编辑器打开任意一个生成的CSS文件(如assets/index.xxxxx.css);
第二步:搜索url(,观察所有匹配项:
• 若看到url(/my-app/assets/logo.xxxx.png)或url(./assets/logo.xxxx.png),说明base生效且资源被正确哈希重写;
• 若仍看到url(../img/bg.jpg)或url(../../src/assets/icon.svg),说明该CSS未被Vite处理——它可能是直接复制进dist的裸CSS,或来自public目录,或用了@import但未走import链路。
第三步:对比该CSS文件在src中的原始位置和dist中的输出位置,计算相对路径偏移是否与Vite默认提取逻辑一致(Vite默认把CSS提取到assets/目录下,所以原始url(../img/x.png)在dist中应变为url(../../img/x.png),但前提是Vite接管了该文件)。
注意:SCSS/Less编译后的CSS若含变量拼接路径(如url('#{$path}/icon.png')),Vite完全无法静态分析,这类路径永远不会被重写。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











