Webpack/Vite构建后@font-face的url()路径失效主因是构建工具未正确解析相对路径,导致404;需通过配置asset规则(Webpack)或使用public目录/动态导入(Vite)确保路径对齐。

Webpack/Vite 构建后 @font-face 的 url() 路径失效
构建工具会重写 CSS 中的 url() 路径,但默认行为和配置不匹配时,@font-face 里的路径就容易变成 404。这不是你写错了,而是构建流程“擅自改了你的地址”。
- Webpack 5+ 默认把
url('./fonts/icon.woff2')解析为模块请求,若未配asset类型规则,它可能被忽略、转 base64(超小字体)或直接丢弃 - Vite 默认只处理
public/下的静态资源;如果字体放在src/assets/fonts/却没用new URL('./xxx.woff2', import.meta.url)写法,构建后路径就断掉 - 相对路径在 CSS 里是相对于该 CSS 文件位置解析的,但构建后 CSS 可能被移到
/assets/index.xxxxx.css,而字体还在/fonts/,相对层级就错乱了
如何让构建工具正确处理字体路径
核心原则:告诉打包器“这是静态资源,别动逻辑,只管复制并修正引用”。
- Webpack:在
module.rules中添加type: 'asset/resource'规则,匹配字体后缀,并用generator.filename指定输出目录,例如fonts/[name].[hash:8][ext] - Vite:优先把字体放
public/fonts/,然后在@font-face中写绝对路径url('/fonts/myfont.woff2');若必须放src/,则改用动态导入:src: url('${new URL('./myfont.woff2', import.meta.url).href}') format('woff2') - 所有情况都禁用 CSS 中的相对路径嵌套写法,比如避免
url('../../fonts/x.ttf')—— 构建器很难推导这种跳转
浏览器 Network 面板里字体请求显示 404 的真实原因
看到 404 不代表文件不存在,而是请求路径和实际部署结构对不上。关键看两个地方:
- Network → Filter 选
font,点开失败请求,看 **Headers → Request URL** 是什么 —— 这才是构建后浏览器真正发出去的地址 - 对比构建产物目录(如
dist/)里是否存在对应路径的文件;注意大小写,MyFont.woff2 ≠ myfont.woff2 - 如果 URL 是
/assets/fonts/xxx.woff2但 dist 里只有/fonts/xxx.woff2,说明构建配置没对齐 publicPath 或 asset emit 逻辑
字体名(font-family)和文件名/路径无关,但和字体元数据强绑定
即使路径全对、格式全有、HTTP 状态码是 200,字体仍不生效,大概率卡在这一步。
立即学习“前端免费学习笔记(深入)”;
-
@font-face里写的font-family: 'MiSans'必须和字体文件内嵌的 PostScript Name 或 Full Name 一致(可用 fonttools 或在线字体查看器验证) - Chrome 开发者工具里右键元素 →
Computed → font-family,能看到最终解析出的字体名;如果显示"MiSans-Regular"而不是"MiSans",说明调用处必须写成font-family: 'MiSans-Regular' - 字体图标库(如 iconfont.cn)生成的包,其
font-family值通常固定为'iconfont',不能按文件名改成'iconfont-regular'
构建过程对字体的处理比图片更隐蔽:它既涉及路径重写,又依赖字体二进制元数据,还穿插着浏览器的 fallback 机制。最容易被忽略的是——你以为路径修好了,其实只是换了个 404 地址;你以为字体加载成功了,其实只是浏览器悄悄 fallback 到了系统字体。


















