跳至主要內容

Loader

wzCoding大约 3 分钟综合知识webpack

Loader

loader 是 webpack 的核心功能之一,它可以对源文件进行解析转换,使之转变成为 webpack 可以使用的模块,从而增强 webpack 的文件处理能力。

使用 loader

有两种方式可以使用 loader,以解析 .scss 文件为例,它的 loader 使用方式如下:

  1. 配置文件:在 webpack.config.js 中配置好要使用的 loader。loader 的配置包括两个属性:testuse,它们分别表示匹配文件的规则(test)与使用哪种 loader 来解析匹配的文件(use)。
    module.exports = {
       module:{
          rules:[
             {
                test:/\.scss$/,    //匹配以 .scss 结尾的文件
                use:[
                   "style-loader",  //最后使用 style-loader 进行样式处理
                   {
                      loader:"css-loader",  //当 scss-loader 对文件处理完成后,再使用 css-loader 进行处理
                      options:{
                         minimize: true,   //使用 css-loader 时添加部分配置
                      }
                   },
                   "scss-loader"   //使用 scss-loader 对 .scss 文件进行解析处理
                ]
             }
          ]
       }
    }
    

由上面的配置示例可以看出,loader 的调用顺序是从后往前调用的。

  1. 内联方式:在 import 导入语句中显示指定 loader。在导入语句中使用 ! 分隔不同的 loader,使用 ? 携带参数对 loader 进行配置。
    //一般使用方式
    import Styles from 'style-loader!css-loader?modules!./styles.css';
    
    //使用 ! 前缀,禁用所有已经配置的普通 loader
    import Styles from '!style-loader!css-loader?modules!./styles.css';
    
    //使用 !! 前缀,禁用所有已经配置的 loader
    import Styles from '!!style-loader!css-loader?modules!./styles.css';
    
    //使用 -! 前缀,禁用所有已经配置的 preLoader 和 loader,不禁用 postLoaders
    import Styles from '-!style-loader!css-loader?modules!./styles.css';
    

编写 loader

在简单了解了 loader 的使用方式后,我们知道了 loader 是 webpack 用来对源文件进行解析转换的,所以 loader 的功能应尽量保持专注在对文件的解析处理上。下面我们将探究如何编写一个 loader,从而加深对 loader 的理解。

loader 功能

loader 的功能应该尽量保持单一,即一个 loader 只完成一种解析转换,如果源文件需要经过多次解析转换,那么就应当使用多个 loader 进行链式调用去执行解析的任务。第一个 loader 会获得源文件的内容进行解析处理并将结果传递出去,之后的 loader 会得到上一个 loader 的处理结果并解析传递,如此按照顺序执行下去直到最后一个 loader。

loader 实现

loader 本质上是一个 Node.js 模块,这个模块应当导出一个方法,该方法的功能是获取处理前的内容,在内部处理完成后再将处理后的内容返回出去。

module.exports = function(source) {
  // source 是 compiler 传递给 loader 的一个文件的原内容
  // ...一些处理过程
  // 返回处理后的内容
  return source;
};

我们在编写 loader 时还可以调用 webpack 提供的 API 或者引入其他模块以增强 loader 的解析能力。

const { getOptions } = require('loader-utils');
const sass = require('node-sass');

module.exports = function(source) {
  // 获取到用户给当前 Loader 传入的 options
  // this 是 webpack 传递给 loader 的上下文对象,其中包含了 webpack 提供的 API
  const options = getOptions(this);
  // ...一些处理过程
  const content = sass(source);
  this.callback(
     null, // 当无法转换原内容时,可以给 webpack 返回一个 Error
     content, // 转换后的内容
     sourceMap, // 用于把转换后的内容得出原内容的 Source Map,方便调试
  )
};
ℹ️提示

更多关于 webpack loader 的信息请查看:webpack loader