webpack打包图片资源

1,391 阅读2分钟

图片加载

in Javascript

webpack只能处理js模块,在js中加载图片模块时需要借助file-loader。如

//index.js
import photo from './../static/image/Chrome.png';
const image = new Image()
image.src = photo
document.body.appendChild(image)

webpack配置file-loader

module.exports = {
  mode: 'production',
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[path][name].[ext]',
              publicPath: 'www.txx.com',
            },
          },
          // 'image-webpack-loader'
        ],
      },
    ],
  }
}

file-loader 和 url-loader 的区别

url-loader内部继承了file-loader,与file-loader不同的是:

  1. url-loader可以把较小的图片转化成base64数据,从而减少对图片资源的http请求。同时打包文件也会变大;
  2. 当图片大小超过设置的限制(limit)时,默认采用file-loader进行加载。fallback默认值“file-loader”;
  3. 所有file-loader的属性,url-loader均可以使用。例如publicPath设置图片公共地址(图片部署到CDN服务器)

in CSS

在css中使用图片时,如background直接指定图片路径即可。

.root{
  width: 200px;
  height: 200px;
  background: url("./../static/image/webpack.jpg") 100%;
}

因为css-loader对css中引用的图片进行了处理

in html

html中通过 <img src=""> 标签直接使用图片时,需要借助html-withimg-loader。如

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="root"></div>
  <img src="./../static/image/eslint.jpeg" alt="eslint">
</body>
</html>

webpack配置loader

module.exports = {
  mode: 'production',
  module: {
    rules: [
      {
        test: /\.(htm|html)$/,
        exclude: /node_modules/,
        use: 'html-withimg-loader',
      }
    ],
  }
}

同时,file-loader/url-laoder 的 esModule设置为false。自webpack2开始,内部就集成了tree shaking代码优化,只会加载引用了的模块,html的图片会被视作未引用的模块资源

图片压缩

进过以上配置,我们已经可以成功地打包图片资源了,接下来我们要对图片资源进行压缩,在页面加载时减少响应时间。

目前主流的webpack图片压缩无非就是 image-webpack-loader 和 imagemin-webpack-plugin。一种是配置loader,一种是配置插件,参数配置也大同小异。个人倾向使用前者,下面就 image-webpack-loader 配置举例

module.exports = {
  mode: 'production',
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/i,
        use: [
          {
            loader: 'file-loader',
            options: {
              name: '[path][name].[ext]',
              publicPath: 'www.txx.com',
            },
          },
          {
            loader: 'image-webpack-loader',
            options: {
                disable: process.env.NODE_ENV !== 'production', //仅生产环境对图片进行压缩
                pngquant: {
                  quality: [0.65, 0.90],
                  speed: 4
                },
            }
          }
        ],
      },
    ],
  }
}

image-webpack-loader 参数配置参考

雪碧图

“雪碧图”又叫css精灵(css sprite),css图片合成技术。

当我们在开发中需要用到很多小图片的时候,比如菜单icon,悬浮icon等,相信大部分开发者直观的做法是直接下载UI稿中的切图,在项目中引入使用。是,这样做没错,但是作为一个直接面向客户的开发者,我们对自己的产品必须严格要求,做到性能最优。

假如我们的应用首屏需要加载很多小图片,也就是说除了html,js,css等请求外,还需要发送很多次http请求去下载图片资源,这显然会降低首屏加载速度,用户体验很差。那么,我们是否可以考虑把这些小图合并成一张大图,然后用css去定位截取使用呢?显然是可以的,这里我只提一下技术方案,不做具体实现demo了

图片合成

首先我们要把这些小图合成一张大图,然后写css样式去扣。听起来很复杂,哈哈哈别怕,社区很强大,牛逼的人也很多,早就有大佬写了一套完整的工具去帮我们完成这些操作。