【从零配置webpack】file-loader和url-loader有什么区别?

479 阅读4分钟

提起webpack,前端开发小伙伴们可能会觉得既熟悉又陌生。熟悉是因为在我们的项目中经常会用到,而陌生则是因为我们常用的前端框架vue、react都对webpack进行了封装,比如vue的脚手架vue cli,很多时候并不需要我们自己去从头配置webpack。

在具体的项目开发中可能会遇到需要根据项目实际修改webpack配置的情况,虽然遇到问题直接百度复制粘贴有时也能解决问题,但是我们不仅要会解决问题,也要更好的解决问题,既要知其然也要知其所以然。

什么是loader?

我们常在项目的webpack配置文件中看到这样一段代码:

module: {
    rules: [
      {
        test: /.css$/i,
        use: ['style-loader', 'css-loader']
      },
      {
        test: /.(png|svg|jpg|jpeg|gif)$/i,
        use: [{
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'static/img',
          },
        }],
      },
    ],
  },

代码里的loader是什么意思呢?它有什么用处呢?

Webpack官方解释是,“loader用于对模块的源代码进习转换”。怎么解释这句话呢?

举一个简单的例子,比如在一个js文件中,通过ES module的方式引入另一个js文件或者图片或者css文件,这在前端开发中是很常见。但是包括ES module模块引入方式在内,CommonJS模块引入规范CMD\AMD等引入方式都不能被浏览器所识别。不同的loader就是webpack提供的在引入这些模块时预处理这些文件,将他们处理成浏览器可以识别的形式。比如,处理css文件有css-loadere,处理vue文件有vue-loader……

图片打包用file-loader还是url-loader?

一个项目不免会引入图片,在开发时图片的路径有时用相对路径,有时用绝对路径。但是webpack最终会将各个模块打包成一个文件,此时图片的路径就是相对于入口html而言的了。选择file-loadere和url-loader都可以帮我们解决这个问题,但是这两个有什么区别,用哪个更好呢?

file-loader

新建一个项目,安装webpack并整理一个目录层级如下的项目:

Snipaste_2021-10-22_15-21-44.png

设置index.js为项目的入口文件,在index.js中引入了一个jpg格式的文件,生成一个div之后将这个图片放到页面里:

import mm from './maomao.jpg'

var strs = document.createElement('div')
strs.innerHTML = '这是index.js文件';

const mming = new Image()
mming.src = mm
strs.appendChild(mming);
document.body.appendChild(strs);

在webpack.config.js中配置webpage的基础配置,这里使用file-loader对图片进行处理:

Snipaste_2021-10-22_15-24-44.png

执行打包命令后,会在项目根目录下生成一个dist文件夹,里面内容如下:

Snipaste_2021-10-22_15-36-41.png

此时可以看到,在dist>static>img下面生成了一个maomao.jpg文件,将indexMe.html在浏览器中运行可以看到图片有正常显示:

Snipaste_2021-10-22_15-39-05.png

file-loader的功能就实现了,其他的一些修改名字等配置就不另外说了。下面介绍url-loader。

url-loader

将webpack.config.js中的file-loader改成url-loader:

Snipaste_2021-10-22_15-41-58.png

将之前的dist目录删除之后,执行打包命令发现项目根目录下又生成了一个dist文件夹,但是文件夹的内容和之前file-loader的有些不一样,它没有生成一个图片:

Snipaste_2021-10-22_15-45-01.png

但是将indexMe.html在浏览器中打开会发现图片还是在的,这是为什么呢?

打开bundle.js可以发现,里面有一个eval执行语句,里面有一个base64格式的图片:

Snipaste_2021-10-22_15-54-46.png

这就是url-loader和file-loader最大的区别,在打包图片时,如果使用url-loader,它会将图片转换成base64的字符串后直接放进bundle.js文件里。

url-loader将图片转成base64的格式后直接打包进js里,好处是减少了一次http请求,带来的问题是当图片过大时,会造成打包的js也很大,导致整个js加载都变慢,加载变慢后可能页面加载很长时间都没有内容显示出来。但是url-loader通过配置也可以解决这个问题。url-loader可通过设置limit这个配置项,设置大于limit限制的图片打包成单独的图片格式,小于limit限制的图片则直接转成base64的格式后直接打包进js里,这样避免了图片过大时也将其打包进js,导致使加载变慢的问题:

Image.png

以上就是webpack中file-loader和url-loader最基本的一个区别,希望对大家有帮助。大家有什么看法欢迎评论区留言交流哦~