04-webpack加载图片资源
本系列文章是我在学习webpack时的总结与收获。本片文章为系列文章的第四篇,包含webpack4及webpack5中对图片资源打包的处理方法。
webpack 4
在 webpack 4 中,常常使用 url-loader 以及 file-loader 来处理图片资源。
file-loader
file-loader:The file-loaderresolves import/require()on a file into a url and emits the file into the output directory.
url-loader:A loader for webpack which transforms files into base64 URIs.
Usage
-
在 webpack.config.js 中添加 file-loader / url-loader
module: { { test: /\.(jpge?|png|gif|svg)$/, use: [ loader: "url-loader" // file-loader ] } } -
在文件中引入图片等资源
import Iamge from '../img/DSC02820.jpg'; const imgEl = new Image(); imgEl.src = Iamge; //------------------------------------------------- const imgEl = new Image(); imgEl.src = require("../img/DSC02820.jpg").default;
打包后图片的名字为:
打包后图片资源的名字是经过md4 摘要算法计算出来的 128bit 的字符串,但是字符串不方便与源文件对应,所以希望可以更加有效的命名打包后的图片
webpack.config.js 中配置改为:
module: {
{
test: /\.(jpge?|png|gif|svg)$/,
use: [
loader: "url-loader", // file-loader
options: {
name: "img/[name].[hash:6].[ext]"
}
]
}
}
该配置表明:打包后,图片资源放在 img 文件下,name 表示图片原本的名字,[hash:6] 表示取 6 位hash值作为图片名字的一部分,ext 表示后缀名
文件名称规则
有时我们处理后的文件名称按照一定的规则进行显示:
- 比如保留原来的文件名、扩展名,同时为了防止重复,包含一个hash值等
- 这时可以使用
placeholders来完成
常用的placeholders
| 名称 | 含义 |
|---|---|
| [ext] | 处理文件的扩展名 |
| [name] | 处理文件的名称 |
| [hash] | 文件的内容,使用MD4散列函数处理,生成的一个128位的hash值 |
| [hash:] | 截取hash的长度,默认32个字符太长了 |
url-loader 和 file-loader的区别
file-loader 会将文件复制到指定的打包目录,并返回 public URL
url-loader 功能与 file-loader 相似,但对于不同大小的文件有不同的做法。设定 limit 值,
- 当文件大小(byte)< limit ,返回一个 DataURL,嵌入到 bundle.js 中
- 当文件大小(byte)> limit,复制文件到指定打包目录
webpack 5
在webpack5之前,加载这些资源我们需要使用一些loader,比如raw-loader、url-loader、file-loader
从webpack5开始,可以直接使用资源模块类型asset module type,来替代上面的loader
资源模块类型,通过添加四种新的模块类型,来替换所有的loader:
- asset/resource:发送一个单独的文件并导出
url,之前使用file-loader - asset/inline:导出一个资源的
data URI,之前通过使用url-loader实现 - asset/source:导出资源的源代码,之前通过使用
raw-loader实现 - asset:在导出一个
data URI和 发送一个单独的文件之间自动选择,之前通过url-loader,并且配置资源体积实现
asset/resource
{
test: /\.(jpe?g|png|gif|svg)$/,
type: "asset/resource"
}
当匹配到图片类型时,不再使用file-loader或url-loader,直接使用asset/resource类型,依然可以完成打包。
打包之后,如图所示:
在没有设置路径的情况下,会直接放到 build 目录下。若想设置目录,需要在 output 中设置assetModuleFilename
output: {
filename: "bundle.js",
path: path.resolve(__dirname, './build'), // 出口必须是绝对路径
assetModuleFilename: "img/[name].[hash:6][ext]" // 同样可以设置placeholder
}
但是,这种设置方式会将所有针对 assetModule 打包的文件放在一起,不利于分类管理。
因此,针对每种匹配做不同的设置,是较好的方式:
{
test: /\.(jpe?g|png|gif|svg)$/,
type: "asset/resource",
generator: {
filename: "img/[name].[hash:6][ext]"
}
}
asset/inline
这种方式会将资源转为base64编码,并l放入bundle.js 中
{
test: /\.(jpe?g|png|gif|svg)$/,
type: "asset/inline",
}
asset
这种类型会根据图片的大小分别对待,和url-loader种的limit一样
{
test: /\.(jpe?g|png|gif|svg)$/,
type: "asset",
generator: {
filename: "img/[name].[hash:6][ext]"
},
// 限制写在parser中
parser: {
dataUrlCondition: {
maxSize: 100 * 1024
}
}
}
References
1.webpack