Loader
什么是 Loader?
Webpack 默认只能处理 JavaScript 和 JSON 文件。Loader 的作用是让 Webpack 拥有加载和解析非 JavaScript 文件的能力。
Loader 本质上是一个导出为函数的 JavaScript 模块。它接收上一个 Loader 产生的结果或者源文件内容作为参数,对其进行转换,然后返回转换后的结果给下一个 Loader 或 Webpack 本身。
常见 Loader
- 样式处理:
css-loader:解析@import和url(),将 CSS 转化为 JS 模块。style-loader:将 JS 字符串生成为style节点,插入到 DOM 中。less-loader/sass-loader:将 Less/Sass 编译为 CSS。
- 脚本处理:
babel-loader:将 ES6+ 代码转换为 ES5。ts-loader:将 TypeScript 编译为 JavaScript。
- 资源处理(Webpack 5 已内置 Asset Modules,较少直接使用):
file-loader:将文件输出到一个文件夹中,并返回 public URI。url-loader:与file-loader类似,但当文件大小低于指定的限制时,可以返回一个 Data URL(Base64)。
Loader 的执行顺序
在 Webpack 配置中,如果有多个 Loader 作用于同一种文件类型,它们的执行顺序是从右到左(或从下到上)的。
module.exports = {
module: {
rules: [
{
test: /\.less$/,
// 执行顺序: less-loader -> css-loader -> style-loader
use: ["style-loader", "css-loader", "less-loader"],
},
],
},
};
自定义 Loader 面试要点
Loader 本质上是一个导出函数的 JavaScript 模块。Webpack 调用此函数并将上一个 Loader 产生的结果或者资源文件传入进去。
基本结构:
module.exports = function (source) {
// 对 source 进行处理,例如移除所有的 console.log
const result = source.replace(/console\.log\(.*\);?/g, "");
// 返回处理后的结果
return result;
};
开发指南与考点:
- 单一职责:一个 Loader 只做一件事情,复杂的转换应拆分为多个 Loader 链式调用。
- 同步与异步:
- 如果处理是同步的,可以直接
return或者调用this.callback。 - 如果处理是异步的,需要调用
const callback = this.async()获取回调函数,在异步操作完成后调用callback(err, result)。
- 如果处理是同步的,可以直接
- 获取配置选项:通过
this.getOptions()(Webpack 5 内置)来获取传入的 options。 - 缓存优化:Webpack 默认会缓存 Loader 的执行结果以提升构建性能。如果不希望缓存,可以通过
this.cacheable(false)关闭。 - Pitching Loader:
- Loader 除了主函数,还可以挂载一个
pitch方法。 - Webpack 在实际执行 Loader 前,会先从左到右执行各个 Loader 的
pitch函数。 - 熔断机制:如果某个
pitch函数返回了结果,Webpack 会跳过剩下的 Loader 及其后续的源文件读取,直接将结果传递给前一个 Loader,这在某些需要拦截处理的场景下非常有用(如style-loader)。
- Loader 除了主函数,还可以挂载一个