这是我参与8月更文挑战的第25天,活动详情查看:8月更文挑战
前期准备
接上篇文章,做如下准备操作:
- 删除
02_webpack配置文件(css)目录下的node_modules和build文件夹; - 在
01_learn_webpack目录下拷贝一份02_webpack配置文件(css),并重命名为03_webpack处理其它资源; - 解决
03_webpack处理其它资源/src/css/test.css文件中的警告问题,在:fullscreen中添加一些内容,如:color: red;; - 打开
VS Code的终端,切换目录到03_webpack处理其它资源下,运行npm install安装当前项目所需依赖,安装完成后,项目目录如下:
file-loader 加载图片资源
我们知道,在真实的开发中,项目中会有 js、css 文件,另外,还会依赖很多其它的资源,比如说图片资源。下面,我们在项目的 src 目录下新建 img 目录,在 img 目录下添加以下两张图片(图片大小分别为 36.74KB、287.60KB):
现在,我们希望在项目中使用这两张图片,通常情况下,有以下两种方式来使用图片:
- 创建一个
img元素,设置src属性; - 创建一个
div元素,设置背景图片;
下面,我们在项目中同时使用上面两种方式来使用图片,来到 ./src/js/component.js 文件下,新增以下红框圈出的内容:
// 创建一个 img 元素,设置 src 属性
// const imgEl = document.createElement('img'); // 第一种创建 img 元素的方法
const imgEl = new Image(); // 第二种创建 img 元素的方法
imgEl.src = require('../img/zznh.png').default; // 这里需要将图片当成资源设置到 src 里边,所以不能直接给一个地址,可以通过 require 的方式来加载资源
element.appendChild(imgEl);
// 创建一个 div 元素,设置背景图片
const bgDivEl = document.createElement('div');
// 添加宽高,以显示该 div
bgDivEl.style.width = 200 + 'px';
bgDivEl.style.height = 200 + 'px';
// 添加 class,以便后面通过 class 选择器找到该 div,然后设置背景图片
bgDivEl.className = 'bg-image';
// 添加背景颜色,以显示该 div
bgDivEl.style.backgroundColor = 'red';
element.appendChild(bgDivEl);
然后,来到 ./src/css/index.css 文件下,新增以下红框圈出的内容:
.bg-image {
background-image: url('../img/nhlt.jpg');
}
下面,我们在终端运行 npm run build 命令进行打包,结果如下:
我们会发现,打包失败了,这是为甚莫呢?原因非常简单,我们之前讲过,在我们处理 css 文件时,默认情况下,webpack 不知道怎么处理,所以就会报错,同时它会告诉我们需要一个合适的 loader 来处理这个 css 文件。而现在,我们的项目中又引入了一些其它资源(.jpg 文件、.png 文件),那对于 webpack 来说,默认情况下它同样不知道这些资源该怎么处理。所以当我们准备加载 .jpg/.png 图片时,webpack 就会给出大意为“模块解析失败,你可能需要一个合适的 loader 来处理这种文件类型”的报错提示。
既然 webpack 默认情况下不知道怎么处理这些类型的图片文件,那我们就通过配置来告诉它该如何进行处理。这里,我们就需要用到 file-loader 了。
-
要处理
jpg、png等格式的图片,我们也需要有对应的loader:file-loader;file-loader的作用就是帮助我们处理import/require()方式引入的文件资源,并且会将它放到我们输出的文件夹中;- 当然我们待会还会学习如何修改它的名字和所在文件夹;
要使用 file-loader,首先要安装它:
npm install file-loader -D
然后我们去 webpack 的配置文件中编写相应的规则来使用 file-loader:
{
test: /.(png|jpe?g|gif|svg)$/,
use: [
{
loader: 'file-loader'
}
]
}
或者简写为:
{
test: /.(png|jpe?g|gif|svg)$/,
use: [
'file-loader'
]
}
因为只有这一个 loader,所以还可以进一步简写为:
{
test: /.(png|jpe?g|gif|svg)$/,
use: 'file-loader'
}
上述代码块中的 test 属性对应的正则表达式中,() 表示分组,匹配小括号内的字符串,可以是一个,也可以是多个,常跟 |(或)符号搭配使用;? 表示前面的字符出现 0 次或 1 次。
完成上述配置后,我们再来运行 npm run build 命令看下效果:
可以看到,除了 3 个警告(警告我们先不管),已经没有报错了。同时,我们会发现在 webpack 的输出目录(这里即 build 文件夹)下,除了 bundle.js 文件,还多了两个图片文件:
这两张图片就是 ./src/img 目录下的两张图片打包后生成的图片,并且,它们其实也已经在项目中被正常引入了。我们来到浏览器页面查看效果:
可见,已经成功引入了图片。为了让第二张图片能显示完整,我们对 ./src/css/index.css 中的代码进行修改:
我们添加了上图中红框圈出的两行代码,通过设置 background-size: contain; 使图片完整显示出来,而通过设置 display: inline-block; 使 div 的背景图片和前面的内容在同一行显示。
修改完后重新运行 npm run build 命令,再来查看效果:
这样,两张图片都能正常显示啦~
当然,除了通过 require() 的方式加载资源,我们还可以使用 import 的方式加载资源,比如我们可以修改 ./src/js/component.js 文件中的内容如下:
重新打包后浏览器页面效果和之前是一样的。
以上,讲了 file-loader 的使用(使用 file-loader 加载图片文件),但是我们后面可能不再用它了,因为到了 webpack5 中,有了新的方式来替代它。
我们已经知道,通过 file-loader 可以去加载对应的图片资源,但是,它现在做的事情其实是非常简单的,只是把图片复制一份到打包的目录下,并做了下重命名,然后项目中最后引用的都是这些重命名后的图片文件。
补充:
-
配置完
file-loader后运行npm run build命令进行打包,在浏览器页面查看效果,发现图片未能正常显示,查看到的元素代码是这样的:<img src="[object Module]">- 原因:与
file-loader的版本有关,在4.x版本时,通过require()直接就能拿到资源,而从5.x版本开始,require()拿到的是一个Module对象,需要通过该对象的default属性才能拿到资源。而我们这里的file-loader版本较新,是6.x版本的:
所以需要通过default属性才能拿到资源。 - 解决办法:修改项目目录下
./src/js/component.js中的第16行代码:
然后重新运行npm run build进行编译。
- 原因:与
-
require()是file-loader来处理的吗?答:不是的,我们是通过
Rule对象的test属性对应的正则表达式规则来指定哪些文件由file-loader来处理的,而不是由require()来决定的。只有和规则匹配上了的文件才由file-loader来处理。(是我们指定的文件让它处理,而不是遇到了require()就让它处理)