1 链式loader执行顺序

一组链式的loader按照相反的顺序执行,从右到左。

链式的最后一个loader将转换过后的结果传递给前一个loader,以此类推。链中的第一个loader,返回webpack期望的js。

2 管理资源

对于webapack来说,默认只能打包js文件,或者说是js模块。

Webpack中的loader可以引入、打包非js文件/模块。

当webpack对项目代码进行打包时,遇到非js文件,会去webpack的配置文件中查找module节点,查询有没有配置去处理对应的节点。

允许将文件从不同的语言(如ts)转换为js,或者将内联图片转换为data URL,允许直接在js模块中import css文件。

2.1 加载css

需要安装 style-loadercss-loader

npm install --save-dev style-loader css-loader

webpack根据正则表达式,来查找所有以.css结尾的文件,都将被提供style-loader,css-loader。

这样可以使你在js文件中使用import './style.css'。

在编译该模块时,引入的style.css将会被<style>给包裹,并添加到html的<head>中。

 module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      }
    ]
 }

Q1: 为什么先引入style-loader,后引入css-loader ?

1、css-loader的作用: 帮助解析css文件中的css代码,除了正常的css代码外,还解析css中的@import、url(..)这种方法来实现require的功能,但是样式内容并没有添加到<style>中。

2、style-loader的作用:帮助我们将css-loader解析后的内容包裹在<style>中,并添加到html的<head>中。

3、loader执行顺序,从右往左。webpack肯定是先将所有css模块解析完成后再添加到style标签中,所以css-loader在后,style-loader在前。

2.2 加载images图像

对于图片,不管是css中的background-image,还是img中的src,使用file-loader | url-loader进行处理。

file-loader解决了路径引入问题。拿图片来说,webpack打包后这些图片的打包路径可能和编码中引入路径不一样,比如开发坏境中引入./images目录下的图片,但是打包却打包到./imgs文件夹下,甚至设置很多文件夹嵌套,导致引用出现问题。file-loader会修改打包后图片的存储路径,首先会将图片移动到output所在文件夹,并且随机生成一个hash值作为图片的名字。并将打包后的图片名称返回import | require函数。

{
  test: /\.(png|svg|jpe?g|gif)$/i,
    use: [
      {
        loader: "file-loader",
        options: {
          name: "[name]_[contenthash:7].[ext]",
          outputPath: 'images/'
        }
      }
    ]
}

file-loader的常用配置项(options)

name: 设置打包生成文件的名称。其中,[name]: 源文件名; [contenthash]: 随机生成的hash值,:7 表示生成的hash值截取前7位; [ext]: 源文件后缀; 一定要用""包裹。

outputPath: 打包文件目录,相对路径,相对于output的设置。我们最终导出的文件路径为output.path + file-loader.outputPath + file-loader.name。例如上面images,会在dist文件夹下创建images文件夹并存储文件。

publicPath:指定最终引用的文件路径(打包生成的index.html文件里面引用资源的前缀)。最终引用文件路径:output.outputPath + file-loader.outputPath + file-loader.name 。例如访问文件路径为http://localhost:8080/dist/images,其中output.publicPath默认为/dist, 这里可以设置为images/

url-loader:https://www.npmjs.com/package/url-loader

url-loader: 内置file-loader。使用url-loader时,可以不用安装file-loader。

当图片较多时会发起很多http请求,会降低页面的性能,这个问题可以使用url-loader进行解决。url-loader会将引入的图片编码,生成dataURL并将其打包到文件中。最终不需要请求直接访问这个dataURL就能访问图片。如果图片过大编码过程将会降低性能,建议将较小的图标设置为baseURL。

url-loader提供了limit参数,如果文件小于limit限制,则返回DataURL(根据encoding设置,默认base64,也可以设置utf-8等),如果大于则会调用file-loader。

进一步压缩、优化图片:

图片压缩: image-webpack-loader

{
  loader: "image-webpack-loader",
  options: {
  	bypassOnDebug: true,
  }
}

loader中使用image-webpack-loader时经常报错:Cannot find module 'imagemin-gifsicle'

这是因为npm下载包时下载不全导致的。

解决方法:

  1. 不要使用npm,使用cnpm i image-webpack-loader@6.0.0 -D; 这里一定要加版本号,如果不加版本号很容易下载不下来。

  2. 使用cnpm下载低版本的包。

比较url-loader、file-loader:https://segmentfault.com/a/1190000018987483?utm_source=tag-newest

最终对图片的优化loader为:

这里先对图片使用image-webpack-loader进行压缩为二次图片,二次图片再使用url-loader

当二次图片大小大于8k直接使用压缩后的文件,小于8k是进行base64编码。

module: {
    rules: [
      {
        test: /\.(png|svg|jpe?g|gif)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 8192, // 8k
              name: '[name]_[hash:7].[ext]',
            }
          },
          {
            loader: "image-webpack-loader",
            options: {
              bypassOnDebug: true,
            }
          }
        ],
      },
    ],
  }

这里能够看到原图片压缩了70%

2.3 加载font字体

使用file-loader 或者 url-loader可以接收、加载字体文件。
对指定文件添加loader

module: {
    rules: [
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        use: [
          'url-loader'
        ]
      }
    ],
  }

​ 存放字体文件并使用@font-face声明混合。url(...)指令会给webpack处理。

2.4 加载csv|tsv|xml数据

对于数据,json属于内置的,也就是说使用import导入.json文件时默认正常运行。但是如果导入CSV、TSV、XML时需要下载csv-loaderxml-loader

module: {
    rules: [
      {
        test: /\.(csv|tsv)$/,
        use: [
          'csv-loader'
        ]
      },
      {
        test: /\.xml$/,
        use: [
          'xml-loader'
        ]
      }
    ]
}