element-ui 字体文件fonts/element-icons.ttf | fonts/element-icons.woff 加载报404 异常排查

公司的项目,后端渲染前端页面,是在8081端口上起了一个服务,而前端自己是在8080上起的服务,在测试时发现一个问题, 字体图标无法正常显示,经过排查,发现页面请求时,element-ui 字体图标文件加载异常,报404错误,具体为 fonts/element-icons.ttf 和 fonts/element-icons.woff 两个文件请求失败,仔细观察后发现,请求域名为8081对应的后端服务器地址,由于这个字体文件在前端服务器上,所以请求失败。

有一个诡异的地方,同样的代码环境,用yarn来安装依赖后启动运行正常,而采用npm安装依赖则有类似问题。当然,这个和yarn或者npm没有关系,肯定是环境配置的问题。经过对比发现,用yarn安装依赖后,运行的页面加载的字体文件并不是一个http请求,而是把字体文件打包成了Base64编码的文件直接嵌入到了页面当中,而采用npm搭建的环境,则发起了一个http请求,并指向了错误的地址。

这样以来就初步定位了问题,排查webpack.base.conf.js,对应的字体模块加载配置

{
  test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
  loader: 'url-loader',
  options: {
    limit: 10000,
    name: utils.assetsPath('fonts/[name].[ext]')
  }
}

由于设置了limit:10000,即文件大于10KB就会直接发起http请求的方式去加载依赖,而小于10KB的文件则直接通过Base64打包嵌入到页面当中,调整该配置为100000,再次打包测试,字体图标显示正常了,初步确定,问题就在这里。虽然问题定位了,但是原因还没找到,由于采用的webpack配置是同一份,不可能出现yarn和npm安装依赖导致配置的改变,再次分析发现,npm安装搭建的环境,请求的woff文件和ttf文件,显著变大了,分别为55956B和28200B,而通过yarn搭建的环境请求的对应字体文件只有11040B和6164B,文件大小明显不同,差异巨大。

这么一来,初步确定了是版本问题,导致了加载对应的字体文件不同,进一步导致了字体文件没有符合配置要求,没有被打包编译为Base64编码文件嵌入到页面导致。经过进一步确认,node_modules文件夹中的element-ui目录中,真实的element-ui版本为2.12.0,而package.json中对应的目标版本为2.4.9,这导致了加载的字体文件不一致,引起了这个问题。
package.json中对应的版本标识为 “element-ui”: “^2.4.9”, 就是这个 ^ 符号,锁定了element-ui的版本范围为2.4.9 ~ 3.0.0,即只要是小于3.0.0的版本,都允许自动升级。这一切还是版本不匹配挖出来的大坑。

另外牵涉到 assetsSubDirectory 和 assetsPublicPath 配置,之前还想过一个方案,既然是加载文件的路径不对,调整路径就是第一个想到的解决方案,经过页面代码的分析发现,由于原先的配置使用了相对路径,即 /static/fonts/element-icons.ttf 导致页面上直接根据后端服务器域名去加载了对应的文件。由于无法在后端服务器增加相应的static目录,只能强制把对应的目标域名改为绝对路径,指向8080端口对应的地址,这里就涉及到了assetsSubDirectory和assetsPublicPath配置,真正的静态文件的请求地址,其实是assetsPublicPath + assetsSubDirectory 再加上对应的webpack.base.conf.js中配置filename等字段指定的文件名称,路径等,所以直接把assetsPublicPath改为绝对路径 http://……:8080 即可。

这个意外的问题,让我搞明白了loader中的一些配置的真正用途,也弄清楚了assetsSubDirectory和assetsPublicPath具体的使用场景。

你可能感兴趣的:(自己挖的坑)