在前端开发中,图片是经常使用到的资源.
在使用图片的时候,我们一般会有两种方式.
- 使用图片地址 url
- 使用 base64 编码.
对于小图片而言,我们一般直接使用 base64
编码,把图片写入到 css
代码中.
这样的好处是可以减少一个http
请求.
之前我们打包的是js
和 css
文件.
结构是从我们写代码的 app
目录,将所需要的资源打包进 dist
目标目录.
我们已经知道了如何将 .js|.css
文件,利用 webpack 工具打包到 dist
文件.
但开发的时候,又有很多图片等静态资源,我们如何基于 webpack
打包到目标目录中去呢?
新建一个基于webapck的项目.
有个点说一下
不管你干了什么!
只要代码里出现了import
require
或者在样式中使用了url
.
在webpack
眼里,这些玩意都叫模块。
除了.js|.json
外,其他的通过这些方式导入的模块
(不管你是.jpg
,.css
还是.xxx
乱七八招的什么东西)
webpack
都不认识。
它不认识,就会去找看你有没有配置对应xx.xx
模块(文件)的loader
.
step 1.
安装 url-loader
& file-loader
.
url-loader 依赖 file-loader
npm i --save-dev @url-loader@1.1.2 file-loader@2.0.0
step 2.
编写 .css
文件,在内部写上一段需要使用到背景图片的样式.
body {
background-color: rgba(0, 0, 0, 0.9);
background-image: url('../images/beijing.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
step 3.
在 webpack.config.js
中,定义这个处理图片文件的loader
.
{
test: /\.(jpg|jpeg|png|gif|svg|webp)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 100, // 小于100kb --> url --> base64编码
// 这里如果只写一个文件名,那么图片将打包到 entry.output.path 路径下,也就是 dist/name.ext
// name: '[name].[ext]',// 大于100KB 把 url(xx) 替换成 ../images/[name].[ext]
// 如果,这里写的名字包含路径,那么也是相对于 entry.ouput.path 路径
// 同时这个名字将会作为生成的css中url中的图片地址.
name:'images/[name].[ext]', // -> 存储路径是 dist/images/name.ext
publicPath: '/webpack-demo-img/dist/' // 加上这个配置,就等于是 pulblicPath + name = css.url中的链接地址.
}
},
对于 url-loader
补充说明:(有个坑,关于为什么配置publicPath)
在
webpack
打包过程中,如果遇到了import (xxx.jpg) require(xxx.jpg)
或者是样式代码中的background-image:url(xxxx)
时,会把这个内容交给url-loader
处理.-
url-loader
根据options
里的两项配置对图片进行相关处理.-
limit
: 数字,单位字节. 102400 = 102400bytes = 100KB. 对于小于 100 KB 的图片,url-loader
会对其进行base64
编码,并用来替换css
中url
这块代码部分.比如background-image: url('../images/beijing.jpg');
===>background-image: url('base64xxxxxxx');
- name: 对于大于 limit 设置的值的图片,如果文件名中包含路径,那么就会以
webpack.config.js
中配置的输出目标路径为根路径,来配置这里的路径.比如 :options.name="images/[name].[ext]"
===>dist/images/[name].[ext]
. 同时将css
代码中的background-image:(url)
的**url部分替换成dist/images/[name].[ext]**
这样的格式.
-
-
publicPath
: 这是一个非常重要的参数.它解决了当url-loader
在打包大于options.limit
值的图片,同时设置background-image:url(options.name)
而导致的最终打包出来的css
文件中,url
访问错误,而出现图片无法访问的问题.- 一般情况下,在
dist
目录,我们都是以一个images
文件夹放图片. 一个css
文件夹放样式.
.
├── app
│ ├── assets
│ │ ├── images
│ │ │ └── beijing.jpg
│ │ └── style
│ │ └── index.less
│ └── index.js
├── dist
├── bundle.js
├── css
│ └── style.css
├── images
│ └── beijing.jpg
└── index.html - 一般情况下,在
在上述例子中,我们最后打包的
css
文件存放路径在dist/css/style.css
文件中.new ExtractTextPlugin('css/style.css'),
图片文件我们设置
images/beijing.png
的时候,图片会打包进dist/images/beijing.jpg
url-loader.options.name
我们设置的是images/beijing.jpg
-> 这就会导致css
文件中的background-url:(images/beijing.png)
所以,对于
css
文件中的images/beijing.png
是在同级目录下找images/beijing.png
,将无法获取到图盘内容.应该改成../images/beijing.png
就可以成功获取.但是如果修改
url-loader.options.name
为../images/beijing.png
又会导致图片文件夹存储路径发生变化.-
所以,这里需要使用绝对路径在替换css文件中的
background-image:(url)
- 图片仍然进入
dist/images/beijing.png
- 样式还是进入
dist/css/style.css
- 但是
url-loader
替换background-image:url(/webpack-demo/dist/images/beijing.jpg)
才行. - 于是就是配置替换的根目录
publicPath:/webpack-demo-img/dist/
为网站根目录. - 最终
url-loader
替换的目录为/webpack-demo-img/dist/images/beijing.jpg
===> publicPath + name
- 图片仍然进入
step 4.
运行 npm run build
step 5.
打开浏览器,查看效果.
对于图片尺寸大于 url-loader.options.limit 的图片,已经测试通过,并url链接也是对的.
那么现在添加一张小于 url-loader.options.limit(100KB)
的图片.
改写 index.html
文件和 .less
文件.
index.html
<div class="img"></div>
index.less
.img {
width: 200px;
height: 200px;
background-image: url('../images/1-44kb.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
重新运行 npm run build
查看结果
打开 webpack
打包生成的 style.css
文件.
url-loader
确实将小于 options.limit
值的图片文件设置成了 base64
编码,并写入到了 css
文件对应的 url
中了.