发布网友 发布时间:2024-10-01 09:57
共1个回答
热心网友 时间:2024-10-29 13:15
1.背景最近项目中引用的可以商用字体包D-DIN,引入过程中遇到字体样式不生效,最终排查在webpack打包文件时出现错误,下文问踩坑过程以及解决方法
2.导入字体包在next.js中的app.less文件下引入字体,定义全部字体变量
@font-face{font-family:'D-DIN';src:url('../assets/fonts/D-DIN.otf');};@font-face{font-family:'D-DIN-Bold';src:url('../assets/fonts/D-DIN-Bold.otf')format("opentype");};但是在页面上,字体的样式并没有发生变化,最终在打包后的样式文件styles.chunk.css中发现url居然是[objectModule]
3.解决问题在网上查找资料发现,webpack的loader处理url时会通过以下方式导入:
src:require('../image.png')//require()是CommonJS模块语法这就导致了我们在上面看到的[objectModule]问题,要解决这个问题,可以在处理字体文件的file-loader中添加esModule:false属性
config.module.rules.push({test:/.otf$/,use:[{loader:'file-loader',options:{esModule:false,//这里设置为false},},],})配置完我们重新运行项目,重新查看style.chunk.css可以发现,文件已经可以正确的被解析(.oft前的一大串经过webpack通过hash进行编译后的结果)
看到了胜利的曙光有木有,回到页面上看字体还是没有变化,还有什么地方不对!(眼神逐渐迷失),后来想到在网络请求过程中会有一个单独请求字体的Font流,点看nextwork的Font中看到居然是404
通过RequestURL发现还是webpack在打包过程中的问题,我们打包后的字体包并不在static/css文件夹下
继续优化,在file-loader的option中添加
name:对编译后的字体名截取前8位(微弱的性能优化,减小http头部长度)
publicPath:访问路径
outputPath:打包路径,将字体文件打包到fonts文件夹
PS:由于next.js框架有服务端渲染,所以需要判断isServer将fonts文件夹存放在正确的位置
config.module.rules.push({test:/.otf$/,use:[{loader:'file-loader',options:{esModule:false,//这里设置为falsename:'[hash:8].[ext]',publicPath:'/_next/static/fonts',outputPath:`${isServer?'../':''}static/fonts/`,},},],})webpack5可以使用generator更方便
{test:/\.ttf|eot|otf|woff2?$/i,type:"asset/resource",generator:{filename:"fonts/[name].[hash:8][ext]"}}加入以上的代码,再次重启我们的项目,发现netwotk中请求字体包已经可以正常的访问
回到页面上看字体已经生效了
4.总结本次踩坑主要还是在webpack的配置上,webpack的配置还是必须要掌握
原文:https://juejin.cn/post/7096401699438329886