场景:项目 npm run build 后,所有 JS 里引用的静态图片都 404;浏览器地址栏却显示 http://localhost:xxx/logo.png——看似路径对了,实则文件根本没被打包。
根因:相对路径在构建后「跑丢了」,需要让 Vite 明确知道「这是静态资源」。
vite官网介绍new URL
1. 问题现象
- 开发环境 npm run dev 正常
- 生产环境 npm run build && npm run preview 图片 404
- Network 面板中图片路径是 /logo.png,但 dist 目录里找不到对应文件
2. 官方方案:new URL(url, import.meta.url)
Vite 官方文档对「非 import 引用的资源」给出了兜底方案:
// ❌ 开发正常,生产 404
const src = './logo.png'
// ✅ 开发 & 生产都正常
const src = new URL('./logo.png', import.meta.url).href
原理:
- new URL() 让构建工具在编译阶段就能静态分析出资源路径
- Vite 会把该文件复制到 dist/assets 并加上 hash,返回最终的绝对路径
3. 实战代码片段
// utils/getAssetURL.ts
export const getAssetURL = (path: string) =>
new URL(path, import.meta.url).href
组件中使用:
<template>
<img :src="logoUrl" alt="logo" />
</template>
<script setup lang="ts">
import { getAssetURL } from '@/utils/getAssetURL'
const logoUrl = getAssetURL('../assets/logo.png')
</script>
4. 打包验证
npm run build
npm run preview # 或本地起 nginx 指向 dist
打开浏览器,Network 面板可见:
Request URL: http://localhost:4173/assets/logo-3ad8b1f7.png
Status: 200 OK
tip:小提示 若仍想使用 import 语法,可写成 import logo from ‘@/assets/logo.png?url’
效果与 new URL() 相同,但 new URL() 更通用,尤其适用于动态拼接路径的场景。