webpack学习—Loader

@一棵菜菜  June 27, 2019

1. 为什么需要Loader

webpack默认只能直接打包js文件,无法打包其他格式的资源,如图片、文本等。但是webpack允许我们使用loaders对文件进行预处理,则你可以打包任何静态资源了

你还可以轻松地使用Node.js编写自己的loaders。

2. 什么是loaders

Loaders是应用于模块源代码上的转换。它们允许您在import或 “load” 文件时对文件进行预处理。
加载器可以将文件从另一种语言(如TypeScript)转换为JavaScript 或内联的图片作为data URLs。Loaders甚至允许您从JavaScript模块直接导入CSS文件!

Loaders其实就是一个打包方案,Loaders将告诉webpack怎么去打包除了js的其他格式的静态资源


3. 例子:webpack打包图片模块

您可以使用Loaders来告诉webpack加载CSS文件。要做到这一点,你需要先安装你需要的Loaders:file-loader

具体使用请参考官方文档《file-loader》
官方描述:The file-loader resolves import/require() on a file into a url and emits the file into the output directory.
即:文件加载器将文件上的import/require()解析为一个url,并将该文件发出到输出目录中。

1. 下载file-loader

npm install file-loader --save-dev

2. 在webpack.config.js文件中指定loaders

Loader将指示webpack对每个.pngjpg等文件使用file-loader

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/,
        use: {
          loader: "file-loader"
        }
      }
    ]
  }
};

使用Loaders时webpack的打包过程【必须理解】

当我们在代码里引入了图片模块时,webpack首先会把这个模块 打包复制到dist目录下,并会改一个名字(可自定义),然后返回文件的公共URI(统一资源标志符,即资源的名称)(即把资源名作为返回值返回给引入图片模块时的这个变量中)。

默认情况下,生成文件的文件名 是文件内容的hash值,其原始扩展名为所需资源。

示例

原始目录:

|- dist ("发布"代码)
   |- bundle.js (打包后生成的包文件)
   |- index.html (首页)
|- src  ("源代码")
   |- component
       |- header.js
       |- sider.js
   |- index.js (webpack打包入口文件)
   |- flag.jpg (图片)

|- node_modules (模块依赖)
|- package.json
|- webpack.config.js

src>index.js中,引入图片模块:

import flagImgURI from "./flag.jpg";
console.log(flagImgURI); // e5e82f2ce4392e20471c81d7399935fc.jpg

webpack打包后,在dist目录下添加了打包好的图片文件:

|- dist
   |- bundle.js 
   |- index.html 
   |- e5e82f2ce4392e20471c81d7399935fc.jpg (打包生成的图片模块文件)
|- src 
   |- index.js 
   |- flag.jpg (图片)

file-loader 的Options 配置

通过Options可以对打包生成的文件名进行修改。

主要的Placeholders(占位符):

  • [path]:相对于webpack.config.js所在文件目录的资源路径;
  • [name]:文件名称;
  • [hash]:指定用于哈希文件内容的哈希方法;
  • [ext]:文件扩展名(即后缀)。

示例:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpe?g|gif)$/,
        use: {
          loader: "file-loader",
          options: {
            name: "images/[name]_[hash].[ext]"
          }
        }
      }
    ]
  }
};

则打包生成的目录:

|- dist
   |- images
      |- flag_e5e82f2ce4392e20471c81d7399935fc.jpg
   |- bundle.js 
   |- index.html 
|- src 
   |- index.js 
   |- flag.jpg (图片)
具体使用请参考官方文档《file-loader》

url-loader

作用:一个用于webpack的loader,它默认将文件转换为base64 字符串

优缺点

相比file-loaderurl-loader减少了对文件资源的请求,即减少了http请求。

但如果对所有文件都使用url-loader,比如当某个文件大小很大时,则转换成base64 字符串后js长度会很长,导致js包体积变大,就会导致js文件加载缓慢。

所以结论(也是limit原理):

  • 如果文件比较小时(即<limit),就使用url-loader转换成base64放在生成的包(bundle.js)里即可(没必要发起http请求,节省时间)。
  • 如果文件比较大时(即>limit),就使用file-loader模式,打包到dist目录下(则可以让bundle.js快速运行,则页面可以先快速地展示出来了,再发起http请求文件资源即可);

而这两种转换都可以通过url-loaderoptions里的limit参数来实现。

options 参数limit

区别:url-loader的工作原理与file-loader类似,但options里多了一个limit参数设置,表示如果文件小于字节(kb)限制,则可以返回一个DataURL

  • limit如果是数字,则代表以字节为单位指定文件最大大小的数字。如果小于limit限制,则文件被转换成base64并放在生成的包文件内(bundle.js);如果超出限制,则同file-loader
  • limit如果是boolean,则代表启用或禁用将文件转换为base64。
 {
    loader: 'url-loader',
    options: {
      limit: 10240, // 10kb
     },
 },
含义:
如果文件的大小 < 10240字节(即10kb),则转换成base64并放在生成的包文件内(bundle.js);
如果文件的大小 >= 10240字节,则file-loader将被使用。
官方文档《url-loader》

4. 小结

只要看到引入的模块不是以.js结尾的,这时就应该想到使用Loaders啦!再去寻找处理这种资源格式的对应Loaders吧~

比如.vue结尾的文件,就需要vue-loader去处理,但还需要些其他配置,详情见vue官网《Vue-Loader》

更多请阅读官方文档《Loaders》


添加新评论