原因
我在控制台查看请求后,发现elementUI的字体文件请求路径不对,
我的路径是/static/css/static/fonts/element-icons.535877f.woff
,
正确的是/static/fonts/element-icons.535877f.woff
解决
build - utils
function generateLoaders (loader, loaderOptions) {
const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader]
if (loader) {
loaders.push({
loader: loader + '-loader',
options: Object.assign({}, loaderOptions, {
sourceMap: options.sourceMap
})
})
}
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader',
publicPath: '../../' // 加上这句话
})
} else {
return ['vue-style-loader'].concat(loaders)
}
}
进一步说明:
同样的代码环境,用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,再次打包测试,字体图标显示正常了,初步确定,问题就在这里。
另一个问题被发现,element-ui的版本问题,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 配置,真正的静态文件的请求地址,其实是assetsPublicPath + assetsSubDirectory 再加上对应的webpack.base.conf.js中配置filename等字段指定的文件名称,路径等。