3-19 加载图片
在网页中不可避免的会依赖图片资源,例如 PNG、JPG、GIF,下面来教你如何用 Webpack 加载图片资源。
使用 file-loader
file-loader 可以把 JavaScript 和 CSS 中导入图片的语句替换成正确的地址,并同时把文件输出到对应的位置。
例如 CSS 源码是这样写的:
#app {
background-image: url(./imgs/a.png);
}
被 file-loader 转换后输出的 CSS 会变成这样:
#app {
background-image: url(5556e1251a78c5afda9ee7dd06ad109b.png);
}
并且在输出目录 dist
中也多出 ./imgs/a.png
对应的图片文件 5556e1251a78c5afda9ee7dd06ad109b.png
, 输出的文件名是根据文件内容的计算出的 Hash 值。
同理在 JavaScript 中导入图片的源码如下:
import imgB from './imgs/b.png';
window.document.getElementById('app').innerHTML = `
<img src="${imgB}"/>
`;
经过 file-loader 处理后输出的 JavaScript 代码如下:
module.exports = __webpack_require__.p + "0bcc1f8d385f78e1271ebfca50668429.png";
也就是说 imgB
的值就是图片对应的 URL 地址。
在 Webpack 中使用 file-loader 非常简单,相关配置如下:
module.exports = {
module: {
rules: [
{
test: /\.png$/,
use: ['file-loader']
}
]
}
};
本实例 提供项目完整代码
使用 url-loader
url-loader 可以把文件的内容经过 base64 编码后注入到 JavaScript 或者 CSS 中去。
例如 CSS 源码是这样写的:
#app {
background-image: url(./imgs/a.png);
}
被 url-loader 转换后输出的 CSS 会变成这样:
#app {
background-image: url(data:image/png;base64,iVBORw01afer...); /* 结尾省略了剩下的 base64 编码后的数据 */
}
同理在 JavaScript 中效果也类似。
从上面的例子中可以看出 url-loader 会把根据图片内容计算出的 base64 编码的字符串直接注入到代码中,由于一般的图片数据量巨大, 这会导致 JavaScript、CSS 文件也跟着变大。 所以在使用 url-loader 时一定要注意图片体积不能太大,不然会导致 JavaScript、CSS 文件过大而带来的网页加载缓慢问题。
一般利用 url-loader 把网页需要用到的小图片资源注入到代码中去,以减少加载次数。因为在 HTTP/1 协议中,每加载一个资源都需要建立一次 HTTP 链接, 为了一个很小的图片而新建一次 HTTP 连接是不划算的。
url-loader 考虑到了以上问题,并提供了一个方便的选择 limit
,该选项用于控制当文件大小小于 limit 时才使用 url-loader,否则使用 fallback
选项中配置的 loader。 相关 Webpack 配置如下:
module.exports = {
module: {
rules: [
{
test: /\.png$/,
use: [{
loader: 'url-loader',
options: {
// 30KB 以下的文件采用 url-loader
limit: 1024 * 30,
// 否则采用 file-loader,默认值就是 file-loader
fallback: 'file-loader',
}
}]
}
]
},
};
除此之外,你还可以做以下优化:
- 通过 imagemin-webpack-plugin 压缩图片;
- 通过 webpack-spritesmith 插件制作雪碧图。
以上加载图片的方法同样适用于其它二进制类型的资源,例如 PDF、SWF 等等。
本实例 提供项目完整代码