
vite 构建时无法正确解析 scss 中相对路径引用的字体和图片资源,导致 `npm run preview` 中字体不显示、背景图缺失;根本原因是 vite 对 `public/` 目录外的静态资源(如 `src/assets/`)不会自动复制到输出目录,且路径别名或深层相对路径在构建后失效。
在 Vite 项目中,src/assets/ 下的字体(.woff, .otf, .woff2)和图片资源不会被自动处理并复制到构建输出目录(默认为 dist/),尤其当 SCSS 中使用 url("../../../src/assets/fonts/...") 这类跨层级相对路径时,构建后的 CSS 会保留原始路径,但浏览器在 dist/ 环境下根本无法访问 src/ 目录——这直接导致 404 错误,字体和背景图均失效。
✅ 正确做法是:将静态资源(字体、图标、关键图片)统一放入 public/ 目录,该目录下的文件会被 Vite 原样复制到 dist/ 根目录,且可通过绝对路径 /xxx 直接引用,无需担心路径解析问题。
✅ 推荐操作步骤:
-
创建 public/fonts/ 目录,并放入字体文件:
your-project/ ├── public/ │ └── fonts/ │ ├── Marcheile-Bold-Condensed.woff │ ├── Marcheile-Bold-Condensed.otf │ └── Marcheile-Bold-Condensed.woff2 ├── src/ ├── vite.config.js └── package.json
-
更新 SCSS 中的 @font-face 引用为根路径:
@font-face { font-family: "CustomFont"; src: url("/fonts/Marcheile-Bold-Condensed.woff") format("woff"), url("/fonts/Marcheile-Bold-Condensed.otf") format("opentype"), url("/fonts/Marcheile-Bold-Condensed.woff2") format("woff2"); font-weight: bold; font-style: normal; }⚠️ 注意:url() 中以 / 开头表示从 dist/ 根目录开始查找,与 public/ 目录结构严格对应。
-
(可选)显式配置 publicDir(增强可读性):
在 vite.config.js 中明确指定(默认即为 'public',但显式声明更清晰):import { defineConfig } from 'vite' export default defineConfig({ build: { minify: false }, publicDir: 'public' // ✅ 显式声明,确保资源从 public 复制 }) -
重新构建并预览:
npm run build && npm run preview
检查 dist/fonts/ 是否存在对应字体文件,并在浏览器开发者工具的 Network 面板中确认字体请求返回 200。
❌ 不推荐的做法(常见误区):
- 继续使用 src/assets/ + 深层相对路径(如 ../../../src/assets/...)→ 构建后路径断裂,必然 404;
- 在 vite.config.js 中通过 assetsInclude 强行包含字体 → 仅影响打包逻辑,不解决 CSS 中路径解析问题;
- 使用 import 字体文件再赋值给 url() → Vite 的 CSS 资源处理不支持动态导入字体(SCSS 编译阶段无法识别 JS 模块)。
✅ 补充建议:
- 若需对字体做哈希命名或压缩,可改用 src/assets/ + Vite 的 import.meta.env.BASE_URL + new URL(..., import.meta.url).href 方式(需配合 vite-plugin-fonts 等插件),但对多数项目,public/ 方案最简洁可靠;
- 所有 CSS 中的 url() 资源(背景图、SVG Sprite 等)均应遵循相同原则:优先放 public/,用 / 绝对路径引用。
遵循以上方案,即可彻底解决 Vite 构建后字体与背景图丢失的问题,确保生产环境资源加载稳定可靠。










