webpack中loader使用和的工作原理

loader的本质就是一个个的函数,在模块的编译阶段,会使用这些loader对源代码进行处理,处理时,一般都会生成AST解析树,这样可以方便处理。

单个loader的使用没有什么好记录的。

多个loader的使用是用一个use数组,loader的使用顺序是从下往上,也就是从use数组的后往前执行的,下面的load1、loader2、loader3是我自己定义的loader

  use: [
    'loader1',
    'loader2',
    {
      loader: 'loader3',
      options: {
        name: 'jack',
        age: 18
      }
    }
  ]

为了方便webpack找到loader,我们可以配置loader的解析规则,也就是解析路径

  // 配置loader的解析规则
  resolveLoader: {
    // 指定找loader去哪个地方找
    modules: [
      // 这是默认值
      'node_modules',
      // 指定自己的
      path.resolve(__dirname, 'loaders')
    ]
  },

下面是loader1.js的内容,注释已经写得很清楚了,值得注意的是,module.exports和module.exports.pitch这两个函数的执行顺序是不一样的,pitch是按照use数组从前往后执行,所以比较适合用来对loader做一些预处理。

// loader本质上是一个函数
// content就是源文件或者后一个loader传过来的内容
// module.exports = function (content, map, meta) {
//   // console.log(content);
//   console.log(111);
//   return content;
// }

// 下面这种写法和上面那种写法是一样的(同步loader)
module.exports = function (content, map, meta) {
  console.log(111);
  // 第一个参数是是否有错误,第三四个参数是可选的
  this.callback(null, content, map, meta);
}


// pitch方法会根据loader的顺序从前往后执行
module.exports.pitch = function () {
  console.log('pitch 111');
}

下面是loader2中的内容,不同于loader1的是,它是一个异步的loader,异步loader的好处就是它可以执行一些异步操作,可以等异步操作完之后再执行接下来的loader,性能更好。

// 异步loader
module.exports = function (content, map, meta) {
  console.log(222);
  // 调用this.async() 告诉webpack这是一个异步loader,需要等待 callback() 回调之后再进行下一个loader处理 
  const callback = this.async();
  setTimeout(() => {
    callback(null, content)
  }, 1000)
  console.log('loader2中的异步')
}
module.exports.pitch = function () {
  console.log('pitch 222');
}

下面是loader3中的内容,主要就是获取loader的选项和验证loader的选项

//getOptions方法可以来获取loader的选项(这个包webpack没有自带)
const { getOptions } = require('loader-utils');
// 验证options是不是符合规范(这个包是webpack内部自带的包)
const { validate } = require('schema-utils');

const schema = require('./schema');

module.exports = function (content, map, meta) {
  // 获取options
  const options = getOptions(this);

  console.log(333, options);

  // 校验options是否合法,如果不合法,会报错
  validate(schema, options, {
    name: 'loader3'
  })

  return content;
}
module.exports.pitch = function () {
  console.log('pitch 333');
}

这是schema.json中的内容

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "名称~"
    }
  },
  "additionalProperties": true
}

下面是执行打包后的结果,可以看到loader中的内容按预期执行
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值