webpack(二)_ 自定义实现一个loader

257 阅读2分钟

这是我参与2022首次更文挑战的第18天,活动详情查看:2022首次更文挑战」。

webpack默认支持js和json, 但像css这样的语法webpack不知道如何处理,那就交给loader解析;

loader

Webpack 支持使用 loader 对文件进行预处理。你可以构建包括 JavaScript 在内的任何静态资源。并且可以使用 Node.js 轻松编写自己的 loader。

处理css文件

// webpack.config.js
const path = require("path");
module.exports = {
  entry: {
    main: "./src/index.js",
  },
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "[name].js",
  },
  mode: "development",
  module: {
    rules: [
      {
        test: /\.css$/,
        // 当多个loader作用于一个模块的时候,是有执行顺序的,自右向左!!
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};

如上所示,在module中配置loader,module就是模块,配置支持更多类型的模块。
通过rules配置不同模块的匹配规则等。
上面代码中,处理匹配css文件,使用"style-loader", "css-loader",loader同plugin一样使用要先安装。

自定义实现一个loader

Loader就是一个函数,声明式函数,不能用箭头函数。 拿到源代码,作进一步的修饰处理,再返回处理后的源码就可以了

// webpack.config.js
const path = require("path");
module.exports = {
  entry: {
    main: "./src/index.js",
  },
  output: {
    path: path.resolve(__dirname, "./dist"),
    filename: "[name].js",
  },
  mode: "development",
  resolveLoader: {
    modules: ["node_modules", "./myLoaders"],
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        // 当多个loader作用于一个模块的时候,是有执行顺序的,自右向左!!
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.js$/,
        use: [
          "webp-loader",
          {
            loader: "webp-loader-async",
            options: {
              name: "Webpack",
            },
          },
        ],
      }
    ],
  },
};

这里来自定义两个loader, 分别叫做webp-loaderwebp-loader-async,对应处理同步和异步。

// webp-loader.js
module.exports = function (source) {
  const result = source.replace("hello", "您好");

  return result;
};
// webp-loader-async.js
// loader的结构 函数 不可以是箭头函数
// loader必须有返回值
// 如何获取options
// 如何处理异步逻辑 this.async this.callback
// 多个loader如何配合
// 处理自定义loader的路径问题
module.exports = function (source) {
  const callback = this.async();
  setTimeout(() => {
    const result = source.replace("loader", this.query.name);
    callback(null, result);
  }, 3000);
};

//入口文件 src/index.js
console.log("hello loader");

小结:

  1. loader的结构:Loader就是一个函数,声明式函数,不能用箭头函数
  2. loader必须有返回值
  3. 如何获取options
  • 如果这个 loader 配置了 options 对象的话,this 就指向这个对象。
  • 如果 loader 中没有 options,而是以 query 字符串作为参数调用时,this.query 就是一个以 ? 开头的字符串。
  1. 如何处理异步逻辑: this.async this.callback image.png
  2. 多个loader如何配合
    通过loader runner(loader解析器)控制处理。
    不同模块执行不会阻塞,但当多个loader作用于一个模块的时候,是自右向左顺序执行的,最后交给webpack\
  3. 处理自定义loader的路径问题
resolveLoader: {
    modules: ["node_modules", "./myLoaders"],
},

myLoaders是自定义的loader都放在这下面。 先从node_modules找loader,找不到再从自定义的myLoaders目录下找