在前端开发中,图片是经常使用到的资源.
在使用图片的时候,我们一般会有两种方式.
- 使用图片地址 url
- 使用 base64 编码.
对于小图片而言,我们一般直接使用 base64 编码,把图片写入到 css 代码中.
这样的好处是可以减少一个http请求.
之前我们打包的是js 和 css 文件.
结构是从我们写代码的 app 目录,将所需要的资源打包进 dist 目标目录.

我们已经知道了如何将 .js|.css 文件,利用 webpack 工具打包到 dist 文件.
但开发的时候,又有很多图片等静态资源,我们如何基于 webpack
打包到目标目录中去呢?
新建一个基于webapck的项目.
有个点说一下
不管你干了什么!
只要代码里出现了importrequire或者在样式中使用了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.jpgurl-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 中了.