「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」
处理图片资源
file-loader
安装:
npm install file-loader -D
为了保留原来的名字或扩展名,我们可以使用PlaceHolders进行配置。并且为了防止命名冲突,我们还会使用hash值。
我们这里介绍几个最常用的placeholder:
[ext]: 处理文件的扩展名;
[name]: 处理文件的名称;
[hash]: 文件的内容,使用MD4的散列函数处理,生成的一个128位的hash值(32个十六进制);
[contentHash]: 在file-loader中和[hash]结果是一致的(在webpack的一些其他地方不一样,后面会讲到);
[hash:]: 截图hash的长度,默认32个字符太长了;
[path]: 文件相对于webpack配置文件的路径;
配置:
{
test: /.(png|jpg|svg|gif)$/i,
use: [
{
loader: "file-loader",
options: {
name: "img/[name]_[hash:6].[ext]",
},
},
],
},
我们除了可以直接在name中添加目标文件夹,还有一个属性,专门用于是指文件的存放路径。outputPath
{
test: /.(png|jpg|svg|gif)$/i,
use: [
{
loader: "file-loader",
options: {
outputPath: "img",
name: "[name]_[hash:6].[ext]",
},
},
],
},
url-loader
url-loader和file-loader的工作方式是相似的,但是url-laoder可以将较小的文件,转成base64的URI。
默认情况下,是将所有的图片都进行base64编码。
安装:
npm install url-loader -D
我们可以通过limit属性,来设置只有小的图片进行base64编码,大的图片不进行编码。
这是因为小的图片转换base64之后可以和页面一起被请求,减少不必要的请求过程;
而大的图片也进行转换,反而会影响页面的请求速度
配置:
{
test: /.(png|jpg|svg|gif)$/i,
use: [
{
loader: "url-loader",
options: {
outputPath: "img",
name: "[name]_[hash:6].[ext]",
limit: 50 * 1024, //小于50kb的进行编码
},
},
],
},
asset module type
webpack5之前,我们使用laoder来处理资源文件。webpack5中,我们可以使用资源模块类型,来替代之前的loader。
资源模块类型(asset module type) ,通过添加 4 种新的模块类型,来替换所有这些 loader:
asset/resource 发送一个单独的文件并导出 URL。之前通过使用 file-loader 实现;
asset/inline 导出一个资源的 data URI。之前通过使用 url-loader 实现;
asset/source 导出资源的源代码。之前通过使用 raw-loader 实现;
asset 在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用 url-loader,并且配置资源体积限制实现;
自定义文件输出路径:
一、通过generator属性进行配置
{
test: /.(png|jpg|svg|gif)$/,
type: "asset/resource",
generator: {
filename: "img/[name]_[hash:6][ext]",
},
},
二、在output中添加assetModuleFilename属性;
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./dist"),
assetModuleFilename: "img/[name]_[hash:6][ext]",
},
限制文件编码的大小
实现通过url-loader的limit的效果。
步骤:
- 将type改为asset
- 添加一个parser属性,并且制定dataUrl的条件,添加maxSize属性;
{
test: /.(png|jpg|svg|gif)$/,
type: "asset",
generator: {
filename: "img/[name]_[hash:6][ext]",
},
parser: {
dataUrlCondition: {
maxSize: 50 * 1024,//小于50kb进行编码,转为base64
},
},
},
处理字体文件
- 在css-loader的6版本中,可以处理url()中的资源,因此我们不需要单独处理字体文件资源。
- 如果在低版本中,我们可以通过file-loader来处理字体资源。
- 在webpack5中可以使用asset modul type来处理字体资源。
//使用资源模块类型进行处理
{
test: /.(eot|ttf|woff2?)$/,
type: "asset/resource",
generator: {
filename: "font/[name]_[hash:6][ext]",
},
},
新版本css-loader中遇到的坑(6.XX版本)
由于要打包图片资源等,所以引入了file-loader或url-loader,这两个loader都可以对图片资源进行打包。
但是由于最新版本(6之后)中可以对css文件中的url进行解析打包,因此如果是在css文件中通过url()引入了图片资源,css-loader是可以处理图片资源的。不需要引入其他的loader。
除了在css中使用图片资源,我们还会在js文件中使用图片资源,因此我们还是需要引入file-laoder或者是url-loader的。但是这里出问题了,这两个loader也会处理css中url()引入的图片资源,最终对同一张图片打包出了两张,并且引发了冲突,最终使用了css-loader打包出来的图片,但是由于冲突,导致图片异常,无法正常的在浏览器中显示。
解决方案:
使用webpack5中的asset module type 来处理资源文件,就可以解决问题了。
切记:使用css-loader(6.XX)就不要使用file-laoder和url-loader,只能使用webpack5为我们提供的asset module type。