webpack自定义loader

497 阅读1分钟

1.定义loader

  • loader就是一个函数 ,不可以是箭头函数,需要用到this做操作
  • 必须有返回值

loader是链式传递的,对⽂件资源从上⼀个loader传递到下⼀个,⽽loader的处理也遵循着从下到上的顺序。

开发原则:

  1. 单⼀原则: 每个Loader只做⼀件事,简单易⽤,便于维护;
  2. 链式调⽤: Webpack 会按顺序链式调⽤每个Loader;
  3. 统⼀原则: 遵循 Webpack 制定的设计规则和结构,输⼊与输出均为字符串,各个 Loader 完全独⽴,即插即 ⽤;
  4. ⽆状态原则:在转换不同模块时,不应该在loader中保留状态;
// 自定义loader
// /myLoaders/replace-loader.js
module.exports = function (source) {
  return source.replace("webpack", "好好笑");
};

配置设置

//设置方式1
module: {
    rules: [
     {
      test: /\.js$/,
      use: [
         path.resolve(__dirname, "./myLoaders/replace-loader.js"),
      ],
    },
  }

//设置方式2
//先定义全局加载的路径./myLoaders
module.exports = {
  resolveLoader: {
    modules: ["node_modules", "./myLoaders"],//先去node_modules找,没有就到myLoaders文件夹找
  },
    ...
     {
          test: /\.js$/,
          use: [
            "replace-loader", //在对应配置就可以直接获取 
          ],
        },
}

loader高级应用

this.callback 返回多种信息

loader 的 api 都挂载this对象上

module.exports = function (source) {
    const content = source.replace("hello", "xxxx");
   this.callback(null, content); //第一个参数为error,第二个位返回内容
    //等价于
//  return source.replace("webpack", "好好笑");
};

this.async处理异步逻辑

  • this.query 接受参数
// /myLoaders/replace-loader-async.js
module.exports = function (source) {
  console.log(this, this.query, source);
  const callback = this.async();//通过 callback引用, 处理异步,跟this.callback功能一样
  setTimeout(() => {
    const content = source.replace("hello", "yeah");
    callback(null, content);
  }, 3000);
};
//webpack.config.js
  {
          test: /\.js$/,
          use: [
         "replace-loader",
            {
              loader: "replace-loader-async",
              options: {
                name: "xxx",
              },
            },
            ]

2.定义样式处理loader

// /myLoaders/my-less-loader.js
// 使用 less模块处理less语法
const less = require("less");
module.exports = function (source) {
  less.render(source, (error, output) => {
    let { css } = output;
    this.callback(error, css);
  });
};

// /myLoaders/my-css-loader.js
module.exports = function (source) {
  return JSON.stringify(source);
};

// /myLoaders/my-style-loader.js
module.exports = function (source) {
  // style
  // style ={ source}
  // style -> head
  return `const tag = document.createElement('style');
        tag.innerHTML = ${source};
        document.head.appendChild(tag)
    `;
};
//webpack.config.js
 {
        test: /\.less$/,
        use: [
          "my-style-loader",
          "my-css-loader",
          "my-less-loader",
        ],
      },
}