所以根据上图看出,loader的作用就是进行非js模块的处理和对高级js语法的处理。

1、webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中。

2、在 webpack 的配置中,loader 有两个属性:

  • test 属性,识别出哪些文件会被转换。
  • use 属性,定义出在进行转换时,应该使用哪个 loader。

3、由于webpack仅仅用于编译JS模块,所以当遇到图片、css等资源时,就需要配置对应的loader。

(1)加载CSS

需要引入css文件的时候,需要安装 style-loader 和 css-loader(css-loader用于读取CSS文件,style-loader把CSS内容注入到JS中),并在module配置中添加这些loader:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// npm install --save-dev style-loader css-loader

// webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
+ module: {
+ rules: [
+ {
+ test: /\.css$/i,
+ use: ['style-loader', 'css-loader'],
+ },
+ ],
+ },
};

这使你可以在依赖于此样式的js文件中直接 import ‘./style.css’,这也是webpack 的一个强大的特性,就是能通过 import 导入任何类型的模块(例如 .css 文件)

代码中rules配置的意思是:webpack 编译器,当你碰到「在 require()/import 语句中被解析为 ‘.css’ 的路径」时,在你对它打包之前,先 use(使用) style-loader 和 css-loader 转换一下。

(2)加载图像

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
+ {
+ test: /\.(png|svg|jpg|jpeg|gif)$/i,
+ type: 'asset/resource', // webpack5中的Asset Modules
+ },
],
},
};

现在,在 import MyImage from ‘./my-image.png’ 时,此图像将被处理并添加到 output 目录,并且 MyImage 变量将包含该图像在处理后的最终 url(因为打包后图片路径和图片名称都发生了变化)。

在使用css-loader时,如前所示,会使用类似过程处理你的 CSS 中的 url(‘./my-image.png’),loader 会识别这是一个本地文件,并将 ‘./my-image.png’ 路径,替换为 output 目录中图像的最终路径。而html-loader以相同的方式处理 <img src="./my-image.png" />

(3)加载fonts字体

1
2
3
4
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
},

(4)加载数据,如JSON文件、CSV、XML等。其中JSON内置支持的,也就是说import Data from ‘./data.json’默认将正常运行。要导入CSV、TSV、XML,你可以使用 csv-loader 和 xml-loader。

1
2
3
4
5
6
7
8
9
10
11
// npm install --save-dev csv-loader xml-loader

// webpack.config.js
{
test: /\.(csv|tsv)$/i,
use: ['csv-loader'],
},
{
test: /\.xml$/i,
use: ['xml-loader'],
},

在使用d3等工具实现某些数据可视化时,这个功能极其有用。可以不用在运行时再去发送一个ajax请求获取和解析数据,而是在构建过程中将其提前加载到模块中,以便浏览器加载模块后,直接就可以访问解析后的数据。

(5)自定义JSON模块的解析

通过使用自定义parser替代特定的webpack loader,可以将任何toml、yaml或json5文件作为JSON模块导入。假设src文件夹下有一个data.toml、一个data.yaml和一个data.json5。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// npm install toml yamljs json5 --save-dev

// webpack.config.js
const path = require('path');
+const toml = require('toml');
+const yaml = require('yamljs');
+const json5 = require('json5');

module.exports = {
// ...
module: {
rules: [
+ {
+ test: /\.toml$/i,
+ type: 'json',
+ parser: {
+ parse: toml.parse,
+ },
+ },
+ {
+ test: /\.yaml$/i,
+ type: 'json',
+ parser: {
+ parse: yaml.parse,
+ },
+ },
+ {
+ test: /\.json5$/i,
+ type: 'json',
+ parser: {
+ parse: json5.parse,
+ },
+ },
],
},
};

然后在需要的地方就可以直接import toml from ‘./data.toml’使用。

4、通过使用不同的loader,webpack还有能力调用外部的脚本或工具,实现新语法的转换(这是babel的功能,webpack通过babel-loader来使用babel),比如说分析转换scss为css,或者把下一代的JS(ES6,ES7)转换为现代浏览器兼容的JS文件。