【Webpack5笔记】loader的概念以及手写clean-log-loader、banner-loader、babel-loader和file-loader

汪德寿
2023-12-01

Loader概念

帮助 webpack 将不同类型的文件转换为 webpack 可识别的模块。 

Loader的执行顺序

pre:前置loader

normal:普通loader

inline:内联loader

post:后置loader

执行的优先级:pre>normal>inline>post

相同优先级执行顺序为:从右到左,从下到上 

// 此时loader执行顺序:loader3 - loader2 - loader1
module: {
  rules: [
    {
      test: /\.js$/,
      loader: "loader1",
    },
    {
      test: /\.js$/,
      loader: "loader2",
    },
    {
      test: /\.js$/,
      loader: "loader3",
    },
  ],
},
// 此时loader执行顺序:loader1 - loader2 - loader3
module: {
  rules: [
    {
      enforce: "pre",
      test: /\.js$/,
      loader: "loader1",
    },
    {
      // 没有enforce就是normal
      test: /\.js$/,
      loader: "loader2",
    },
    {
      enforce: "post",
      test: /\.js$/,
      loader: "loader3",
    },
  ],
},

1、手写clean-log-loader

作用:用来清理 js 代码中的console.log语句

/console\.log\(.*\);?/g,""

红色反斜杠是转义,.*为任何内容都可以,;?为有没有分号都可以,g为全局生效," "为替换为空。

// loaders/clean-log-loader.js
module.exports = function cleanLogLoader(content) {
  // 将console.log替换为空
  return content.replace(/console\.log\(.*\);?/g, "");
};

2、手写banner-loader

作用:给 js 代码添加文本注释

文件地址:loaders/banner-loader/index.js

const schema = require("./schema.json");

module.exports = function (content) {
  // 获取loader的options,同时对options内容进行校验
  // schema是options的校验规则(符合 JSON schema 规则)
  const options = this.getOptions(schema);  //schema对options进行约束

  const prefix = `
    /*
    * Author: ${options.author}
    */
  `;

  return `${prefix} \n ${content}`;
};

文件地址:loaders/banner-loader/schema.json

对options进行约束,只约束了author性质为字符串,不能出现其他属性: 

{
  "type": "object",
  "properties": {
    "author": {
      "type": "string"
    }
  },
  "additionalProperties": false
}

 webpack.config.js

{
   test:/\.js$/,
   loader:"/loader/banner-loader"
   options:{
      author:"老王",  
   }

}

3、手写babel-loader

作用:编译 js 代码,将 ES6+语法编译成 ES5-语法。

 @babel/core · Babel 中文文档 (docschina.org)

下载依赖

npm i @babel/core @babel/preset-env -D

文件地址:loaders/babel-loader/index.js

const schema = require("./schema.json");
const babel = require("@babel/core");

module.exports = function (content) {
  const options = this.getOptions(schema);
  // 使用异步loader
  const callback = this.async();
  // 使用babel对js代码进行编译
  babel.transform(content, options, function (err, result) {
    callback(err, result.code);
  });
};

文件地址:loaders/babel-loader/schema.json

{
  "type": "object",
  "properties": {
    "presets": {
      "type": "array"
    }
  },
  "additionalProperties": true
}

 webpack.config.js

{
   test:/\.js$/,
   loader:"/loader/babel-loader"
   options:{
      presets:["@babel/preset-env"], 
   }

}

 4、手写file-loader

作用:将文件原封不动输出出去

下载包,一个工具函数,生产带hash值的文件

npm i loader-utils -D

loaders/file-loader.js

const loaderUtils = require("loader-utils");

function fileLoader(content) {
  // 根据文件内容生产一个新的文件名称
  const filename = loaderUtils.interpolateName(this, "[hash].[ext]", {
    content,
  });
  // 输出文件
  this.emitFile(filename, content);
  // 暴露出去,给js引用。
  // 记得加上''
  return `export default '${filename}'`;
}

// loader 解决的是二进制的内容
// 图片是 Buffer 数据
fileLoader.raw = true;

module.exports = fileLoader;

loader配置

{
  test: /\.(png|jpe?g|gif)$/,
  loader: "./loaders/file-loader.js",
  type: "javascript/auto", // 解决图片重复打包问题
},

 类似资料: