返回

webpack 系列之四:剖析 loader 详解(二)

前端

从 loaderContext 说起

在 webpack 中,loader 的执行过程是从 loaderContext 开始的。loaderContext 是一个上下文对象,它包含了有关当前正在处理的模块的所有信息,包括模块的资源路径、资源类型、正在使用的 loader 列表以及一些其他元数据。

当 webpack 创建一个新的模块时,它会首先创建一个 loaderContext 对象,并将这个对象传递给第一个 loader。第一个 loader 会根据 loaderContext 中的信息来决定如何处理这个模块。如果这个模块是一个 JavaScript 文件,那么第一个 loader 可能是一个 JavaScript loader,这个 loader 会将 JavaScript 文件编译成一种更高级的格式,比如 ES5 或 ES6。如果这个模块是一个 CSS 文件,那么第一个 loader 可能是一个 CSS loader,这个 loader 会将 CSS 文件解析成一组 CSS 规则。

解析模块类型

loaderContext 中包含了一个名为 type 的属性,这个属性指示了当前正在处理的模块的类型。模块的类型可以是以下几种之一:

  • asset:这是一个二进制资源,比如图片、字体、视频或音频文件。
  • javascript/auto:这是一个 JavaScript 文件,但它的类型尚未确定。
  • javascript/esm:这是一个 JavaScript 模块,它使用 ES 模块语法编写。
  • javascript/dynamic:这是一个 JavaScript 文件,它包含动态加载的模块。
  • javascript/module:这是一个 JavaScript 文件,它使用 CommonJS 模块语法编写。
  • json:这是一个 JSON 文件。
  • style/module:这是一个 CSS 模块,它使用 CSS 模块语法编写。
  • style/scoped:这是一个 CSS 文件,它包含作用域样式。
  • style:这是一个普通的 CSS 文件。

应用合适的 loader

根据模块的类型,webpack 会选择合适的 loader 来处理这个模块。loader 的选择是根据 loader 的匹配规则来进行的。loader 的匹配规则可以是以下几种之一:

  • 资源路径:loader 可以根据模块的资源路径来匹配。比如,一个 loader 可以匹配所有以 .js 结尾的文件。
  • 资源类型:loader 可以根据模块的类型来匹配。比如,一个 loader 可以匹配所有 JavaScript 文件。
  • loader API:loader 可以通过 loader API 来匹配模块。比如,一个 loader 可以匹配所有使用某个特定 loader API 的模块。

执行 loader

当 webpack 选择好合适的 loader 之后,它会将模块传递给第一个 loader。第一个 loader 会根据 loaderContext 中的信息来处理这个模块。如果这个模块是一个 JavaScript 文件,那么第一个 loader 可能是一个 JavaScript loader,这个 loader 会将 JavaScript 文件编译成一种更高级的格式,比如 ES5 或 ES6。如果这个模块是一个 CSS 文件,那么第一个 loader 可能是一个 CSS loader,这个 loader 会将 CSS 文件解析成一组 CSS 规则。

第一个 loader 处理完模块之后,它会将处理结果传递给下一个 loader。下一个 loader 会根据 loaderContext 中的信息来处理这个模块。这个过程会一直持续下去,直到所有的 loader 都处理完这个模块。

编译、转换和打包资源

loader 可以用于编译、转换和打包资源。编译是指将一种格式的资源转换成另一种格式的资源。比如,一个 JavaScript loader 可以将 JavaScript 文件编译成 ES5 或 ES6 格式。转换是指将一种格式的资源转换成另一种格式的资源,但两种格式的资源是等价的。比如,一个 CSS loader 可以将 CSS 文件转换成一组 CSS 规则。打包是指将多个资源合并成一个资源。比如,一个 JavaScript loader 可以将多个 JavaScript 文件合并成一个 JavaScript 文件。

常见问题

如何知道 webpack 使用了哪些 loader?

可以使用 webpack 的 --verbose 选项来查看 webpack 使用了哪些 loader。

如何配置 webpack 的 loader?

可以使用 webpack 的 module.rules 配置项来配置 webpack 的 loader。

如何编写自己的 loader?

可以使用 webpack 的 loader API 来编写自己的 loader。

总结

loader 是 webpack 中一个非常重要的概念。loader 可以用于编译、转换和打包资源。通过使用 loader,我们可以将多种格式的资源集成到 webpack 的构建过程中。