在加载文件模块(字体文件、图片、音视频等)时,webpack 并不知道如何对其进行加载,必须指定对应的 Loader 来完成这个功能。
file-loader
:
- 新建
src/img
文件夹并引入一张图片。 - 新建
src/js/componenet.js
文件并编写代码。import likeImg from '../img/like.jpg' function component() { const img = document.createElement('img') img.src = likeImg return img } document.body.appendChild(component())
- 新建
src/index.js
并引入src/js/componenet.js
文件。import './js/component.js'
- 新建
index.html
文件并引入 Webpack 打包后的 JS 文件。<script src="./dist/main.js"></script>
- 运行 webpack 命令进行打包,会发现报错了。
使用 file-loader
:
file-loader
:对 import
/require()
方式引入的文件资源进行处理,并且会将其放到打包输出的文件夹下。
file-loader
的原理:只是将图片复制到了打包输出的文件夹下,并对其进行了重命名,在代码中引用文件时引用的都是重命名后的名称。
从
file-loader
V5 开始,file-loader
处理使用require()
方式引入的文件资源,返回值是一个对象,获取文件资源的 URL 要使用对象的 default 属性。
- 安装
file-loader
:npm install file-loader --save-dev
。 - 在
webpack.config.js
配置文件中配置file-loader
:module.exports = { module: { rules: [ { test: /\.(png|jpe?g|gif|svg)$/, use: "file-loader" } ] } }
此时,再去运行 webpack
命令进行打包,会发现,报错信息不见了,图片显示在了页面中,并且图片被打包到了 dist 文件夹下。
配置 webpack 打包后 file-loader
生成的文件名称和文件路径:
file-loader
会根据文件内容采用 MD4 算法生成文件名称,但此时就无法再根据名称区分打包后的文件与哪个源文件是一一对应的了;并且将全部文件资源都直接放到打包的根目录下,也会很凌乱。
可以通过配置 file-loader
中的 options 来修改生成的文件名称和文件路径:
- name:打包后的文件名。可以使用占位符,webpack 打包后会将占位符替换成对应的名称。其中可使用的占位符有:
[name]
:被处理文件的名称。[ext]
:被处理文件的扩展名。[hash]
:根据被处理文件的内容,使用 MD4 的散列函数处理,生成的一个 128 位的hash 值(32 个十六进制)。[contentHash]
:在file-loader
中[contentHash]
和[hash]
是一致的(但是在 Webpack 的其他地方是有区别的)。[hash:length]
:截取部分 hash。[path]
:处理文件相对于webpack.config.js
配置文件的路径。
- outputPath:打包后文件的路径
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)$/,
use: [
{
loader: "file-loader",
options: {
// 打包后的文件名。[name]表示源文件名,[hash:6]表示截取 6 位生成的 hash 值,[ext]表示源文件的扩展名
name: "[name]-[hash:6].[ext]",
// 打包后文件的路径。统一放到 img 文件夹下。但这种写法比较少见,如果想要配置打包后文件的路径,一般会直接写到打包后的文件名中 "img/[name]-[hash:6].[ext]"
outputPath: "img",
}
}
]
}
]
}
}
再次运行 webpack
进行打包,会发现打包后的文件名已经被修改了。
url-loader
:
使用 url-loader
:
url-loader
:和 file-lodaer
的工作方式相似,但是 url-loader
会将文件转化成 base64 的 URL。
- 安装
url-loader
:npm install url-loader --save-dev
。 - 在
webpack.config.js
配置文件中配置url-loader
:module.exports = { module: { rules: [ { test: /\.(png|jpe?g|gif|svg)$/, use: ["url-loader"], } ] } }
运行 webpack
命令进行打包,会发现打包生成的文件夹中并没有图片,而是被转成了 base64 的 URL 直接插入到了 JS 代码中。
配置不超过多大尺寸的图片才转换成 base64 的 URL:
url-loader
的 options 中提供了一个 limit 属性,可以用来限制多少字节以下的图片才转成 base64 的 URL,超过的会和 file-loader 一样打包到输出的文件夹下。
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)$/,
use: [
{
loader: "url-loader",
options: {
name: "img/[name]-[hash:6].[ext]",
// 以字节为单位。不超过 100kb 的图片才转换成 base64 的 URL,超过的 100kb 的图片就和 file-loader 一样打包到输出的文件夹下
limit: 100 * 1024,
}
}
]
}
]
}
}
此时,再去运行 webpack
命令进行打包,会发现图片被打包到了生成的文件夹下。
Webpack5 中的资源模块类型:
从 Webpack5 开始,Webpack 已经内置了对文件的处理,可以直接使用资源模块类型 asset module type
来替代上面的 loader。可以配置 4 种模块类型。
-
asset/resource
:发送一个单独的文件并导出 URL。之前通过使用file-loader
来实现。
-
asset/inline
:导出一个资源的 data URL。之前通过url-loader
来实现。
-
asset/source
:直接读取成字符串,导出资源的源代码。之前通过raw-loader
来实现。 -
asset
:在导出一个 data URL 和发送一个单独的文件之间自动选择。之前通过使用url-lodaer
并且配置资源体积的限制来实现。
使用 Webpack5 中的资源模块类型:
在 webpack.config.js
配置文件中进行配置。
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)$/,
type: 'asset',
}
]
}
}
运行 webpack
命令进行打包,会发现,大图片被打包到了生成的文件夹下,小图片被转成了 base64 的 URL 直接插入到 JS 中。
配置使用资源模块类型打包后生成的文件路径和文件名:
output.assetModuleFilename
属性:用来配置所有经过资源模块类型打包后的资源模块输出后的文件路径和文件名。module.exports = { output: { // 所有经过资源模块类型打包后的资源模块输出后的文件路径和文件名。 // 将图片打包到输出文件夹下的 img 文件夹下,图片名称取图片的名称-6位哈希值.图片后缀名。此处的 [ext] 中已经包含了后缀名前的那个 . assetModuleFilename: 'img/[name]-[hash:6][ext]', }, module: { rules: [ { test: /\.(png|jpe?g|gif|svg)$/, type: 'asset', parser: { dataUrlCondition: { maxSize: 1000000 * 1024, } } }, ] } }
generator.file
属性:针对匹配的资源模块进行单独设置,用来配置匹配到的资源模块打包后的资源模块输出后的文件路径和文件名。module.exports = { module: { rules: [ { test: /\.(png|jpe?g|gif|svg)$/, type: 'asset', // 针对匹配的资源模块进行单独设置 generator: { file: 'img/[name]-[hash:6][ext]', } } ] } }
此时,再运行 webpack
命令进行打包,会发现,大图片被打包到了生成的文件夹下的 img 文件夹下。
配置不超过多大尺寸的图片才转换成 base64 的 URL:
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)$/,
type: 'asset',
parser: {
// 配置不超过 100kb 的图片转成 base 的 URL,超过的会被直接打包到输出的文件夹下
dataUrlCondition: {
maxSize: 100 * 1024,
}
}
}
]
}
}