折腾:
【已解决】wepack打包时出错:Module parse failed jpg Unexpected character
期间,知道是需要使用可以加载png,jpg等图片的loader,但是不知道对于url-loader和file-loader到底该用哪个,以及两者有何区别。
webpack url-loader vs file-loader
User file-loader and url-loader together for same file types? · Issue #653 · webpack/webpack
DataUrl
然后又发现一个专门加载图片的:
tcoopman/image-webpack-loader: Image loader module for webpack
那到底用哪个??
算了,还是先搞清楚url-loader和file-loader再说。
webpack-contrib/url-loader: url loader module for webpack
“If the file is greater than the limit (in bytes) the file-loader is used and all query parameters are passed to it.”
babel/babel-loader: Webpack plugin for Babel
Webpack 入门指迷 – 题叶 – SegmentFault
“这个 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.”
➜ react-hot-boilerplate git:(master) ✗ npm install –save-dev url-loader npm WARN [email protected] requires a peer of webpack@1 || 2 || ^2.1.0-beta || ^2.2.0-rc but none was installed. npm WARN [email protected] requires a peer of react@^15.6.1 but none was installed. npm WARN [email protected] requires a peer of file-loader@* but none was installed. added 2 packages in 11.566s |
webpack-contrib/file-loader: file loader for webpack
“By default the filename of the resulting file is the MD5 hash of the file’s contents with the original extension of the required resource.”
➜ react-hot-boilerplate git:(master) ✗ npm install –save-dev file-loader npm WARN [email protected] requires a peer of webpack@1 || 2 || ^2.1.0-beta || ^2.2.0-rc but none was installed. npm WARN [email protected] requires a peer of react@^15.6.1 but none was installed. added 2 packages in 10.553s |
结果期间遇到:
【已解决】Webpack打包出错:ERROR in Entry module not found Cannot resolve file or directory
【总结】
先解释背景:
(1)DataUrl和limit
url-loader中的url,和代码里面的url(比如:background-image: url(‘assets/img/user1-128×128.jpg’))完全没有关系。
url-loader中的url,指的是DataUrl中的url,支持url(…)和require(…)
另外,实际上css-loader会把url(…)转换为require(…)的。
再说:url-loader和file-loader区别
url-loader是对于file-loader的封装,且多了个功能,可以设置limit,当文件大小小于limit时,自动转换为DataURL,大于等于limit时,按照正常文件加载。
换句话说:那就可以不用file-loader了。
但是对于之前一个项目配置了:
{ test: /\.(svg|woff2?|ttf|eot|jpe?g|png|gif)(\?.*)?$/i, use: ENV===’production’ ? ‘file-loader’ : ‘url-loader’ } |
即对于生产环境中用file-loader,对于开发环境用url-loader,不知道是什么特殊考虑。
有点清楚了:
因为生产环境中,未了防治缓存问题,尽量用hash名作为文件名,包括图片的文件名,所以此处,当生产环境时,生成的图片,都是类似于:
8c4a576e6aa3ae896bfdc89084df6599.png
不过呢:
url-loader是基于file-loader封装的,所以:
url-loader=file-loader + limit功能
且由于url-loader中都说了:
当设置了limit后,大于limit的文件,则把对应的(query中配置的)参数传递给file-loader,所以此处,无序file-loader,直接用url-loader即可。
经过实际测试,url-loader也支持(file-loader本身就有的)定义文件名的功能。
所以此处的:
use: isProd ? { loader: ‘file-loader’, query: { // name: ‘[path][name].[ext]?[md5:hash:base64:6]’ //name: ‘[path][name]_[md5:hash:base64:6].[ext]’ name: ‘[name]_[md5:hash:base64:6].[ext]’ } } : { loader: ‘url-loader’, query: { // inline base64 DataURL for <=2KB images, direct URLs for the rest limit: 2048, } } |
可以改为:
use : { loader: ‘url-loader’, query: { // inline base64 DataURL for <=2KB images, direct URLs for the rest limit: 2048, name: ‘[name]_[md5:hash:base64:6].[ext]’ } } |
即可实现:
对于img的src的图片的代码:
<div className=”demo_image” /> .demo_image { width: 128px; height: 128px; background-image: url(‘assets/img/user1-128×128.jpg’) } |
当文件小于2048 byte=2KB时,background-image会被自动变成这种:
url(data:image/jpeg;base64,/9j/4AAQSkZJRg…………..14ioBcss/9k=) |
之类的Data URL。
否则就当做正常的文件被加载,生成的文件名类似于:
user1-128x128_vykxhX.jpg