解决 Webpack 5 Asset Modules 字体文件报 404 找不到资源问题

老项目从 Webpack 4 升级到 Webpack 5,把静态资源 file-loader 换成了 Webpack 5 新增的 Asset Modules 特性:

1
2
3
4
5
6
7
8
9
10
11
12
13
  webpackChain
.rule('font-rule')
.test(/\.(ttf|eot|woff|woff2)$/)
- .use('file-loader')
- .loader('file-loader')
- .options({
- name: 'fonts/[contenthash].[ext]'
- })
+ .type('asset/resource')
+ .generator({
+ filename: 'fonts/[contenthash][ext]'
+ })
.end()

然而替换的过程没有那么顺利,编译打包虽然没有任何报错,但运行时字体文件报了 404。

检查打包结果发现,打包后的 CSS 包含的字体路径是错误的:

dist-tree
1
2
3
4
5
dist
├── css
│   └── index.css
└── fonts
   └── abc.ttf
index.css
1
2
3
4
@font-face {
font-family: 'abc';
src: url('fonts/abc.ttf') format('truetype');
}

由于 CSS 文件中写的是字体的相对路径,浏览器会请求 css/fonts/abc.ttf,报了 404 找不到。

搜索了一下午,找到了以下相关问题:

都没有得到解决,其中一个答案是把 asset/resource 换成 asset/inline,虽然可以解决,但如果字体过大,inline 会大幅增加 CSS 文件大小,所以不适用。

最后,在 mini-css-extract-plugin 的 issue 中找到了解决方法。

原因是我配置的 webpack output.publicPath 是 “./“,改为 “auto“ 即可被正确识别,打包后的 CSS 会以 “../fonts/abc.ttf“ 的路径引用字体。

解决 Webpack 5 Asset Modules 字体文件报 404 找不到资源问题

https://www.imaegoo.com/2021/webpack-asset-modules-in-css/

作者

iMaeGoo

发布于

2021-11-22

更新于

2021-11-22

许可协议

CC BY 4.0

评论