前言
在项目开发中我们一般通过两种方式来使用图片
import LufeiImg from "./assets/image/lufei.jpg";
import "./assets/css/style.css";
// 引入图片的两种方式
// 方式一:以src元素的形式
const imgEl = document.createElement("img");
imgEl.src = LufeiImg; // 设置src属性
document.body.append(imgEl);
// 方式二:以背景图片的形式
const bgDiv = document.createElement("div");
bgDiv.className = " bg-image";
document.body.append(bgDiv);
这个时候用webpack打包会报错,如图所示:
在解决如果打包图片的问题之前,我们先来了解一下webpack的资源模块;
资源模块(asset module)
定义:资源模块是一种模块类型,它允许使用资源文件(图片,图标等)而无需使用配置额外的loader。
在webpack 5 之前,通常使用:
- raw-loader 将文件导入字符串
- url-loader 将文件作为data URL 内联到 bundle中
- file-loader 将文件发送到输出目录
资源模块类型(asset module type),通过添加4种新的模块类型,来替换所有这些loader:
-
asset/resource 发送一个单独的文件并导出URL。
- 之前通过使用file-loader实现
-
asset/inline 导出资源的源代码。
- 之前通过使用raw-loader实现
-
asset/source 导出资源的源代码。
- 之前通过使用 raw-loader 实现
-
asset 在导出一个 data URL 和发送一个单独的文件之间自由选择。
- 之前通过使用 url-loader,并且配置资源体积限制实现
使用
resource资源
// webpack.config.js
// ........
module: {
rules: [
// .......
{
test: /.(png|jpe?g|svg|gif)$/,
// 1.打包两张图片, 并且这两张图片有自己的地址, 将地址设置到img/bgi中
// 缺点: 很多张图片加载会有很多次网络请求
type: "asset/resource",
},
],
},
// ........
输出结果:
inline资源
// webpack.config.js
// ........
module: {
rules: [
// .......
{
test: /.(png|jpe?g|svg|gif)$/,
// 2.将图片进行base64的编码, 并且直接编码后的源码放到打包的js文件中
// 缺点: 造成js文件非常大, 下载js文件本身消耗时间非常长, 造成js代码的下载和解析/执行时间过长
type: "asset/inline"
},
],
},
// ........
输出结果:
通用资源类型(asset)
// webpack.config.js
// ........
module: {
rules: [
// .......
{
test: /.(png|jpe?g|svg|gif)$/,
// 对于小于8kb的图片, 视为inline类型,可以进行base64编码
// 对于大于8kb的图片, 单独的图片打包, 形成url地址, 单独的请求这个url图片
type: "asset"
},
],
},
// ........
输出结果:
我们看到这里打包后的图片的名称有点杂乱,那么我们该如何自定义文件名称呢?
自定义文件名称
-
方式一:在output中添加assetModuleFilename属性;
-
方式二: 在rule中,添加一个generator属性,并且这是filename;
这里我们介绍几个常用的的placeholder:
- [ext] 处理文件的扩展名
- [name] 处理文件的名称
- [contenthash] 使用MD4的散列函数处理,生成一个128位的hash值
前面我们提到通用资源类型,会按默认条件,自动根据文件的大小,按resource和inline之间进行选择处理。
可以通过在配置的rule层级中,设置Rule.parser.dataUrlCondition.maxSize选项来修改此条件:
// webpack.config.js
// ........
module: {
rules: [
// .......
{
test: /.(png|jpe?g|svg|gif)$/,
// 对于小于8kb的图片, 视为inline类型,可以进行base64编码
// 对于大于8kb的图片, 单独的图片打包, 形成url地址, 单独的请求这个url图片
type: "asset",
generator: {
filename: "[name]_[contenthash:6][ext]"
},
parser: {
dataUrlCondition: {
maxSize: 32 * 1024 // 32kb
}
}
},
],
},
// ........
输出结果:
图片2以base64编码形式打包进bundle文件了
以上全部,谢谢