深入 Webpack5 等构建工具系列三(3) - url-loader 加载图片资源

860 阅读1分钟

这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战

上篇文章,本文讲解 url-loader

  • url-loaderfile-loader 的工作方式是相似的,但是可以将较小的文件转成 base64 的 URI(这意味着到时候可以和网页内容一起被请求下来)。
  • 安装 url-loader
     npm install url-loader -D
    
  • 使用 url-loader
    {
      test: /.(png|jpe?g|gif|svg)$/,
      use: [
        {
          // loader: 'file-loader',
          loader: 'url-loader',
          options: {
            name: 'img/[name].[hash:6].[ext]',
            // outputPath: 'img'
          }
        }
      ]
    }
    
    我们只需要将上篇文章中在 webpack 配置文件中配置的 file-loader 改成 url-loader 即可。

配置完成后我们先把之前打包出来的文件夹(build 文件夹)删掉,再来运行 npm run build,然后去浏览器中查看效果:

image-20210215174250039.png

可以看到,图片都能正常显示。再来看打包出来的 build 文件夹下的内容:

image-20210215174426696.png

啊叻,之前使用 file-loader 处理最后生成的图片文件怎么不见了?原因很简单,当我们使用 url-loader 处理文件时,它会通过 base64 编码将原来的文件转成 base64 data,然后将其直接嵌入到 webpack 打包后的输出文件(这里即 bundle.js)中去了。而浏览器是可以解析 base64 的数据的,所以这里就能正常显示图片啦。

在此,我们需要知道 file-loaderurl-loader 的区别:

  • file-loader 相当于将图片复制一份到输出目录中;
  • url-loader 默认情况下会将所有的图片文件转成 base64 编码;

那在开发中,对于这两种 loader,我们该如何选择呢?

  • 如果所有图片都进行转换(即使用 url-loader 的默认配置),就意味着最后打包出来的 js 文件会变得很大,那么网页就需要花更多时间来加载这一 js 文件,下载下来之后网页才能把图片等内容渲染出来,这个速度就比较慢了。
  • 而如果所有图片都直接使用(即使用 file-loader),虽然减小了最后打包出来的 js 文件的大小,网页可以快速地将其加载下来,意味着网页可以快速地显示一部分内容(当然,图片的标签已经有了,图片还没有显示)。但弊端在于,每张图片都需要进行一次 http 请求,这意味着这种方式需要更多的 http 请求,那么对于前端和服务器的压力都会变大。
  • 开发中,我们往往是将比较大的图片放到单独的图片文件中,到时发送单独的 http 请求来获取该图片;而对于比较小的图片,为了减少 http 请求次数,我们一般会将其编码成 base64 的数据,而后直接嵌入到最后打包出来的 js 文件中或 html 中。简单来说,就是小的图片需要转换,而大的图片直接使用即可;
    • 这是因为小的图片转换为 base64 之后可以和页面一起被请求,减少不必要的请求过程
    • 大的图片也进行转换,反而会影响页面的请求速度

所以呢,我们现在希望把前面两张图片中较小的那张转换成 base64,较大的那张依然以图片的形式展示。那该怎么做呢?很简单,只需要在 url-loader 对应的 options 中对 limit 属性进行设置就可以了,limit 属性对应的值可以是一个数值,以字节为单位指定文件的最大大小。如果文件大小等于或大于限制,将使用 file-loader(默认情况下)。比如我们这里希望大小在 100kb 以下的图片到时候被转化成 base64,而 100kb 以上(包括 100kb)的图片到时候以单独的图片格式进行打包,那就可以这样配置:

image-20210215184442228.png

{
  test: /.(png|jpe?g|gif|svg)$/,
  use: [
    {
      // loader: 'file-loader',
      loader: 'url-loader',
      options: {
        name: 'img/[name].[hash:6].[ext]',
        limit: 100 * 1024
      }
    }
  ]
}

修改完配置后,再来运行 npm run build 查看打包效果:

image-20210215184926713.png

可以看到,输出目录中的 img 文件夹下只有那张大于 100KB 的图片文件了,而另一张小于 100KB 大小的图片已经被打包到 bundle.js 中了。我们再来到浏览器页面查看效果:

image-20210215185408567.png

以上就是关于 url-loader 的使用说明。如果我们设置了 limiturl-loader 就会根据我们设置的 limit 决定要不要将对应的资源转成 base64 了。

补充:有了 url-loader 就没有必要用 file-loader 了吗?是的,直接使用 url-loader 就可以了。