Skip to content

练习:写一个loader,让webpack支持打包图片资源。

webpack本身引入图片资源是不支持的,支持也是需要Loader辅助的。

1.先在src/assets/webpack.png,准备一个图片

入口文件:

js
const imgPath = require("./assets/webpack.png");
console.log("入口文件", imgPath);

//在页面上显示图片
const img = document.createElement("img");
img.src = imgPath;
document.body.appendChild(img);

loaders/img-loader.js

js
var loaderUtil = require("loader-utils");

/**
 *图片处理的loader
 * @param {*} buffer 图片的2进制
 * @returns 返回处理后的js代码字符串
 */
function loader(buffer) {
    //通过loaderUtil拿到webpack的上下文this的loader的参数
  const { limit = 1000, filename = "[contenthash:5].[ext]" } =
    loaderUtil.getOptions(this);
  let content = "";
  //判断图片大小,如果大于limit,则使用文件形式,否则使用base64处理
  if (buffer.byteLength >= limit) {
    content = getFilePath.call(this, buffer, filename);
  } else {
    content = getBase64(buffer);
  }
  console.log(content);
  return `module.exports = \`${content}\``;
}
loader.raw = true; //给loader加上raw属性,webpack编译的时候就会按照原始格式进行编译

/* 
对图片的处理有两种方法:
1.使用base64处理
2.生成文件的形式
*/
function getBase64(buffer) {
  return "data:image/png;base64," + buffer.toString("base64");
}

//看个热闹就行
function getFilePath(buffer, name) {
  //filename就是文件路径 xxx.png,使用loaderUtil给文件起个名字
  var filename = loaderUtil.interpolateName(this, name, {
    content: buffer,
  });

  //给最终生成的总hash的chunk添加一个资源,让生成该打包文件
  this.emitFile(filename, buffer);

  return filename;
}

module.exports = loader;

webpack.config.js

js
module.exports = {
  mode: "development",
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.(png)|(jpg)|(gif)$/,
        use: [
          {
            loader: "./loaders/img-loader",
            //给loader传参,通过limit大小让loader处理打包图片的方式(base64/文件路径)
            //用户可以自定义img的名称
            options: {
              limit: 3000,
              filename: "img-[contenthash:5].[ext]",
            },
          },
        ],
      },
    ],
  },
};

执行npx webpack,查看打包后的main.js,用一个index.html引入,查看结果

MIT License