loader
webpack 只是一个打包工具,它只负责分析各个模块的依赖关系,然后形成资源清单,最终打包生成到指定的文件中。
其他的功能需要借助 webpack loader 和 webpack plugin 来完成。
这篇笔记,先介绍 webpack loader,webpack plugin 下篇笔记再说吧。
首先,我们得需要知道 loader 是用来干嘛的,然后再能明确如何去学习。
loader:其本质是一个字符串处理函数。也就是官方的解释:loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。
之前的笔记中有提到,webpack 不仅仅打包 js 文件,它还能打包图片、css 等其他类型的文件。再比如,在入口模块 js 文件中,手动写了一行导入 css 文件的代码 require('./css/index.css')
。此时,直接去编译,webpack 会报错,因为 webpack 不认识 css 语法,无法做依赖分析,自然就会抛出错误。这个时候,就需要用到 loader,loader 的作用就是把源码模块的代码进行转换,转换成 webpack 认识的代码,进行模块依赖分析。
loader 的作用图:
loader 配置
在 webpack.config.js 文件中,配置 loader 的属性是 module
对象。该属性值是一个对象,有 rules
、noParse
两个属性。这里主要介绍一下 rules
属性配置。
- rules:loader 规则集,该属性值是一个数组,数组的每项数据是一个对象,一个对象表示一个规则。
- test:表示匹配文件的正则表达式;
- use:表示处理文件的各个 loader;该属性是一个数组,因为一个文件可能需要多个 loader 进行处理;数组的每一项是一个对象,配置每个 loader 的信息;注意:该数组中的 loader 是从后往前进行处理的,也就是说文件被数组的最后一项处理,然后再被数组的倒数第二项处理,直至数组第一项。
- loader:loader 文件的路径字符串,或者 loader 的名称字符串;
- options:对象,用于给 loader 传递参数;
- noParse:表示不通过 loader 转换的文件;
eg:/jquery|lodash/
loader 的完整配置:
module.exports = {
module: {
rules: [ // loader 的规则集
{
test: /\.js$/g, // 文件匹配的正则表达式
use: [ // 要使用的 loader 数组
{
loader: './loaders/test-loader.js', // loader 的路径
options: { // loader 可接收到 用户传递的参数
jsFile: true,
}
}
]
}, // 规则,一个对象是一个 loader 规则
]
}
}
简写配置:
module.exports = {
module: {
rules: [ // loader 的规则集
{
test: /\.js$/g,
use: ['./loaders/test-loader.js?jsFile=true'],
},
]
}
}
官方文档参考 webpack loader。
loader 核心原理
上篇笔记中有介绍 webpack 编译模块的流程,loader 处理文件内容发生在 webpack 模块编译的哪个部分?
还记得上篇笔记中 webpack 编译模块的流程吗?复习一下:
然后,再来想想 loader 在其中的哪一步?
loader 的作用是进行源码转换的,目的是为了让 webpack 可以认识源码内容,然后对其进行模块依赖分析。所以,loader 的处理流程是文件内容读取之后,进行抽象语法树(AST)之前。
看个图就明白了:
webpack.config.js 文件中配置好 loader,loader 内部是如何处理的?
上面提到一个文件可能存在要被多个 loader 处理,处理的顺序的 use
属性值的数组的逆序。逆序的概念,这里同样会找到答案。
- 首先,入口模块编译中,webpack.config.js 会读取
module.rules
属性值,默认loaders
是一个空数组; - 根据
test
属性值匹配,看当前模块文件是否满足正则表达式,满足则把 loader 记录loaders
数组中,不满足则不记录; - 直至
module.rules
属性值读取完; - webpack 内部开始处理
loaders
数组,从数组的最后一项开始,直到数组的第一项;
来个灵魂画手的图:
最最最重要的是,要记住,loader 就是一个做字符串转换的函数!!!!