根本原因是CSS中url()以文件自身位置为基准解析,构建后CSS被移至dist/assets/而内部相对路径未重写,导致解析错位;仅src目录下CSS或import引入的第三方CSS会被Vite重写url(),public下CSS及非字面量路径均不处理。

开发时能加载,构建后CSS里url()全404
根本不是路径“写错了”,而是 CSS 中 url() 的解析基准在构建前后发生了位移:开发时以源文件位置为起点(src/css/style.css → ../assets/bg.png 能命中),构建后 CSS 被提取到 dist/assets/style.xxxx.css,但里面 url(../assets/bg.png) 还是按原相对逻辑算,结果指向 dist/assets/../assets/bg.png —— 这个路径根本不存在。
Vite只重写import进来的CSS里的url()
只有两种情况下的 CSS 会被 Vite 扫描并重写内部 url():
- src 目录下的 CSS/SCSS 文件(含
.vue单文件组件的<style>块) - 通过 JS
import引入的第三方 CSS(如import 'bootstrap/dist/css/bootstrap.min.css')
如果只是在 index.html 里用 <link href="node_modules/xxx.css"> 或 SCSS 里用 @import "xxx.css"(非 import 链路),Vite 完全跳过,原样拷贝进 dist,里面的 url(../fonts/...) 一个字都不改。
public/目录下的CSS和url()完全不被处理
放在 public/ 下的 CSS 文件(比如 public/css/main.css)会直接复制进 dist/,路径不变,且其中所有 url() 都绕过 Vite 构建链路:
立即学习“前端免费学习笔记(深入)”;
-
url(/logo.png)→ 依赖部署时服务器根配置,本地file://下必 404 -
url(./img/bg.jpg)→ 基准是dist/css/main.css所在位置,不是你想象的项目结构 -
url('@/assets/bg.jpg')→ SCSS 编译器不认识@/别名,原样输出,浏览器直接报错
base配置对CSS内url()几乎没影响
base 只控制 HTML 中 <script> 和 <link rel="stylesheet"> 的前缀,不影响 CSS 文件内部的 url() 解析。即使你设了 base: '/my-app/',dist/assets/style.xxxx.css 里还是可能出现 url(./assets/bg.xxxx.png),而不是 url(/my-app/assets/bg.xxxx.png) —— 因为 Vite 默认用相对路径写入哈希资源,不是绝对路径。
真正起作用的是:资源是否在 src/assets、url() 是否为静态字面量、CSS 是否走 import 链路。这三个条件缺一不可,漏掉任何一个,路径就失控。


















