开发环境:Webpack + React
好几个使用了Font-awesome字体文件的项目中都遇到同一个问题,在本地测试的时候,使用webpack开发服务器,字体图标无法正常显示。
通过Chrome开发者工具可以看到,对字体文件.woff
,woff2
和ttf
加载失败。其他的文件,比如打包之后的js文件,加载正常。
请求URL中的 http://localhost:3000/assets/bundles/ 是本地测试时webpack配置中的output.publicPath
。
output: {
path: path.resolve('./html/static/bundles/local/'),
filename: "[name]-[hash].js",
publicPath: 'http://localhost:3000/assets/bundles/'
},
其实加载的是项目中对应 output.path
中的文件。如下图所示,可以看到字体文件都好好的在这里。怎么其他的文件都加载成功了,就.woff
,woff2
和ttf
总是加载不了呢?奇了怪了。
不推荐的解决办法
使用Chrome的一个插件,叫Allow-Control-Allow-Origin: *。这个插件的功能是:
Allows to you request any site with ajax from any source. Adds to response 'Allow-Control-Allow-Origin: *' header
其实是用来解决跨域问题的,但确实也能暂时解决我们这个问题。做法是,将 http://localhost:3000/assets/bundles/* 添加到配置中,然后刷新页面,就能看到之前无法显示的字体图标都正常加载到了。
在发现正确的解决办法之前,我们本地测试的时候,都使用这个插件。之所以可行是因为,在部署到服务器上之后,字体图标都能正常显示了。
但是最近开始做微信服务号开发时,服务号内的网页,也使用font-awesome字体。部署到服务器上之后,在PC端访问,以及在IOS上通过服务号内访问,都一切正常。问题就在于,在Android上通过服务号内访问时,字体又不能正常显示了!
没办法,只能找彻底的解决办法了。分析一下肯定是webpack的问题,所以就仔细研究webpack配置吧。
正确的解决办法
不能正常加载时,webpack处理字体文件使用的是file-loader
:
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }
而正确的使用方式是,使用url-loader
:
{test: /\.(woff|woff2|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000'}
url-loader
是file-loader
的上层封装,也就是有file-loader
的功能,但是比它更强大,青出于蓝而胜于蓝的感觉。
The url-loader works like the file-loader, but can return a DataURL if the file is smaller than a byte limit.
强大之处在于有个过滤。比如上面的配置的意思是,小于10000b的对应格式的文件,被编码成DataURL
,然后内嵌到引用的文件,这样页面加载的时候就没有http请求;大于这个限制的文件,则会使用file-loader
处理,生成对应的文件放到output.path
目录下,页面加载的时候仍有http请求。
当然也可以同时配置url-loader
和file-loader
,比如下面这种方式也是可以的。
{ test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
{ test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }
疑问
问题是解决了,但还是有一些疑惑...
为什么.eot
文件就可以使用file-loader
处理并且能加载呢?
为什么偏偏是.woff
,woff2
一定要url-loader
处理成DataURL呢?
为什么作为文件就加载不到呢?
......还有待解答。
参考阅读
- FontAwesome-webpack: http://npm.taobao.org/package/FontAwesome-webpack
文档的示例中limit
比较小,使用时注意一下。 - webpack学习笔记-2-file-loader 和 url-loader:http://blog.csdn.net/qq_38652603/article/details/73835153
这篇文章分析得挺清晰详细的。 - url-loader: https://www.npmjs.com/package/url-loader
- file-loader:https://www.npmjs.com/package/file-loader