webpack 对图像的配置实践总结

151 阅读3分钟

页面适应不同尺寸屏幕是基本需求,怎么让图片做到自适应呢? png、jpeg、bmp、svg,text, 在webpack4 需要引入 filter-loader在webpack5 内置了, asset-modules 用于指定加载器的类型,也就是告诉webpack 该如何处理不同的类型文件 asset-modules 在默认情况下,使用asset/resource 类型的加载器会生成带有[hash][ext][query]后缀的文件名,如果需要自定义文件名, 可以通过设置output.assetModuleFilename属性设置 module.relues.parser.dataUrlCondition y用于限制文件大小的阙值

Asset Modules 类型通过添加4种新的模块类型替换了所有这些加载起 asset/resource 生成单独的文件并导出URl asset/inline 导出资产的数据URL asset/source 导出资产的数据代码

asset 会自动选择导出数据 URL 还是生成单独的文件,可以设置文件大小限制来实现;

基本配置

module.exports = {
...
module: {
    rules: [
    ...,
      {
      test: /\.(jpe?g|png|svg|gif)$/,
        type: "asset", // 值🈶asset/line
        parser: {
          // 如果图片大小小于某个阙值,则base64,大于某个阙值输出单独文件;
          dataUrlCondition: {
            maxSize: 1024,
          },
        },
      },
     ]
   }
}

压缩图片

image-webpack-loader 可以在webpack 打包过程中对图片进行优化和压缩,从而减少图片文件的大小,提高页面加载速度和响应速度 它的底层依赖于 imagemin 和 一系列的图像优化工具, 包括mozipeg、optipng、pnpquant、svgo、gifsicle和webp 等可以自动选择最优的优化工具对图片进行处理 optipng: 用于压缩PNG图片工具、 pnpquant: 同样用于压缩PNG图片,可以设置图片质量和压缩速度、 svgo: 用于压缩SVG图片,包含多个插件、 gifsicle: 用于压缩GIF图片 webp:用于压缩JPG/PNG 图片压缩并转换为webp图片格式

pnpm i image-webpack-loader --save
module.exports = {
...
module: {
    rules: [
       {
        test: /\.(jpe?g|png|svg|gif)$/,
       options: {
         // 是否禁用图片优化和压缩
         disable: !isProduction, // 如果是生成环境不需要压缩
         mozipeg: {
          Progressive:true, // 是否开启渐进式JPEG,可以有效提升JPEG图片的加载速度
          quality: 65 // 压缩JPEG 图片的质量,取之范围为0到100, 值越大质量越好但文件越大 
         },
         optipng: {
           enabled:true // 是否开启png 图片的优化,可以提升png加载速度
         },
         pnpquant: {
          // 压缩png图片的质量范围,取值范围1-1, 值越大质量越好,但文件越大
          // 第一个值表示压缩质量的下限,第二个值表示压缩的上限
          quality: [0.65, 0.9],
          speed: 4 // 压缩PNG的速度,取值范围1-10, 值越大速度越快但质量越低
         },
         svgo: {
          plugin: [ // 压缩svg的插件列表,这里包含removeViewBox,和cleanupIDs两个插件
            { // 用于删除SVG种的viewBox属性
              // viewBox 属性是用来指定svg视口范围,它的值是一个矩形框的坐标和宽高
              removeViewBox: false
            },
            {
              // 用于删除svg中 的无用的ID属性
              cleanupIDs: true

            }

          ]
         },
         gifsicle: {
          interlaced: true, // 是否开启gif 图片的隔行扫描,可以有效提升GIF图片和加载速度

         },
         webp: {

         },
       }
      },
     ]
   }
}

响应式图片

responsive-loader

pnpm i responsive-loader --save
 module: {
    rules: [
    ...
{
        test: /\.png$/,
        oneOf: [
          {
            // resourceQuery 是一个用于匹配请求资源的的URL 中查询字符串中,第一个不匹配下一个对象进行匹配
            resourceQuery: /sizes/,
            use: [
              {
                loader: "responsive-loader", // 这样配 所有的图片都会是响应式,但场景是指定某张图片需要响应式
                options: {
                  // sizes: [300,600, 1024], // 将图片切成三个规格 这里是写法1,这里写了后,在图片路径里就不用再写切片尺寸了
                  adapter: require("responsive-loader/sharp"),
                },
              },
            ],
          },
          {
            type: 'asset/resource'
          },
        ],
      },
      ...
    ]
}

需要响应式的图片,在对应路径下进行设置 sizes[]=300,sizes[]=600,sizes[]=1024

import bg from './images/img.png?sizes[]=300,sizes[]=600,sizes[]=1024';
console.log(bg, ' bg.srcSet');
let image = new Image();

image.srcset = bg.srcSet;
image.sizes =  `(min-width: 1024) 1024px,100vw`
document.body.appendChild(image);

构建出来的三个尺寸的图片

image.png image.png

image.png

效果:

iShot_2025-01-04_23.56.57.gif