Loader,是 webpack 中的第四个核心属性(前面三个分别是 entry、output、mode),我们通常将其翻译成“转换器”。
为什么使用 Loader
因为 webpack 自身只能解析 JavaScript 代码,也就意味着,当我们在项目中使用 less、sass、JSX 等其他浏览器不能解析的代码时,webpack 默认是不能对它们进行处理的。所以这个时候,我们就需要在 webpack 中引入一些额外的工具,让它能够对项目中的非 JavaScript 代码进行转换处理,将其转换成浏览器能够解析的代码。
这些额外的转换工具,就是我们这一章要讲的 Loader 转换器。
Loader 的基本配置
Loader 的配置是在 webpack 配置项的 module
属性里进行的:
module.exports = {
// loaders
module: {
}
}
module 是模块的意思,所以 loader 在这里配置也就表示了它是用来解析与处理模块的。
module 配置项里最重要的一个配置子项就是 rules
属性了,它用来定义不同类型 loader 的不同处理规则:
module.exports = {
// loaders
module: {
rules: [
{},
{},
// ...
]
}
}
rules
是一个数组,数组的每一项都是一个对象。这些对象都用于各类 loader 的转换规则配置。
配置 CSS 资源的打包
这里我们通过对 CSS 样式文件的 loader 配置,来学习 rules
中 loader 的配置语法。
我们在项目中创建一个 src/css/index.css
文件,在里面写上一些简单的样式:
body {
background-color: #cccccc;
}
h1 {
color: orange;
}
然后在我们项目的入口 JS 文件 src/index.js
中引入:
import './css/index.css'
接下来我们先直接执行打包命令 npx webpack
看一下:
可以看到,打包 ./src/css/index.css
时报错了。这也证明了 webpack 在默认情况下是不能对非 JavaScript 文件进行打包的。
所以接下来,我们就要针对 CSS 对 webpack 进行 loader 的配置。
下载 loader
首先,我们需要在项目根目录执行以下命令来下载专门处理 CSS 的 loader:
npm i style-loader css-loader -D
配置 loader
下载完成后,开始在对 loader 进行相关配置:
module.exports = {
// loaders
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
}
执行打包命令
配置完成后,我们在项目根目录重新执行一次打包命令:
npx webpack
运行打包后的代码
我们在 index.html
中引入打包后的 JS 文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<h1>hello webpack</h1>
<script src="./dist/bundle.js"></script>
</body>
</html>
打开浏览器:
可以看到,CSS 样式已经生效。也就意味着,关于 CSS 的 loader 的配置我们就成功了。
loader 配置详解
通过上面一个简单的例子,我们应该对 loader 的使用有了一个比较深刻的印象了。
接下来我们就来具体的讲解一下 loader 配置的一些常用属性。
test
test
的属性值,是一个正则表达式或正则表达式数组。用于配置模块文件名,当项目中的模块文件名与 test
的正则匹配上时,该模块的代码就会被 use
属性里的 loader 转换处理。
例如我们这个例子中的 /\.css$/
,就用于匹配所有以 .css
为结尾的文件。
use
use
的属性值,可以是字符串、对象或数组,都用来表示当前规则要使用的 loader。
如果只配置一个 loader,可以用字符串。例如:
{
// ...
use: 'babel-loader'
}
如果 loader 需要额外配置参数,可以用对象,额外参数放在 options
中(有部分 loader 放 query
中)。例如:
{
// ...
use: {
loader: 'babel-loader',
options: {
// ... 其他配置
}
}
}
如果使用多个 loader 进行链式处理,那么可以取数组,数组的每一项可以是字符串或对象,字符串或对象的使用同上。
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" }
]
}
注:数组中的 loader 会按照其在数组中的位置从左到右、从上往下依次执行。
exclude
exclude
的属性值,可以是字符串或正则表达式,字符串需要是绝对路径。当我们有一些文件不想被正则匹配到的 loader 处理时,就可以配置 exclude
排除项。
例如:
{
test: /\.css$/,
exclude: /node_modules/,
use: ["style-loader", "css-loader"]
}
上面的配置文件表示,除了 node_modules
文件夹,对项目中的所有以 .css
为后缀名的文件使用 style-loader
和 css-loader
处理。
将 node_modules
中的所有文件都排除在外,可以减少 webpack 解析的范围,从而提高打包效率。
include
include
表示的意思正好与 exclude
相反,它表示只对匹配到的文件进行处理。
{
test: /\.css$/,
include: /src/,
use: ["style-loader", "css-loader"]
}
上面的配置表示,只对 src 目录下所有以 .css
为后缀名的文件使用 style-loader
和 css-loader
处理。
enforce
对同一类后缀名类型的文件,我们可以使用多个 loader 处理,例如处理 CSS 时使用 ['style-loader', 'css-loader']
,loader 的处理顺序是数组项从后向前。如果我们想强制某个 loader 最先处理或最后处理,可以使用 enforce
项。
webpack 推荐使用的 enforce 项有两个:pre
和 post
。
pre
表示这个 loader 在所有的 loader 之前执行,post
表示这个 loader 在所有的 loader 执行后再执行。
举个例子:
{
test: /\.js$/,
use: ['eslint-loader'],
enforce: 'pre',
exclude: /node_modules/,
}
这个配置表示在所有处理 JS 文件模块的 loader 执行之前,先执行 eslint-loader
,这样我们就可以在 JS 代码未被处理的时候就进行 eslint 代码规范校验。
关于 loader 的一些基本使用我们就先讲这些,后续我们再单独讲一些项目中常用 loader 的配置。