前几天在做一个图表项目时,遇到这样一个问题:
这个项目的数字字体要求使用特殊字体,于是在 css 文件中引入了字体并使用,在本地开发时是正常的,部署到服务器,在 Ghrome 浏览器中看起来是正常的,但是在 safari 浏览器中引入的字体却没有生效,是什么原因呢?
现象
表面上看是引入的特殊数字字体在 safari 浏览器没有效果。
排查过程
1. 查看字体是否加载成功
检查 -> network -> font
发现需要的字体文件是 404
2. 查看字体加载不成功的原因
具体的字体加载的路径是 https://xxx/Lato-Regular.ttf ,据分析这个路径不会有这个文件的,因为字体没有做单独的打包,所以不是浏览器的问题,应该是谷歌浏览器也会有这个问题的,只是谷歌浏览器和Safari 浏览器由于字体没有生效,展示的都是浏览器的默认字体。
3. 尝试使用 base-64 的方式打包字体
修改 webpack 对 .ttf 的打包,没有效果(其实设置了 url-loader 打包就可以了,不需要加其他额外的配置了)
注:url-loader 功能类似于 file-loader , 但是在文件大小(单位为字节)低于指定的限制时,可以返回一个DataURL。
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif|ttf)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
}
]
}
}
4. 修改字体的引入路径
经过 wenpack 打包的配置的修改无效后,尝试修改字体的引入路径,发现字体的引入路径出现了问题,需要将原有的绝对路径引入方式修改为相对路径的引入方式,字体才能引入成功。
@font-face
font-family 'Lato-Regular'
// src url('/src/font/Lato-Regular.ttf') format('woff') 修改前
src url('../../font/Lato-Regular.ttf') format('woff') 修改后
修改后:
最终解决方法
修改字体的引入路径为相对路径。
总结
当我们处理css中的图片、字体等资源文件时,常用的两种loader是 file-loader或者url-loader,两者的主要差异在于,url-loader可以设置图片、字体等文件的大小限制,当文件的大小超过限制时,其表现行为等同于 file-loader,而当文件不超过限制时,则会将文件以base64的形式打包,以减少请求次数。有时会出现因为地址错误导致引用失效情况,可以查看是否是以上的情况。
为什么本地开发引入的字体可以正确的显示,部署到服务器却不生效了呢?
- webpack 本地开发中使用的是 webpack-dev-server,实时编译后的文件都保存到了内存当中,引用字体包的时候使用的是绝对路径,因此在本地开发时引入的字体生效;
- 使用webpack打包后的 dist 目录,字体包的实际存储路径与 http 请求字体包的路径不一致,所以字体没有生效;