Loader
先来看一下官方文档中对于Loader解释
Out of the box, webpack only understands JavaScript and JSON files. Loaders allow webpack to process other types of files and convert them into valid modules that can be consumed by your application and added to the dependency graph.
默认情况下,webpack只能理解和打包Javascript和JSON文件,通过使用Loaders,允许webpack将不同格式的文件转换能够被你的应用所使用的成有效的模块,并添加到依赖中。
使用file-laoder打包图片文件
文件结构:(/source_code/03/03-01)
- dist
- index.html
-images - avatar.jpg
- index.html
- src
- index.js
- webpack.config.js
文件内容
- src/index.js
import avatar from '../images/avatar.jpg'
let img = new Image()
img.src = avatar
img.width = 200
let root = document.getElementById('root')
root.appendChild(img)
- webpack.config.js
const path = require('path')
module.exports = {
// 定义入口文件
entry: path.resolve(__dirname, "src/index.js"),
// 定义打包后输入的文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [{
test: /\.jpg$/, // 使用file-loader打包jpg文件
use: 'file-loader'
}]
}
}
执行npm run bundle
进行打包,可以看到在dist目录中除了打包生成了bundle.js
以外,还生成了一个60b6e2a03de866e096a5d3478e982781.jpg
文件。那么我们来分析一下webpack使用file-load做了哪些工作:
- 首先当webpack编译打包项目的时候,根据配置,当他遇到使用
.jpg
之类的图片文件的时候,他会先将图片移动动打包输出的目录中(dist
)。 - 根据配置,对图片文件进行重命名。并且得到图片相对于
dist
目录的名称,并将这个名称作为返回值,返回到引入这个图片的变量之中。
通过上面的两个步骤,我们就能够在我们的项目中,引入jpg作为模块使用了。
通过上面的示例我们要知道,一旦在我们的项目中引入非js或者json文件的时候,我们首先就要想到使用loader来对其进行打包。
其他配置项
使用上面的配置,我们发现图片的名字在打包之后变成了一个很长的名字,如果我们想保持图片的名字不变,这个时候我们就需要进行一些额外的配置了。
- 修改webpack.config.js(/source/03/03-01/webpack.config.1.js)
const path = require('path')
module.exports = {
// 定义入口文件
entry: path.resolve(__dirname, "src/index.js"),
// 定义打包后输入的文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [{
test: /\.jpg$/,
use: {
loader: 'file-loader',
options: {
name: '[name].[ext]' //FIXME: 增加关于输出文件名的配置
outputPath: 'images/'
//FIXME: 增加关于输出文件目录的配置
}
}
}]
}
}
通过我们以上的配置,再次进行打包。这时我们看到dist
中输出的图片文件名称,就和源文件一致了。
name: '[name].[ext]'
这种语法,我们称之为占位符,类似的占位符,在webpack中常用的还有:
- [hash]:使用
md5
生成的hash值
url-loader打包图片
在使用url-loader
打包文件的时候,他和file-loader的机制不同,他并不会将文件复制到dist
目录,而是将图片文件转换成base64,插入到目标文件中。
- 使用
npm i url-loader -D
,安装url-loader - 更改webpack.config.js的相关代码(/source_code/03/03-01/webpack.config.2.js)
const path = require('path')
module.exports = {
// 定义入口文件
entry: path.resolve(__dirname, "src/index.js"),
// 定义打包后输入的文件
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
module: {
rules: [{
test: /\.jpg$/,
use: {
loader: 'url-loader'
}
}]
}
}
- 执行
npm run bundle
进行打包
但是这种使用方式会带来一个问题,如果我们引入的是一个比较大的图片的话,那么使用这种方式,会使我们的目标文件变得很大,从而降低加载速度。为了避免这个问题,我们需要配置额外的参数
//...
module: {
rules: [{
test: /\.jpg$/,
use: {
loader: 'url-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/',
limit: 2048 // 2KB
}
}
}]
}
//...
上面的配置的意义为:当图片文件大于limit
设置的2KB的时候,他会使用根据name
和outputPath
的选项将文件打包复制到输出目录中,如果小于的话,他会使用base64的形式,将其注入到引入他的变量中