自定义loader


Loader是用于对模块的源代码进行转换(处理),之前我们已经使用过很多Loader,比如css-loader、style-loader、babel-loader等。

loader本质

Loader本质上是一个导出为函数的JavaScript模块; loader runner库会调用这个函数,然后将上一个loader产生的结果或者资源文件传入进去;

loader返回必须是一个buffer或者javascript字符串

自定义loader

//content:资源文件的内容;
//map:sourcemap相关的数据;
//meta:一些元数据
module.exports = function (content,map,meta) {
  console.log(content, "自定义loader");
  return content;
};

webpack.config.js

const path = require("path");
module.exports = {
  context: path.resolve(__dirname, ""),
  module: {
    rules: [
      {
        test: /\.js$/i,
        use: "./custom-loader/custom-loader",
      },
    ],
  },
};

image-20210904165252768

resolveLoader

指定loader所在的位置

webpack.config.js

const path = require("path");
module.exports = {
  mode: development,
  context: path.resolve(__dirname, ""),
  module: {
    rules: [
      {
        test: /\.js$/i,
        use: "custom-loader01",
      },
    ],
  },
  resolveLoader: {
    modules: ["node_modules", "./custom-loader"],
  },
};

image-20210904170248492

loader执行顺序

loader 总是 从右到左被调用。有些情况下,loader 只关心 request 后面的 元数据(metadata),并且忽略前一个 loader 的结果。在实际(从右到左)执行 loader 之前,会先 从左到右 调用 loader 上的 pitch 方法。

image-20210904174723961

enforce

指定 loader 种类。没有值表示是普通 loader。

Pitching 阶段: loader 上的 pitch 方法,按照 后置(post)、行内(inline)、普通(normal)、前置(pre) 的顺序调用。 Normal 阶段: loader 上的 常规方法,按照 前置(pre)、普通(normal)、行内(inline)、后置(post) 的顺序调用。模块源码的转换, 发生在这个阶段。

webpack.config.js

{
    test:/\.js$/i,
    use:'loader',
    enforce:'pre'
}

同步loader

默认创建的Loader就是同步的Loader; 这个Loader必须通过 return 或者 this.callback 来返回结果,交给下一个loader来处理; 通常在有错误的情况下,我们会使用 this.callback

webpack.config.js

module.exports= function (content) {
    
     // return content
    //第一个参数必须是 Error 或者 null;
    //第二个参数是一个 string或者Buffer;
    this.callback(null,content)
}

异步loader

webpack.config.js

module.exports = function (content) {
  const callback = this.async();

  setTimeout(() => {
    callback(null, content);
  }, 2000);
};

获取传入参数

npm i loader-utils

webpack.config.js

      {
        test: /\.js$/i,
        use: {
          loader: "custom-loader01",
          options: {
            name: "lu",
            age: "18",
          },
        },
      },

custom-loader.js

const { getOptions } = require("loader-utils");

//NormalLoader
//异步
module.exports = function (content) {
  const options = getOptions(this);
  console.log(options, "options");
  const callback = this.async();

  setTimeout(() => {
    callback(null, content);
  }, 2000);
};

image-20210904205745311

校验传入参数

npm i schema-utils -D

custom-schema.json

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "名字"
    },
    "age": {
      "type": "number",
      "description": "年龄"
    }
  }
}

webpack.config.js

      {
        test: /\.js$/i,
        use: {
          loader: "custom-loader01",
          options: {
            name: "lu",
            age: "18",
          },
        },
      },

custom-loader.js

const { getOptions } = require("loader-utils");
const { validate } = require("schema-utils");
const schema = require("../custom-schema/custom-schema.json");
//NormalLoader
//异步
module.exports = function (content) {
  const options = getOptions(this);
  console.log(options, "options");
  validate(schema, options);
  const callback = this.async();
  setTimeout(() => {
    callback(null, content);
  }, 2000);
};

image-20210904205927222

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.13.0