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 resolvesimport/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对每个.png
、jpg
等文件使用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-loader
,url-loader
减少了对文件资源的请求,即减少了http请求。
但如果对所有文件都使用url-loader
,比如当某个文件大小很大时,则转换成base64 字符串后js长度会很长,导致js包体积变大,就会导致js文件加载缓慢。
所以结论(也是limit
原理):
- 如果文件比较小时(即
<limit
),就使用url-loader
转换成base64放在生成的包(bundle.js)里即可(没必要发起http请求,节省时间)。 - 如果文件比较大时(即
>limit
),就使用file-loader
模式,打包到dist目录下(则可以让bundle.js快速运行,则页面可以先快速地展示出来了,再发起http请求文件资源即可);
而这两种转换都可以通过url-loader
的options
里的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》